fontisan 0.2.17 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/.rubocop_todo.yml +86 -86
  4. data/CHANGELOG.md +12 -2
  5. data/README.adoc +53 -1
  6. data/docs/.vitepress/config.ts +68 -8
  7. data/docs/.vitepress/theme/style.css +570 -272
  8. data/docs/CONVERSION_GUIDE.adoc +31 -8
  9. data/docs/EXTRACT_TTC_MIGRATION.md +1 -1
  10. data/docs/WOFF_WOFF2_FORMATS.adoc +53 -0
  11. data/docs/api/conversion-options.md +37 -14
  12. data/docs/cli/audit.md +337 -0
  13. data/docs/cli/convert.md +20 -1
  14. data/docs/cli/index.md +31 -0
  15. data/docs/guide/color.md +1 -1
  16. data/docs/guide/conversion/options.md +32 -3
  17. data/docs/guide/conversion/ttf-otf.md +1 -1
  18. data/docs/guide/conversion/type1.md +1 -1
  19. data/docs/guide/conversion/web.md +91 -32
  20. data/docs/guide/conversion.md +6 -5
  21. data/docs/guide/formats/woff.md +35 -11
  22. data/docs/guide/index.md +2 -2
  23. data/docs/guide/migrations/extract-ttc.md +1 -1
  24. data/docs/guide/quick-start.md +4 -4
  25. data/docs/guide/type1.md +4 -4
  26. data/docs/guide/woff.md +19 -17
  27. data/docs/index.md +2 -0
  28. data/docs/lychee.toml +5 -1
  29. data/docs/package.json +1 -1
  30. data/docs/public/robots.txt +4 -0
  31. data/docs/scripts/post-build.mjs +81 -0
  32. data/lib/fontisan/base_collection.rb +23 -9
  33. data/lib/fontisan/binary/structures.rb +0 -2
  34. data/lib/fontisan/binary.rb +11 -0
  35. data/lib/fontisan/cldr/aggregator.rb +33 -0
  36. data/lib/fontisan/cldr/cache_manager.rb +110 -0
  37. data/lib/fontisan/cldr/config.rb +59 -0
  38. data/lib/fontisan/cldr/download_error.rb +9 -0
  39. data/lib/fontisan/cldr/downloader.rb +79 -0
  40. data/lib/fontisan/cldr/error.rb +8 -0
  41. data/lib/fontisan/cldr/index.rb +64 -0
  42. data/lib/fontisan/cldr/index_builder.rb +72 -0
  43. data/lib/fontisan/cldr/unicode_set_parser.rb +189 -0
  44. data/lib/fontisan/cldr/unknown_version_error.rb +9 -0
  45. data/lib/fontisan/cldr/version_resolver.rb +91 -0
  46. data/lib/fontisan/cldr.rb +23 -0
  47. data/lib/fontisan/cli/cldr_cli.rb +85 -0
  48. data/lib/fontisan/cli.rb +31 -2
  49. data/lib/fontisan/collection/builder.rb +0 -4
  50. data/lib/fontisan/collection/dfont_builder.rb +0 -4
  51. data/lib/fontisan/collection/shared_logic.rb +0 -2
  52. data/lib/fontisan/collection/writer.rb +0 -3
  53. data/lib/fontisan/collection.rb +15 -0
  54. data/lib/fontisan/commands/base_command.rb +0 -3
  55. data/lib/fontisan/commands/convert_command.rb +25 -20
  56. data/lib/fontisan/commands/dump_table_command.rb +0 -3
  57. data/lib/fontisan/commands/export_command.rb +0 -4
  58. data/lib/fontisan/commands/features_command.rb +0 -3
  59. data/lib/fontisan/commands/instance_command.rb +0 -5
  60. data/lib/fontisan/commands/ls_command.rb +0 -6
  61. data/lib/fontisan/commands/optical_size_command.rb +0 -3
  62. data/lib/fontisan/commands/pack_command.rb +0 -5
  63. data/lib/fontisan/commands/scripts_command.rb +0 -2
  64. data/lib/fontisan/commands/subset_command.rb +0 -3
  65. data/lib/fontisan/commands/unicode_command.rb +0 -3
  66. data/lib/fontisan/commands/unpack_command.rb +0 -7
  67. data/lib/fontisan/commands/validate_command.rb +0 -8
  68. data/lib/fontisan/commands/variable_command.rb +0 -3
  69. data/lib/fontisan/commands.rb +26 -0
  70. data/lib/fontisan/config/cldr.yml +22 -0
  71. data/lib/fontisan/config/conversion_matrix.yml +38 -0
  72. data/lib/fontisan/constants.rb +19 -0
  73. data/lib/fontisan/conversion_options.rb +30 -19
  74. data/lib/fontisan/converters/cff_table_builder.rb +0 -3
  75. data/lib/fontisan/converters/collection_converter.rb +0 -8
  76. data/lib/fontisan/converters/conversion_strategy.rb +161 -46
  77. data/lib/fontisan/converters/format_converter.rb +143 -32
  78. data/lib/fontisan/converters/glyf_table_builder.rb +0 -2
  79. data/lib/fontisan/converters/outline_converter.rb +0 -19
  80. data/lib/fontisan/converters/outline_extraction.rb +0 -5
  81. data/lib/fontisan/converters/outline_optimizer.rb +0 -5
  82. data/lib/fontisan/converters/svg_generator.rb +0 -4
  83. data/lib/fontisan/converters/table_copier.rb +0 -2
  84. data/lib/fontisan/converters/type1_converter.rb +0 -11
  85. data/lib/fontisan/converters/woff2_encoder.rb +49 -20
  86. data/lib/fontisan/converters/woff_writer.rb +211 -282
  87. data/lib/fontisan/converters.rb +21 -0
  88. data/lib/fontisan/dfont_collection.rb +29 -10
  89. data/lib/fontisan/export/exporter.rb +0 -6
  90. data/lib/fontisan/export/transformers/font_to_ttx.rb +0 -9
  91. data/lib/fontisan/export/transformers/head_transformer.rb +0 -2
  92. data/lib/fontisan/export/transformers/hhea_transformer.rb +0 -2
  93. data/lib/fontisan/export/transformers/maxp_transformer.rb +0 -2
  94. data/lib/fontisan/export/transformers/name_transformer.rb +0 -2
  95. data/lib/fontisan/export/transformers/os2_transformer.rb +0 -2
  96. data/lib/fontisan/export/transformers/post_transformer.rb +0 -2
  97. data/lib/fontisan/export/transformers.rb +17 -0
  98. data/lib/fontisan/export.rb +13 -0
  99. data/lib/fontisan/font_loader.rb +14 -19
  100. data/lib/fontisan/font_writer.rb +0 -1
  101. data/lib/fontisan/formatters.rb +9 -0
  102. data/lib/fontisan/hints/hint_converter.rb +0 -1
  103. data/lib/fontisan/hints/postscript_hint_applier.rb +0 -9
  104. data/lib/fontisan/hints/postscript_hint_extractor.rb +0 -2
  105. data/lib/fontisan/hints/truetype_hint_extractor.rb +0 -2
  106. data/lib/fontisan/hints.rb +19 -0
  107. data/lib/fontisan/metrics_calculator.rb +0 -2
  108. data/lib/fontisan/models/all_scripts_features_info.rb +0 -1
  109. data/lib/fontisan/models/cldr/language_coverage.rb +31 -0
  110. data/lib/fontisan/models/cldr.rb +12 -0
  111. data/lib/fontisan/models/collection_brief_info.rb +0 -1
  112. data/lib/fontisan/models/collection_info.rb +0 -2
  113. data/lib/fontisan/models/collection_list_info.rb +0 -1
  114. data/lib/fontisan/models/collection_validation_report.rb +0 -2
  115. data/lib/fontisan/models/color_glyph.rb +0 -1
  116. data/lib/fontisan/models/font_report.rb +0 -1
  117. data/lib/fontisan/models/ttx/tables.rb +21 -0
  118. data/lib/fontisan/models/ttx/ttfont.rb +0 -8
  119. data/lib/fontisan/models/ttx.rb +14 -0
  120. data/lib/fontisan/models.rb +47 -0
  121. data/lib/fontisan/open_type_collection.rb +6 -5
  122. data/lib/fontisan/open_type_font.rb +8 -2
  123. data/lib/fontisan/open_type_font_extensions.rb +9 -9
  124. data/lib/fontisan/optimizers/pattern_analyzer.rb +0 -1
  125. data/lib/fontisan/optimizers.rb +14 -0
  126. data/lib/fontisan/outline_extractor.rb +0 -2
  127. data/lib/fontisan/parsers/dfont_parser.rb +0 -1
  128. data/lib/fontisan/parsers.rb +10 -0
  129. data/lib/fontisan/pipeline/format_detector.rb +29 -102
  130. data/lib/fontisan/pipeline/output_writer.rb +11 -9
  131. data/lib/fontisan/pipeline/strategies/instance_strategy.rb +0 -4
  132. data/lib/fontisan/pipeline/strategies/named_strategy.rb +0 -4
  133. data/lib/fontisan/pipeline/strategies/preserve_strategy.rb +0 -2
  134. data/lib/fontisan/pipeline/strategies.rb +16 -0
  135. data/lib/fontisan/pipeline/transformation_pipeline.rb +0 -7
  136. data/lib/fontisan/pipeline/variation_resolver.rb +0 -7
  137. data/lib/fontisan/pipeline.rb +14 -0
  138. data/lib/fontisan/sfnt_font.rb +29 -14
  139. data/lib/fontisan/sfnt_table.rb +0 -4
  140. data/lib/fontisan/subset/builder.rb +0 -6
  141. data/lib/fontisan/subset.rb +13 -0
  142. data/lib/fontisan/svg/font_generator.rb +0 -4
  143. data/lib/fontisan/svg/glyph_generator.rb +0 -2
  144. data/lib/fontisan/svg.rb +12 -0
  145. data/lib/fontisan/tables/cbdt.rb +0 -1
  146. data/lib/fontisan/tables/cblc.rb +0 -1
  147. data/lib/fontisan/tables/cff/charset.rb +0 -1
  148. data/lib/fontisan/tables/cff/charstring.rb +0 -1
  149. data/lib/fontisan/tables/cff/charstring_rebuilder.rb +0 -4
  150. data/lib/fontisan/tables/cff/charstrings_index.rb +0 -3
  151. data/lib/fontisan/tables/cff/dict.rb +0 -1
  152. data/lib/fontisan/tables/cff/encoding.rb +0 -1
  153. data/lib/fontisan/tables/cff/header.rb +0 -2
  154. data/lib/fontisan/tables/cff/hint_operation_injector.rb +0 -2
  155. data/lib/fontisan/tables/cff/index.rb +0 -1
  156. data/lib/fontisan/tables/cff/private_dict.rb +0 -2
  157. data/lib/fontisan/tables/cff/private_dict_writer.rb +0 -2
  158. data/lib/fontisan/tables/cff/table_builder.rb +0 -6
  159. data/lib/fontisan/tables/cff/top_dict.rb +0 -2
  160. data/lib/fontisan/tables/cff.rb +23 -15
  161. data/lib/fontisan/tables/cff2/charstring_parser.rb +0 -2
  162. data/lib/fontisan/tables/cff2/table_builder.rb +0 -11
  163. data/lib/fontisan/tables/cff2/table_reader.rb +0 -2
  164. data/lib/fontisan/tables/cff2.rb +13 -14
  165. data/lib/fontisan/tables/cmap.rb +24 -2
  166. data/lib/fontisan/tables/cmap_table.rb +0 -3
  167. data/lib/fontisan/tables/colr.rb +0 -1
  168. data/lib/fontisan/tables/cpal.rb +0 -1
  169. data/lib/fontisan/tables/cvar.rb +0 -2
  170. data/lib/fontisan/tables/fvar.rb +0 -1
  171. data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +0 -2
  172. data/lib/fontisan/tables/glyf/glyph_builder.rb +0 -3
  173. data/lib/fontisan/tables/glyf.rb +0 -6
  174. data/lib/fontisan/tables/glyf_table.rb +0 -3
  175. data/lib/fontisan/tables/gpos.rb +0 -2
  176. data/lib/fontisan/tables/gsub.rb +0 -2
  177. data/lib/fontisan/tables/gvar.rb +0 -2
  178. data/lib/fontisan/tables/head.rb +0 -2
  179. data/lib/fontisan/tables/head_table.rb +0 -3
  180. data/lib/fontisan/tables/hhea.rb +0 -2
  181. data/lib/fontisan/tables/hhea_table.rb +0 -3
  182. data/lib/fontisan/tables/hmtx.rb +0 -2
  183. data/lib/fontisan/tables/hmtx_table.rb +0 -3
  184. data/lib/fontisan/tables/hvar.rb +0 -3
  185. data/lib/fontisan/tables/loca.rb +0 -2
  186. data/lib/fontisan/tables/loca_table.rb +0 -3
  187. data/lib/fontisan/tables/maxp.rb +0 -2
  188. data/lib/fontisan/tables/maxp_table.rb +0 -3
  189. data/lib/fontisan/tables/mvar.rb +0 -3
  190. data/lib/fontisan/tables/name.rb +0 -2
  191. data/lib/fontisan/tables/name_table.rb +0 -3
  192. data/lib/fontisan/tables/os2_table.rb +0 -3
  193. data/lib/fontisan/tables/post_table.rb +0 -3
  194. data/lib/fontisan/tables/sbix.rb +0 -1
  195. data/lib/fontisan/tables/svg.rb +0 -1
  196. data/lib/fontisan/tables/variation_common.rb +0 -1
  197. data/lib/fontisan/tables/vvar.rb +0 -3
  198. data/lib/fontisan/tables.rb +55 -0
  199. data/lib/fontisan/true_type_collection.rb +6 -14
  200. data/lib/fontisan/true_type_font.rb +8 -2
  201. data/lib/fontisan/true_type_font_extensions.rb +9 -9
  202. data/lib/fontisan/type1/afm_generator.rb +0 -4
  203. data/lib/fontisan/type1/conversion_options.rb +0 -2
  204. data/lib/fontisan/type1/encodings.rb +0 -2
  205. data/lib/fontisan/type1/generator.rb +0 -8
  206. data/lib/fontisan/type1/pfa_generator.rb +0 -3
  207. data/lib/fontisan/type1/pfb_generator.rb +0 -5
  208. data/lib/fontisan/type1/pfm_generator.rb +0 -4
  209. data/lib/fontisan/type1.rb +42 -69
  210. data/lib/fontisan/type1_font.rb +40 -11
  211. data/lib/fontisan/utilities/checksum_calculator.rb +0 -1
  212. data/lib/fontisan/utilities.rb +10 -0
  213. data/lib/fontisan/utils.rb +10 -0
  214. data/lib/fontisan/validation/collection_validator.rb +0 -2
  215. data/lib/fontisan/validation.rb +9 -0
  216. data/lib/fontisan/validators/basic_validator.rb +0 -2
  217. data/lib/fontisan/validators/font_book_validator.rb +0 -2
  218. data/lib/fontisan/validators/opentype_validator.rb +0 -2
  219. data/lib/fontisan/validators/profile_loader.rb +0 -5
  220. data/lib/fontisan/validators/validator.rb +0 -2
  221. data/lib/fontisan/validators/web_font_validator.rb +0 -2
  222. data/lib/fontisan/validators.rb +14 -0
  223. data/lib/fontisan/variable/delta_applicator.rb +0 -4
  224. data/lib/fontisan/variable/instancer.rb +0 -3
  225. data/lib/fontisan/variable/static_font_builder.rb +0 -3
  226. data/lib/fontisan/variable.rb +16 -0
  227. data/lib/fontisan/variation/blend_applier.rb +0 -2
  228. data/lib/fontisan/variation/cache.rb +0 -2
  229. data/lib/fontisan/variation/converter.rb +0 -3
  230. data/lib/fontisan/variation/data_extractor.rb +0 -2
  231. data/lib/fontisan/variation/delta_applier.rb +0 -5
  232. data/lib/fontisan/variation/inspector.rb +0 -1
  233. data/lib/fontisan/variation/instance_generator.rb +0 -6
  234. data/lib/fontisan/variation/instance_writer.rb +0 -5
  235. data/lib/fontisan/variation/metrics_adjuster.rb +0 -4
  236. data/lib/fontisan/variation/optimizer.rb +0 -3
  237. data/lib/fontisan/variation/parallel_generator.rb +0 -3
  238. data/lib/fontisan/variation/subsetter.rb +0 -4
  239. data/lib/fontisan/variation/tuple_variation_header.rb +0 -2
  240. data/lib/fontisan/variation/variable_svg_generator.rb +0 -3
  241. data/lib/fontisan/variation/variation_context.rb +0 -3
  242. data/lib/fontisan/variation/variation_preserver.rb +0 -3
  243. data/lib/fontisan/variation.rb +31 -0
  244. data/lib/fontisan/version.rb +1 -1
  245. data/lib/fontisan/woff2.rb +13 -0
  246. data/lib/fontisan/woff2_font.rb +31 -9
  247. data/lib/fontisan/woff_font.rb +31 -2
  248. data/lib/fontisan.rb +121 -196
  249. metadata +46 -2
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "parsers/dfont_parser"
4
- require_relative "error"
5
- require_relative "collection/shared_logic"
6
-
7
3
  module Fontisan
8
4
  # DfontCollection represents an Apple dfont suitcase containing multiple fonts
9
5
  #
@@ -26,6 +22,35 @@ module Fontisan
26
22
  class DfontCollection
27
23
  include Collection::SharedLogic
28
24
 
25
+ # High-level pipeline format identifier. Owned by the collection class
26
+ # so the conversion pipeline can dispatch without case statements (OCP).
27
+ #
28
+ # @return [Symbol] :dfont
29
+ def format = :dfont
30
+
31
+ # Whether this object represents a font collection rather than a single
32
+ # font. Each font class is the authority on this question.
33
+ #
34
+ # @return [Boolean]
35
+ def collection? = true
36
+
37
+ # Variation profile. dfonts are containers; per-font variation is not
38
+ # exposed at the collection level.
39
+ #
40
+ # @return [Symbol] :static
41
+ def variation_type = :static
42
+
43
+ # Outline representation. dfonts may contain mixed-flavor fonts;
44
+ # per-font outline type requires loading an individual font.
45
+ #
46
+ # @return [Symbol] :unknown
47
+ def outline_type = :unknown
48
+
49
+ # Collections have no single SFNT table directory.
50
+ #
51
+ # @return [Array<String>] empty
52
+ def table_names = []
53
+
29
54
  # Path to dfont file
30
55
  # @return [String]
31
56
  attr_reader :path
@@ -138,9 +163,6 @@ module Fontisan
138
163
  # @param io [IO] Open file handle
139
164
  # @return [Models::CollectionListInfo] Collection list info
140
165
  def list_fonts(io)
141
- require_relative "models/collection_list_info"
142
- require_relative "models/collection_font_summary"
143
-
144
166
  fonts = extract_fonts(io)
145
167
 
146
168
  summaries = fonts.map.with_index do |font, index|
@@ -227,9 +249,6 @@ module Fontisan
227
249
  # puts "Format: #{info.collection_format}"
228
250
  # end
229
251
  def collection_info(io, path)
230
- require_relative "models/collection_info"
231
- require_relative "models/table_sharing_info"
232
-
233
252
  # Calculate table sharing statistics
234
253
  table_sharing = calculate_table_sharing(io)
235
254
 
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../models/font_export"
4
- require_relative "table_serializer"
5
- require_relative "ttx_generator"
6
- require_relative "transformers/font_to_ttx"
7
- require_relative "../utilities/checksum_calculator"
8
-
9
3
  module Fontisan
10
4
  module Export
11
5
  # Exporter orchestrates font export to YAML/JSON/TTX
@@ -1,14 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/ttfont"
4
- require_relative "../../models/ttx/glyph_order"
5
- require_relative "head_transformer"
6
- require_relative "name_transformer"
7
- require_relative "os2_transformer"
8
- require_relative "post_transformer"
9
- require_relative "hhea_transformer"
10
- require_relative "maxp_transformer"
11
-
12
3
  module Fontisan
13
4
  module Export
14
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/head_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/hhea_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/maxp_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/name_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/os2_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../models/ttx/tables/post_table"
4
-
5
3
  module Fontisan
6
4
  module Export
7
5
  module Transformers
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Export::Transformers namespace.
4
+
5
+ module Fontisan
6
+ module Export
7
+ module Transformers
8
+ autoload :FontToTtx, "fontisan/export/transformers/font_to_ttx"
9
+ autoload :HeadTransformer, "fontisan/export/transformers/head_transformer"
10
+ autoload :HheaTransformer, "fontisan/export/transformers/hhea_transformer"
11
+ autoload :MaxpTransformer, "fontisan/export/transformers/maxp_transformer"
12
+ autoload :NameTransformer, "fontisan/export/transformers/name_transformer"
13
+ autoload :Os2Transformer, "fontisan/export/transformers/os2_transformer"
14
+ autoload :PostTransformer, "fontisan/export/transformers/post_transformer"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Export namespace.
4
+
5
+ module Fontisan
6
+ module Export
7
+ autoload :Exporter, "fontisan/export/exporter"
8
+ autoload :TableSerializer, "fontisan/export/table_serializer"
9
+ autoload :Transformers, "fontisan/export/transformers/font_to_ttx"
10
+ autoload :TtxGenerator, "fontisan/export/ttx_generator"
11
+ autoload :TtxParser, "fontisan/export/ttx_parser"
12
+ end
13
+ end
@@ -1,18 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require_relative "constants"
5
- require_relative "loading_modes"
6
- require_relative "true_type_font"
7
- require_relative "open_type_font"
8
- require_relative "true_type_collection"
9
- require_relative "open_type_collection"
10
- require_relative "dfont_collection"
11
- require_relative "woff_font"
12
- require_relative "woff2_font"
13
- require_relative "type1_font"
14
- require_relative "parsers/dfont_parser"
15
- require_relative "error"
16
4
 
17
5
  module Fontisan
18
6
  # FontLoader provides unified font loading with content-based format detection.
@@ -85,12 +73,18 @@ module Fontisan
85
73
 
86
74
  format = detect(path)
87
75
  case format
88
- when :ttf then TrueTypeFont.from_file(path, mode: resolved_mode, lazy: resolved_lazy)
89
- when :otf then OpenTypeFont.from_file(path, mode: resolved_mode, lazy: resolved_lazy)
90
- when :woff then WoffFont.from_file(path, mode: resolved_mode, lazy: resolved_lazy)
91
- when :woff2 then Woff2Font.from_file(path, mode: resolved_mode, lazy: resolved_lazy)
92
- when :ttc, :otc then load_from_collection(path, format, font_index, mode: resolved_mode)
93
- when :dfont then load_dfont(path, font_index: font_index, mode: resolved_mode)
76
+ when :ttf then TrueTypeFont.from_file(path, mode: resolved_mode,
77
+ lazy: resolved_lazy)
78
+ when :otf then OpenTypeFont.from_file(path, mode: resolved_mode,
79
+ lazy: resolved_lazy)
80
+ when :woff then WoffFont.from_file(path, mode: resolved_mode,
81
+ lazy: resolved_lazy)
82
+ when :woff2 then Woff2Font.from_file(path, mode: resolved_mode,
83
+ lazy: resolved_lazy)
84
+ when :ttc, :otc then load_from_collection(path, format, font_index,
85
+ mode: resolved_mode)
86
+ when :dfont then load_dfont(path, font_index: font_index,
87
+ mode: resolved_mode)
94
88
  when :pfa, :pfb then Type1Font.from_file(path, mode: resolved_mode)
95
89
  else
96
90
  raise InvalidFontError,
@@ -279,7 +273,8 @@ module Fontisan
279
273
  # public `lazy:` flag is not threaded through this path.
280
274
  def self.load_dfont(path, font_index:, mode:)
281
275
  File.open(path, "rb") do |io|
282
- sfnt_io = StringIO.new(Parsers::DfontParser.extract_sfnt(io, index: font_index))
276
+ sfnt_io = StringIO.new(Parsers::DfontParser.extract_sfnt(io,
277
+ index: font_index))
283
278
  klass = case Constants.sfnt_format_for(sfnt_io.read(4))
284
279
  when :ttf then TrueTypeFont
285
280
  when :otf then OpenTypeFont
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
- require_relative "constants"
5
4
 
6
5
  module Fontisan
7
6
  # FontWriter handles writing font binaries from table data
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Formatters namespace.
4
+
5
+ module Fontisan
6
+ module Formatters
7
+ autoload :TextFormatter, "fontisan/formatters/text_formatter"
8
+ end
9
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
- require_relative "../models/hint"
5
4
 
6
5
  module Fontisan
7
6
  module Hints
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../models/hint"
4
3
  require "json"
5
4
 
6
5
  module Fontisan
@@ -80,9 +79,6 @@ module Fontisan
80
79
  cff2_data = tables["CFF2"] || tables["CFF2 "]
81
80
 
82
81
  begin
83
- require_relative "../tables/cff2/table_reader"
84
- require_relative "../tables/cff2/table_builder"
85
-
86
82
  reader = Tables::Cff2::TableReader.new(cff2_data)
87
83
 
88
84
  # Validate CFF2 version
@@ -131,11 +127,6 @@ module Fontisan
131
127
 
132
128
  # Apply hints (both font-level and per-glyph)
133
129
  begin
134
- require_relative "../tables/cff/table_builder"
135
- require_relative "../tables/cff/charstring_rebuilder"
136
- require_relative "../tables/cff/hint_operation_injector"
137
- require_relative "../tables/cff"
138
-
139
130
  # Parse CFF binary data into Cff object if needed
140
131
  cff_data = tables["CFF "]
141
132
  cff_table = if cff_data.is_a?(Tables::Cff)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../models/hint"
4
-
5
3
  module Fontisan
6
4
  module Hints
7
5
  # Extracts rendering hints from PostScript/CFF CharString data
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../models/hint"
4
-
5
3
  module Fontisan
6
4
  module Hints
7
5
  # Extracts rendering hints from TrueType glyph data
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Hints namespace.
4
+
5
+ module Fontisan
6
+ module Hints
7
+ autoload :HintConverter, "fontisan/hints/hint_converter"
8
+ autoload :HintValidator, "fontisan/hints/hint_validator"
9
+ autoload :PostScriptHintApplier, "fontisan/hints/postscript_hint_applier"
10
+ autoload :PostScriptHintExtractor,
11
+ "fontisan/hints/postscript_hint_extractor"
12
+ autoload :TrueTypeHintApplier, "fontisan/hints/truetype_hint_applier"
13
+ autoload :TrueTypeHintExtractor, "fontisan/hints/truetype_hint_extractor"
14
+ autoload :TrueTypeInstructionAnalyzer,
15
+ "fontisan/hints/truetype_instruction_analyzer"
16
+ autoload :TrueTypeInstructionGenerator,
17
+ "fontisan/hints/truetype_instruction_generator"
18
+ end
19
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "constants"
4
-
5
3
  module Fontisan
6
4
  # High-level utility class for accessing font metrics
7
5
  #
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "features_info"
5
4
 
6
5
  module Fontisan
7
6
  module Models
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Fontisan
6
+ module Models
7
+ module Cldr
8
+ # Per-language coverage for one face against a CLDR exemplar set.
9
+ #
10
+ # `coverage_ratio` is in [0.0, 1.0] rounded to 4 decimal places;
11
+ # `fully_supported` is true only when every required codepoint
12
+ # (total > 0) is covered. A language with total == 0 (empty exemplar
13
+ # set in the index) is reported as ratio 0.0, fully_supported false.
14
+ class LanguageCoverage < Lutaml::Model::Serializable
15
+ attribute :language, :string
16
+ attribute :covered, :integer
17
+ attribute :total, :integer
18
+ attribute :coverage_ratio, :float
19
+ attribute :fully_supported, Lutaml::Model::Type::Boolean
20
+
21
+ key_value do
22
+ map "language", to: :language
23
+ map "covered", to: :covered
24
+ map "total", to: :total
25
+ map "coverage_ratio", to: :coverage_ratio
26
+ map "fully_supported", to: :fully_supported
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Fontisan
6
+ module Models
7
+ # Namespace for CLDR-derived audit models.
8
+ module Cldr
9
+ autoload :LanguageCoverage, "fontisan/models/cldr/language_coverage"
10
+ end
11
+ end
12
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "font_info"
5
4
 
6
5
  module Fontisan
7
6
  module Models
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "table_sharing_info"
5
- require_relative "font_info"
6
4
 
7
5
  module Fontisan
8
6
  module Models
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "collection_font_summary"
5
4
 
6
5
  module Fontisan
7
6
  module Models
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "font_report"
4
- require_relative "validation_report"
5
3
  require "lutaml/model"
6
4
 
7
5
  module Fontisan
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "color_layer"
5
4
 
6
5
  module Fontisan
7
6
  module Models
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "validation_report"
4
3
  require "lutaml/model"
5
4
 
6
5
  module Fontisan
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Models::Ttx::Tables namespace.
4
+
5
+ module Fontisan
6
+ module Models
7
+ module Ttx
8
+ module Tables
9
+ autoload :BinaryTable, "fontisan/models/ttx/tables/binary_table"
10
+ autoload :HeadTable, "fontisan/models/ttx/tables/head_table"
11
+ autoload :HheaTable, "fontisan/models/ttx/tables/hhea_table"
12
+ autoload :MaxpTable, "fontisan/models/ttx/tables/maxp_table"
13
+ autoload :NameRecord, "fontisan/models/ttx/tables/name_table"
14
+ autoload :NameTable, "fontisan/models/ttx/tables/name_table"
15
+ autoload :Os2Table, "fontisan/models/ttx/tables/os2_table"
16
+ autoload :Panose, "fontisan/models/ttx/tables/os2_table"
17
+ autoload :PostTable, "fontisan/models/ttx/tables/post_table"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,14 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "glyph_order"
5
- require_relative "tables/head_table"
6
- require_relative "tables/name_table"
7
- require_relative "tables/maxp_table"
8
- require_relative "tables/hhea_table"
9
- require_relative "tables/os2_table"
10
- require_relative "tables/post_table"
11
- require_relative "tables/binary_table"
12
4
 
13
5
  module Fontisan
14
6
  module Models
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Models::Ttx namespace.
4
+
5
+ module Fontisan
6
+ module Models
7
+ module Ttx
8
+ autoload :GlyphId, "fontisan/models/ttx/glyph_order"
9
+ autoload :GlyphOrder, "fontisan/models/ttx/glyph_order"
10
+ autoload :Tables, "fontisan/models/ttx/tables/os2_table"
11
+ autoload :TtFont, "fontisan/models/ttx/ttfont"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Models namespace.
4
+
5
+ module Fontisan
6
+ module Models
7
+ autoload :AllScriptsFeaturesInfo,
8
+ "fontisan/models/all_scripts_features_info"
9
+ autoload :AxisInfo, "fontisan/models/variable_font_info"
10
+ autoload :BitmapGlyph, "fontisan/models/bitmap_glyph"
11
+ autoload :BitmapStrike, "fontisan/models/bitmap_strike"
12
+ autoload :CollectionBriefInfo, "fontisan/models/collection_brief_info"
13
+ autoload :CollectionFontSummary, "fontisan/models/collection_font_summary"
14
+ autoload :CollectionInfo, "fontisan/models/collection_info"
15
+ autoload :CollectionListInfo, "fontisan/models/collection_list_info"
16
+ autoload :CollectionValidationReport,
17
+ "fontisan/models/collection_validation_report"
18
+ autoload :Cldr, "fontisan/models/cldr"
19
+ autoload :ColorGlyph, "fontisan/models/color_glyph"
20
+ autoload :ColorLayer, "fontisan/models/color_layer"
21
+ autoload :ColorPalette, "fontisan/models/color_palette"
22
+ autoload :FeatureRecord, "fontisan/models/features_info"
23
+ autoload :FeaturesInfo, "fontisan/models/features_info"
24
+ autoload :FontExport, "fontisan/models/font_export"
25
+ autoload :FontInfo, "fontisan/models/font_info"
26
+ autoload :FontReport, "fontisan/models/font_report"
27
+ autoload :FontSummary, "fontisan/models/font_summary"
28
+ autoload :GlyphInfo, "fontisan/models/glyph_info"
29
+ autoload :GlyphOutline, "fontisan/models/glyph_outline"
30
+ autoload :Hint, "fontisan/models/hint"
31
+ autoload :HintSet, "fontisan/models/hint"
32
+ autoload :InstanceInfo, "fontisan/models/variable_font_info"
33
+ autoload :OpticalSizeInfo, "fontisan/models/optical_size_info"
34
+ autoload :Outline, "fontisan/models/outline"
35
+ autoload :ScriptRecord, "fontisan/models/scripts_info"
36
+ autoload :ScriptsInfo, "fontisan/models/scripts_info"
37
+ autoload :SvgGlyph, "fontisan/models/svg_glyph"
38
+ autoload :TableEntry, "fontisan/models/table_info"
39
+ autoload :TableInfo, "fontisan/models/table_info"
40
+ autoload :TableSharingInfo, "fontisan/models/table_sharing_info"
41
+ autoload :Ttx, "fontisan/models/ttx/ttfont"
42
+ autoload :UnicodeMapping, "fontisan/models/unicode_mappings"
43
+ autoload :UnicodeMappings, "fontisan/models/unicode_mappings"
44
+ autoload :ValidationReport, "fontisan/models/validation_report"
45
+ autoload :VariableFontInfo, "fontisan/models/variable_font_info"
46
+ end
47
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base_collection"
4
-
5
3
  module Fontisan
6
4
  # OpenType Collection domain object
7
5
  #
@@ -15,11 +13,16 @@ module Fontisan
15
13
  # fonts = otc.extract_fonts(io) # => [OpenTypeFont, OpenTypeFont, ...]
16
14
  # end
17
15
  class OpenTypeCollection < BaseCollection
16
+ # High-level pipeline format identifier. Owned by the collection class
17
+ # so the conversion pipeline can dispatch without case statements (OCP).
18
+ #
19
+ # @return [Symbol] :otc
20
+ def format = :otc
21
+
18
22
  # Get the font class for OpenType collections
19
23
  #
20
24
  # @return [Class] OpenTypeFont class
21
25
  def self.font_class
22
- require_relative "open_type_font"
23
26
  OpenTypeFont
24
27
  end
25
28
 
@@ -38,8 +41,6 @@ module Fontisan
38
41
  # @param io [IO] Open file handle to read fonts from
39
42
  # @return [Array<OpenTypeFont>] Array of font objects
40
43
  def extract_fonts(io)
41
- require_relative "open_type_font"
42
-
43
44
  font_offsets.map do |offset|
44
45
  OpenTypeFont.from_collection(io, offset)
45
46
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "sfnt_font"
4
-
5
3
  module Fontisan
6
4
  # OpenType Font domain object
7
5
  #
@@ -26,6 +24,14 @@ module Fontisan
26
24
  # @example Reading from TTC collection
27
25
  # otf = OpenTypeFont.from_collection(io, offset)
28
26
  class OpenTypeFont < SfntFont
27
+ extend OpenTypeFontExtensions
28
+
29
+ # High-level pipeline format identifier. Owned by the font class so the
30
+ # conversion pipeline can dispatch without case statements (OCP).
31
+ #
32
+ # @return [Symbol] :otf
33
+ def format = :otf
34
+
29
35
  # Page cache for lazy loading (maps page_start_offset => page_data)
30
36
  attr_accessor :page_cache
31
37
 
@@ -1,24 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- # Extensions to OpenTypeFont for table-based construction
5
- class OpenTypeFont
4
+ # Extension module for {OpenTypeFont} providing table-based construction.
5
+ #
6
+ # Extended into OpenTypeFont from +open_type_font.rb+ so that
7
+ # +OpenTypeFont.from_tables(...)+ is available whenever the class
8
+ # itself is loaded.
9
+ module OpenTypeFontExtensions
6
10
  # Create font from hash of tables
7
11
  #
8
12
  # This is used during font conversion when we have tables but not a file.
9
13
  #
10
14
  # @param tables [Hash<String, String>] Map of table tag to binary data
11
15
  # @return [OpenTypeFont] New font instance
12
- def self.from_tables(tables)
13
- # Create minimal header structure
16
+ def from_tables(tables)
14
17
  font = new
15
18
  font.initialize_storage
16
19
  font.loading_mode = LoadingModes::FULL
17
20
 
18
- # Store table data
19
21
  font.table_data = tables
20
22
 
21
- # Build header from tables
22
23
  num_tables = tables.size
23
24
  max_power = 0
24
25
  n = num_tables
@@ -37,13 +38,12 @@ module Fontisan
37
38
  font.header.entry_selector = entry_selector
38
39
  font.header.range_shift = range_shift
39
40
 
40
- # Build table directory
41
41
  font.tables.clear
42
42
  tables.each_key do |tag|
43
43
  entry = TableDirectory.new
44
44
  entry.tag = tag
45
- entry.checksum = 0 # Will be calculated on write
46
- entry.offset = 0 # Will be calculated on write
45
+ entry.checksum = 0
46
+ entry.offset = 0
47
47
  entry.table_length = tables[tag].bytesize
48
48
  font.tables << entry
49
49
  end