fontisan 0.2.16 → 0.2.22

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 (318) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +14 -90
  3. data/Gemfile +6 -3
  4. data/README.adoc +257 -1
  5. data/docs/.vitepress/config.ts +68 -8
  6. data/docs/.vitepress/theme/style.css +570 -272
  7. data/docs/CONVERSION_GUIDE.adoc +31 -8
  8. data/docs/EXTRACT_TTC_MIGRATION.md +1 -1
  9. data/docs/WOFF_WOFF2_FORMATS.adoc +53 -0
  10. data/docs/api/conversion-options.md +37 -14
  11. data/docs/api/font-loader.md +21 -15
  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/audit/codepoint_range_coalescer.rb +41 -0
  33. data/lib/fontisan/audit/context.rb +122 -0
  34. data/lib/fontisan/audit/differ.rb +124 -0
  35. data/lib/fontisan/audit/extractors/aggregations.rb +54 -0
  36. data/lib/fontisan/audit/extractors/base.rb +26 -0
  37. data/lib/fontisan/audit/extractors/color_capabilities.rb +141 -0
  38. data/lib/fontisan/audit/extractors/coverage.rb +48 -0
  39. data/lib/fontisan/audit/extractors/hinting.rb +197 -0
  40. data/lib/fontisan/audit/extractors/identity.rb +52 -0
  41. data/lib/fontisan/audit/extractors/language_coverage.rb +37 -0
  42. data/lib/fontisan/audit/extractors/licensing.rb +79 -0
  43. data/lib/fontisan/audit/extractors/metrics.rb +103 -0
  44. data/lib/fontisan/audit/extractors/opentype_layout.rb +69 -0
  45. data/lib/fontisan/audit/extractors/provenance.rb +29 -0
  46. data/lib/fontisan/audit/extractors/style.rb +32 -0
  47. data/lib/fontisan/audit/extractors/variation_detail.rb +99 -0
  48. data/lib/fontisan/audit/extractors.rb +27 -0
  49. data/lib/fontisan/audit/library_aggregator.rb +83 -0
  50. data/lib/fontisan/audit/library_auditor.rb +90 -0
  51. data/lib/fontisan/audit/registry.rb +60 -0
  52. data/lib/fontisan/audit/style_extractor.rb +80 -0
  53. data/lib/fontisan/audit.rb +20 -0
  54. data/lib/fontisan/base_collection.rb +23 -9
  55. data/lib/fontisan/binary/structures.rb +0 -2
  56. data/lib/fontisan/binary.rb +11 -0
  57. data/lib/fontisan/cldr/aggregator.rb +33 -0
  58. data/lib/fontisan/cldr/cache_manager.rb +110 -0
  59. data/lib/fontisan/cldr/config.rb +59 -0
  60. data/lib/fontisan/cldr/download_error.rb +9 -0
  61. data/lib/fontisan/cldr/downloader.rb +79 -0
  62. data/lib/fontisan/cldr/error.rb +8 -0
  63. data/lib/fontisan/cldr/index.rb +64 -0
  64. data/lib/fontisan/cldr/index_builder.rb +72 -0
  65. data/lib/fontisan/cldr/unicode_set_parser.rb +172 -0
  66. data/lib/fontisan/cldr/unknown_version_error.rb +9 -0
  67. data/lib/fontisan/cldr/version_resolver.rb +91 -0
  68. data/lib/fontisan/cldr.rb +23 -0
  69. data/lib/fontisan/cli/cldr_cli.rb +85 -0
  70. data/lib/fontisan/cli/ucd_cli.rb +97 -0
  71. data/lib/fontisan/cli.rb +201 -2
  72. data/lib/fontisan/collection/builder.rb +0 -4
  73. data/lib/fontisan/collection/dfont_builder.rb +0 -4
  74. data/lib/fontisan/collection/shared_logic.rb +0 -2
  75. data/lib/fontisan/collection/writer.rb +0 -3
  76. data/lib/fontisan/collection.rb +15 -0
  77. data/lib/fontisan/commands/audit_command.rb +123 -0
  78. data/lib/fontisan/commands/audit_compare_command.rb +66 -0
  79. data/lib/fontisan/commands/audit_library_command.rb +46 -0
  80. data/lib/fontisan/commands/base_command.rb +0 -3
  81. data/lib/fontisan/commands/convert_command.rb +25 -20
  82. data/lib/fontisan/commands/dump_table_command.rb +0 -3
  83. data/lib/fontisan/commands/export_command.rb +0 -4
  84. data/lib/fontisan/commands/features_command.rb +0 -3
  85. data/lib/fontisan/commands/instance_command.rb +0 -5
  86. data/lib/fontisan/commands/ls_command.rb +0 -6
  87. data/lib/fontisan/commands/optical_size_command.rb +0 -3
  88. data/lib/fontisan/commands/pack_command.rb +0 -5
  89. data/lib/fontisan/commands/scripts_command.rb +0 -2
  90. data/lib/fontisan/commands/subset_command.rb +0 -3
  91. data/lib/fontisan/commands/unicode_command.rb +0 -3
  92. data/lib/fontisan/commands/unpack_command.rb +0 -7
  93. data/lib/fontisan/commands/validate_command.rb +0 -8
  94. data/lib/fontisan/commands/variable_command.rb +0 -3
  95. data/lib/fontisan/commands.rb +29 -0
  96. data/lib/fontisan/config/cldr.yml +22 -0
  97. data/lib/fontisan/config/conversion_matrix.yml +38 -0
  98. data/lib/fontisan/config/ucd.yml +23 -0
  99. data/lib/fontisan/constants.rb +48 -6
  100. data/lib/fontisan/conversion_options.rb +30 -19
  101. data/lib/fontisan/converters/cff_table_builder.rb +0 -3
  102. data/lib/fontisan/converters/collection_converter.rb +0 -8
  103. data/lib/fontisan/converters/conversion_strategy.rb +161 -46
  104. data/lib/fontisan/converters/format_converter.rb +143 -32
  105. data/lib/fontisan/converters/glyf_table_builder.rb +0 -2
  106. data/lib/fontisan/converters/outline_converter.rb +0 -19
  107. data/lib/fontisan/converters/outline_extraction.rb +0 -5
  108. data/lib/fontisan/converters/outline_optimizer.rb +0 -5
  109. data/lib/fontisan/converters/svg_generator.rb +0 -4
  110. data/lib/fontisan/converters/table_copier.rb +0 -2
  111. data/lib/fontisan/converters/type1_converter.rb +0 -11
  112. data/lib/fontisan/converters/woff2_encoder.rb +49 -20
  113. data/lib/fontisan/converters/woff_writer.rb +211 -282
  114. data/lib/fontisan/converters.rb +21 -0
  115. data/lib/fontisan/dfont_collection.rb +29 -10
  116. data/lib/fontisan/export/exporter.rb +0 -6
  117. data/lib/fontisan/export/transformers/font_to_ttx.rb +0 -9
  118. data/lib/fontisan/export/transformers/head_transformer.rb +0 -2
  119. data/lib/fontisan/export/transformers/hhea_transformer.rb +0 -2
  120. data/lib/fontisan/export/transformers/maxp_transformer.rb +0 -2
  121. data/lib/fontisan/export/transformers/name_transformer.rb +0 -2
  122. data/lib/fontisan/export/transformers/os2_transformer.rb +0 -2
  123. data/lib/fontisan/export/transformers/post_transformer.rb +0 -2
  124. data/lib/fontisan/export/transformers.rb +17 -0
  125. data/lib/fontisan/export.rb +13 -0
  126. data/lib/fontisan/font_loader.rb +189 -328
  127. data/lib/fontisan/font_writer.rb +0 -1
  128. data/lib/fontisan/formatters/audit_diff_text_renderer.rb +122 -0
  129. data/lib/fontisan/formatters/audit_text_renderer.rb +324 -0
  130. data/lib/fontisan/formatters/library_summary_text_renderer.rb +99 -0
  131. data/lib/fontisan/formatters/text_formatter.rb +6 -0
  132. data/lib/fontisan/formatters.rb +12 -0
  133. data/lib/fontisan/hints/hint_converter.rb +0 -1
  134. data/lib/fontisan/hints/postscript_hint_applier.rb +0 -9
  135. data/lib/fontisan/hints/postscript_hint_extractor.rb +0 -2
  136. data/lib/fontisan/hints/truetype_hint_extractor.rb +0 -2
  137. data/lib/fontisan/hints.rb +16 -0
  138. data/lib/fontisan/metrics_calculator.rb +0 -2
  139. data/lib/fontisan/models/all_scripts_features_info.rb +0 -1
  140. data/lib/fontisan/models/audit/audit_axis.rb +30 -0
  141. data/lib/fontisan/models/audit/audit_block.rb +32 -0
  142. data/lib/fontisan/models/audit/audit_diff.rb +77 -0
  143. data/lib/fontisan/models/audit/audit_report.rb +153 -0
  144. data/lib/fontisan/models/audit/codepoint_range.rb +40 -0
  145. data/lib/fontisan/models/audit/codepoint_set_diff.rb +34 -0
  146. data/lib/fontisan/models/audit/color_capabilities.rb +93 -0
  147. data/lib/fontisan/models/audit/duplicate_group.rb +23 -0
  148. data/lib/fontisan/models/audit/embedding_type.rb +76 -0
  149. data/lib/fontisan/models/audit/field_change.rb +28 -0
  150. data/lib/fontisan/models/audit/fs_selection_flags.rb +61 -0
  151. data/lib/fontisan/models/audit/gasp_range.rb +63 -0
  152. data/lib/fontisan/models/audit/hinting.rb +93 -0
  153. data/lib/fontisan/models/audit/library_summary.rb +40 -0
  154. data/lib/fontisan/models/audit/licensing.rb +48 -0
  155. data/lib/fontisan/models/audit/metrics.rb +111 -0
  156. data/lib/fontisan/models/audit/named_instance.rb +41 -0
  157. data/lib/fontisan/models/audit/opentype_layout.rb +40 -0
  158. data/lib/fontisan/models/audit/script_coverage_row.rb +26 -0
  159. data/lib/fontisan/models/audit/script_features.rb +28 -0
  160. data/lib/fontisan/models/audit/variation_detail.rb +44 -0
  161. data/lib/fontisan/models/audit.rb +33 -0
  162. data/lib/fontisan/models/cldr/language_coverage.rb +31 -0
  163. data/lib/fontisan/models/cldr.rb +12 -0
  164. data/lib/fontisan/models/collection_brief_info.rb +0 -1
  165. data/lib/fontisan/models/collection_info.rb +0 -2
  166. data/lib/fontisan/models/collection_list_info.rb +0 -1
  167. data/lib/fontisan/models/collection_validation_report.rb +0 -2
  168. data/lib/fontisan/models/color_glyph.rb +0 -1
  169. data/lib/fontisan/models/font_report.rb +0 -1
  170. data/lib/fontisan/models/ttx/tables.rb +21 -0
  171. data/lib/fontisan/models/ttx/ttfont.rb +0 -8
  172. data/lib/fontisan/models/ttx.rb +14 -0
  173. data/lib/fontisan/models/ucd/ucd.rb +38 -0
  174. data/lib/fontisan/models/ucd/ucd_char.rb +67 -0
  175. data/lib/fontisan/models/ucd.rb +19 -0
  176. data/lib/fontisan/models.rb +47 -0
  177. data/lib/fontisan/open_type_collection.rb +6 -5
  178. data/lib/fontisan/open_type_font.rb +8 -2
  179. data/lib/fontisan/open_type_font_extensions.rb +9 -9
  180. data/lib/fontisan/optimizers/pattern_analyzer.rb +0 -1
  181. data/lib/fontisan/optimizers.rb +14 -0
  182. data/lib/fontisan/outline_extractor.rb +0 -2
  183. data/lib/fontisan/parsers/dfont_parser.rb +0 -1
  184. data/lib/fontisan/parsers.rb +10 -0
  185. data/lib/fontisan/pipeline/format_detector.rb +29 -102
  186. data/lib/fontisan/pipeline/output_writer.rb +11 -9
  187. data/lib/fontisan/pipeline/strategies/instance_strategy.rb +0 -4
  188. data/lib/fontisan/pipeline/strategies/named_strategy.rb +0 -4
  189. data/lib/fontisan/pipeline/strategies/preserve_strategy.rb +0 -2
  190. data/lib/fontisan/pipeline/strategies.rb +14 -0
  191. data/lib/fontisan/pipeline/transformation_pipeline.rb +0 -7
  192. data/lib/fontisan/pipeline/variation_resolver.rb +0 -7
  193. data/lib/fontisan/pipeline.rb +13 -0
  194. data/lib/fontisan/sfnt_font.rb +29 -14
  195. data/lib/fontisan/sfnt_table.rb +0 -4
  196. data/lib/fontisan/subset/builder.rb +0 -6
  197. data/lib/fontisan/subset.rb +13 -0
  198. data/lib/fontisan/svg/font_generator.rb +0 -4
  199. data/lib/fontisan/svg/glyph_generator.rb +0 -2
  200. data/lib/fontisan/svg.rb +12 -0
  201. data/lib/fontisan/tables/cbdt.rb +0 -1
  202. data/lib/fontisan/tables/cblc.rb +0 -1
  203. data/lib/fontisan/tables/cff/charset.rb +0 -1
  204. data/lib/fontisan/tables/cff/charstring.rb +0 -1
  205. data/lib/fontisan/tables/cff/charstring_rebuilder.rb +0 -4
  206. data/lib/fontisan/tables/cff/charstrings_index.rb +0 -3
  207. data/lib/fontisan/tables/cff/dict.rb +0 -1
  208. data/lib/fontisan/tables/cff/encoding.rb +0 -1
  209. data/lib/fontisan/tables/cff/header.rb +0 -2
  210. data/lib/fontisan/tables/cff/hint_operation_injector.rb +0 -2
  211. data/lib/fontisan/tables/cff/index.rb +0 -1
  212. data/lib/fontisan/tables/cff/private_dict.rb +0 -2
  213. data/lib/fontisan/tables/cff/private_dict_writer.rb +0 -2
  214. data/lib/fontisan/tables/cff/table_builder.rb +0 -6
  215. data/lib/fontisan/tables/cff/top_dict.rb +0 -2
  216. data/lib/fontisan/tables/cff.rb +22 -15
  217. data/lib/fontisan/tables/cff2/charstring_parser.rb +0 -2
  218. data/lib/fontisan/tables/cff2/table_builder.rb +0 -11
  219. data/lib/fontisan/tables/cff2/table_reader.rb +0 -2
  220. data/lib/fontisan/tables/cff2.rb +13 -14
  221. data/lib/fontisan/tables/cmap.rb +24 -2
  222. data/lib/fontisan/tables/cmap_table.rb +0 -3
  223. data/lib/fontisan/tables/colr.rb +0 -1
  224. data/lib/fontisan/tables/cpal.rb +0 -1
  225. data/lib/fontisan/tables/cvar.rb +0 -2
  226. data/lib/fontisan/tables/fvar.rb +0 -1
  227. data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +0 -2
  228. data/lib/fontisan/tables/glyf/glyph_builder.rb +0 -3
  229. data/lib/fontisan/tables/glyf.rb +0 -6
  230. data/lib/fontisan/tables/glyf_table.rb +0 -3
  231. data/lib/fontisan/tables/gpos.rb +0 -2
  232. data/lib/fontisan/tables/gsub.rb +0 -2
  233. data/lib/fontisan/tables/gvar.rb +0 -2
  234. data/lib/fontisan/tables/head.rb +0 -2
  235. data/lib/fontisan/tables/head_table.rb +0 -3
  236. data/lib/fontisan/tables/hhea.rb +0 -2
  237. data/lib/fontisan/tables/hhea_table.rb +0 -3
  238. data/lib/fontisan/tables/hmtx.rb +0 -2
  239. data/lib/fontisan/tables/hmtx_table.rb +0 -3
  240. data/lib/fontisan/tables/hvar.rb +0 -3
  241. data/lib/fontisan/tables/loca.rb +0 -2
  242. data/lib/fontisan/tables/loca_table.rb +0 -3
  243. data/lib/fontisan/tables/maxp.rb +0 -2
  244. data/lib/fontisan/tables/maxp_table.rb +0 -3
  245. data/lib/fontisan/tables/mvar.rb +0 -3
  246. data/lib/fontisan/tables/name.rb +0 -2
  247. data/lib/fontisan/tables/name_table.rb +0 -3
  248. data/lib/fontisan/tables/os2_table.rb +0 -3
  249. data/lib/fontisan/tables/post_table.rb +0 -3
  250. data/lib/fontisan/tables/sbix.rb +0 -1
  251. data/lib/fontisan/tables/svg.rb +0 -1
  252. data/lib/fontisan/tables/variation_common.rb +0 -1
  253. data/lib/fontisan/tables/vvar.rb +0 -3
  254. data/lib/fontisan/tables.rb +54 -0
  255. data/lib/fontisan/true_type_collection.rb +6 -14
  256. data/lib/fontisan/true_type_font.rb +8 -2
  257. data/lib/fontisan/true_type_font_extensions.rb +9 -9
  258. data/lib/fontisan/type1/afm_generator.rb +0 -4
  259. data/lib/fontisan/type1/conversion_options.rb +0 -2
  260. data/lib/fontisan/type1/encodings.rb +0 -2
  261. data/lib/fontisan/type1/generator.rb +0 -8
  262. data/lib/fontisan/type1/pfa_generator.rb +0 -3
  263. data/lib/fontisan/type1/pfb_generator.rb +0 -5
  264. data/lib/fontisan/type1/pfm_generator.rb +0 -4
  265. data/lib/fontisan/type1.rb +42 -69
  266. data/lib/fontisan/type1_font.rb +40 -11
  267. data/lib/fontisan/ucd/aggregator.rb +73 -0
  268. data/lib/fontisan/ucd/cache_manager.rb +111 -0
  269. data/lib/fontisan/ucd/config.rb +59 -0
  270. data/lib/fontisan/ucd/download_error.rb +9 -0
  271. data/lib/fontisan/ucd/downloader.rb +88 -0
  272. data/lib/fontisan/ucd/error.rb +8 -0
  273. data/lib/fontisan/ucd/index.rb +103 -0
  274. data/lib/fontisan/ucd/index_builder.rb +107 -0
  275. data/lib/fontisan/ucd/range_entry.rb +56 -0
  276. data/lib/fontisan/ucd/unknown_version_error.rb +9 -0
  277. data/lib/fontisan/ucd/version_resolver.rb +79 -0
  278. data/lib/fontisan/ucd.rb +23 -0
  279. data/lib/fontisan/utilities/checksum_calculator.rb +0 -1
  280. data/lib/fontisan/utilities.rb +10 -0
  281. data/lib/fontisan/utils.rb +10 -0
  282. data/lib/fontisan/validation/collection_validator.rb +0 -2
  283. data/lib/fontisan/validation.rb +9 -0
  284. data/lib/fontisan/validators/basic_validator.rb +0 -2
  285. data/lib/fontisan/validators/font_book_validator.rb +0 -2
  286. data/lib/fontisan/validators/opentype_validator.rb +0 -2
  287. data/lib/fontisan/validators/profile_loader.rb +0 -5
  288. data/lib/fontisan/validators/validator.rb +0 -2
  289. data/lib/fontisan/validators/web_font_validator.rb +0 -2
  290. data/lib/fontisan/validators.rb +14 -0
  291. data/lib/fontisan/variable/delta_applicator.rb +0 -4
  292. data/lib/fontisan/variable/instancer.rb +0 -3
  293. data/lib/fontisan/variable/static_font_builder.rb +0 -3
  294. data/lib/fontisan/variable.rb +16 -0
  295. data/lib/fontisan/variation/blend_applier.rb +0 -2
  296. data/lib/fontisan/variation/cache.rb +0 -2
  297. data/lib/fontisan/variation/converter.rb +0 -3
  298. data/lib/fontisan/variation/data_extractor.rb +0 -2
  299. data/lib/fontisan/variation/delta_applier.rb +0 -5
  300. data/lib/fontisan/variation/inspector.rb +0 -1
  301. data/lib/fontisan/variation/instance_generator.rb +0 -6
  302. data/lib/fontisan/variation/instance_writer.rb +0 -5
  303. data/lib/fontisan/variation/metrics_adjuster.rb +0 -4
  304. data/lib/fontisan/variation/optimizer.rb +0 -3
  305. data/lib/fontisan/variation/parallel_generator.rb +0 -3
  306. data/lib/fontisan/variation/subsetter.rb +0 -4
  307. data/lib/fontisan/variation/tuple_variation_header.rb +0 -2
  308. data/lib/fontisan/variation/variable_svg_generator.rb +0 -3
  309. data/lib/fontisan/variation/variation_context.rb +0 -3
  310. data/lib/fontisan/variation/variation_preserver.rb +0 -3
  311. data/lib/fontisan/variation.rb +31 -0
  312. data/lib/fontisan/version.rb +1 -1
  313. data/lib/fontisan/woff2.rb +13 -0
  314. data/lib/fontisan/woff2_font.rb +31 -9
  315. data/lib/fontisan/woff_font.rb +31 -2
  316. data/lib/fontisan.rb +124 -196
  317. metadata +128 -7
  318. data/fontisan.gemspec +0 -47
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "hmtx"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'hmtx' (Horizontal Metrics) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
- require_relative "variation_common"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # Parser for the 'HVAR' (Horizontal Metrics Variations) table
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
-
5
3
  module Fontisan
6
4
  module Tables
7
5
  # Parser for the 'loca' (Index to Location) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "loca"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'loca' (Index to Location) table
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
-
5
3
  module Fontisan
6
4
  module Tables
7
5
  # BinData structure for the 'maxp' (Maximum Profile) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "maxp"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'maxp' (Maximum Profile) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
- require_relative "variation_common"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # Parser for the 'MVAR' (Metrics Variations) table
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
-
5
3
  module Fontisan
6
4
  module Tables
7
5
  # BinData structure for a single name record
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "name"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'name' (Naming) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "os2"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'OS/2' (OS/2 and Windows Metrics) table
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../sfnt_table"
4
- require_relative "post"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # OOP representation of the 'post' (PostScript) table
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require_relative "../binary/base_record"
5
4
 
6
5
  module Fontisan
7
6
  module Tables
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "stringio"
4
4
  require "zlib"
5
- require_relative "../binary/base_record"
6
5
 
7
6
  module Fontisan
8
7
  module Tables
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require_relative "../binary/base_record"
5
4
 
6
5
  module Fontisan
7
6
  module Tables
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../binary/base_record"
4
- require_relative "variation_common"
5
-
6
3
  module Fontisan
7
4
  module Tables
8
5
  # Parser for the 'VVAR' (Vertical Metrics Variations) table
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Tables namespace.
4
+
5
+ module Fontisan
6
+ module Tables
7
+ autoload :Cbdt, "fontisan/tables/cbdt"
8
+ autoload :Cblc, "fontisan/tables/cblc"
9
+ autoload :Cff, "fontisan/tables/cff"
10
+ autoload :Cff2, "fontisan/tables/cff2"
11
+ autoload :Cmap, "fontisan/tables/cmap"
12
+ autoload :CmapTable, "fontisan/tables/cmap_table"
13
+ autoload :Colr, "fontisan/tables/colr"
14
+ autoload :CompoundGlyph, "fontisan/tables/glyf/compound_glyph"
15
+ autoload :CompoundGlyphResolver, "fontisan/tables/glyf/compound_glyph_resolver"
16
+ autoload :Cpal, "fontisan/tables/cpal"
17
+ autoload :CurveConverter, "fontisan/tables/glyf/curve_converter"
18
+ autoload :Cvar, "fontisan/tables/cvar"
19
+ autoload :Fvar, "fontisan/tables/fvar"
20
+ autoload :Glyf, "fontisan/tables/glyf"
21
+ autoload :GlyfTable, "fontisan/tables/glyf_table"
22
+ autoload :GlyphBuilder, "fontisan/tables/glyf/glyph_builder"
23
+ autoload :Gpos, "fontisan/tables/gpos"
24
+ autoload :Gsub, "fontisan/tables/gsub"
25
+ autoload :Gvar, "fontisan/tables/gvar"
26
+ autoload :Head, "fontisan/tables/head"
27
+ autoload :HeadTable, "fontisan/tables/head_table"
28
+ autoload :Hhea, "fontisan/tables/hhea"
29
+ autoload :HheaTable, "fontisan/tables/hhea_table"
30
+ autoload :Hmtx, "fontisan/tables/hmtx"
31
+ autoload :HmtxTable, "fontisan/tables/hmtx_table"
32
+ autoload :Hvar, "fontisan/tables/hvar"
33
+ autoload :InstanceRecord, "fontisan/tables/fvar"
34
+ autoload :LayoutCommon, "fontisan/tables/layout_common"
35
+ autoload :Loca, "fontisan/tables/loca"
36
+ autoload :LocaTable, "fontisan/tables/loca_table"
37
+ autoload :Maxp, "fontisan/tables/maxp"
38
+ autoload :MaxpTable, "fontisan/tables/maxp_table"
39
+ autoload :Mvar, "fontisan/tables/mvar"
40
+ autoload :Name, "fontisan/tables/name"
41
+ autoload :NameRecord, "fontisan/tables/name"
42
+ autoload :NameTable, "fontisan/tables/name_table"
43
+ autoload :Os2, "fontisan/tables/os2"
44
+ autoload :Os2Table, "fontisan/tables/os2_table"
45
+ autoload :Post, "fontisan/tables/post"
46
+ autoload :PostTable, "fontisan/tables/post_table"
47
+ autoload :Sbix, "fontisan/tables/sbix"
48
+ autoload :SimpleGlyph, "fontisan/tables/glyf/simple_glyph"
49
+ autoload :Svg, "fontisan/tables/svg"
50
+ autoload :VariationAxisRecord, "fontisan/tables/fvar"
51
+ autoload :VariationCommon, "fontisan/tables/variation_common"
52
+ autoload :Vvar, "fontisan/tables/vvar"
53
+ end
54
+ 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
  # TrueType Collection domain object
7
5
  #
@@ -15,11 +13,16 @@ module Fontisan
15
13
  # fonts = ttc.extract_fonts(io) # => [TrueTypeFont, TrueTypeFont, ...]
16
14
  # end
17
15
  class TrueTypeCollection < 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] :ttc
20
+ def format = :ttc
21
+
18
22
  # Get the font class for TrueType collections
19
23
  #
20
24
  # @return [Class] TrueTypeFont class
21
25
  def self.font_class
22
- require_relative "true_type_font"
23
26
  TrueTypeFont
24
27
  end
25
28
 
@@ -41,7 +44,6 @@ module Fontisan
41
44
  def font(index, io, mode: LoadingModes::FULL)
42
45
  return nil if index >= num_fonts
43
46
 
44
- require_relative "true_type_font"
45
47
  TrueTypeFont.from_collection(io, font_offsets[index], mode: mode)
46
48
  end
47
49
 
@@ -53,8 +55,6 @@ module Fontisan
53
55
  # @param io [IO] Open file handle to read fonts from
54
56
  # @return [Array<TrueTypeFont>] Array of font objects
55
57
  def extract_fonts(io)
56
- require_relative "true_type_font"
57
-
58
58
  font_offsets.map do |offset|
59
59
  TrueTypeFont.from_collection(io, offset)
60
60
  end
@@ -67,11 +67,6 @@ module Fontisan
67
67
  # @param io [IO] Open file handle to read fonts from
68
68
  # @return [CollectionListInfo] List of fonts with metadata
69
69
  def list_fonts(io)
70
- require_relative "models/collection_list_info"
71
- require_relative "models/collection_font_summary"
72
- require_relative "true_type_font"
73
- require_relative "tables/name"
74
-
75
70
  fonts = font_offsets.map.with_index do |offset, index|
76
71
  font = TrueTypeFont.from_collection(io, offset)
77
72
 
@@ -124,9 +119,6 @@ module Fontisan
124
119
  # @param io [IO] Open file handle
125
120
  # @return [TableSharingInfo] Sharing statistics
126
121
  def calculate_table_sharing(io)
127
- require_relative "models/table_sharing_info"
128
- require_relative "true_type_font"
129
-
130
122
  # Extract all fonts
131
123
  fonts = font_offsets.map do |offset|
132
124
  TrueTypeFont.from_collection(io, offset)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "sfnt_font"
4
-
5
3
  module Fontisan
6
4
  # TrueType Font domain object
7
5
  #
@@ -25,6 +23,14 @@ module Fontisan
25
23
  # @example Reading from TTC collection
26
24
  # ttf = TrueTypeFont.from_collection(io, offset)
27
25
  class TrueTypeFont < SfntFont
26
+ extend TrueTypeFontExtensions
27
+
28
+ # High-level pipeline format identifier. Owned by the font class so the
29
+ # conversion pipeline can dispatch without case statements (OCP).
30
+ #
31
+ # @return [Symbol] :ttf
32
+ def format = :ttf
33
+
28
34
  # Check if font is TrueType flavored
29
35
  #
30
36
  # @return [Boolean] true for TrueType fonts
@@ -1,24 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- # Extensions to TrueTypeFont for table-based construction
5
- class TrueTypeFont
4
+ # Extension module for {TrueTypeFont} providing table-based construction.
5
+ #
6
+ # Extended into TrueTypeFont from +true_type_font.rb+ so that
7
+ # +TrueTypeFont.from_tables(...)+ is available whenever the class
8
+ # itself is loaded.
9
+ module TrueTypeFontExtensions
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 [TrueTypeFont] 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
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "upm_scaler"
4
- require_relative "encodings"
5
- require_relative "agl"
6
-
7
3
  module Fontisan
8
4
  module Type1
9
5
  # AFM (Adobe Font Metrics) file generator
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "encodings"
4
-
5
3
  module Fontisan
6
4
  module Type1
7
5
  # Conversion options for Type 1 font generation
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "agl"
4
-
5
3
  module Fontisan
6
4
  module Type1
7
5
  # Font encoding schemes for Type 1 fonts
@@ -1,14 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
- require_relative "upm_scaler"
5
- require_relative "encodings"
6
- require_relative "conversion_options"
7
- require_relative "afm_generator"
8
- require_relative "pfm_generator"
9
- require_relative "pfa_generator"
10
- require_relative "pfb_generator"
11
- require_relative "inf_generator"
12
4
 
13
5
  module Fontisan
14
6
  module Type1
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "pfb_generator"
4
- require_relative "decryptor"
5
-
6
3
  module Fontisan
7
4
  module Type1
8
5
  # PFA (Printer Font ASCII) Generator
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "upm_scaler"
4
- require_relative "ttf_to_type1_converter"
5
- require_relative "decryptor"
6
- require_relative "../tables/name"
7
-
8
3
  module Fontisan
9
4
  module Type1
10
5
  # PFB (Printer Font Binary) Generator
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../constants"
4
- require_relative "upm_scaler"
5
- require_relative "afm_generator"
6
-
7
3
  module Fontisan
8
4
  module Type1
9
5
  # PFM (Printer Font Metrics) file generator
@@ -1,75 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Autoload hub for the Fontisan::Type1 namespace.
4
+ #
5
+ # Adobe Type 1 Font support — PFB/PFA parsing, eexec decryption,
6
+ # CharString decryption, font dictionary parsing, conversion from
7
+ # TTF/OTF, UPM scaling, and multiple encoding support.
8
+ #
9
+ # @example Generate Type 1 formats from TTF
10
+ # font = Fontisan::FontLoader.load("font.ttf")
11
+ # result = Fontisan::Type1::Generator.generate(font)
12
+ # result[:afm] # => AFM file content
13
+ # result[:pfm] # => PFM file content
14
+ # result[:pfb] # => PFB file content
15
+ # result[:inf] # => INF file content
16
+ #
17
+ # @example Generate with specific options
18
+ # options = Fontisan::Type1::ConversionOptions.windows_type1
19
+ # result = Fontisan::Type1::Generator.generate(font, options)
20
+ #
21
+ # @see https://www.adobe.com/devnet/font/pdfs/Type1.pdf
22
+
3
23
  module Fontisan
4
- # Adobe Type 1 Font support
5
- #
6
- # [`Type1`](lib/fontisan/type1.rb) provides parsing and conversion
7
- # capabilities for Adobe Type 1 fonts in PFB (Printer Font Binary)
8
- # and PFA (Printer Font ASCII) formats.
9
- #
10
- # Type 1 fonts were the standard for digital typography in the 1980s-1990s
11
- # and are still encountered in legacy systems and design workflows.
12
- #
13
- # Key features:
14
- # - PFB and PFA format parsing
15
- # - eexec decryption for encrypted font portions
16
- # - CharString decryption with lenIV handling
17
- # - Font dictionary parsing (FontInfo, Private dict)
18
- # - Conversion from TTF/OTF to Type 1 formats
19
- # - UPM scaling for Type 1 compatibility (1000 UPM)
20
- # - Multiple encoding support (AdobeStandard, ISOLatin1, Unicode)
21
- #
22
- # @example Generate Type 1 formats from TTF
23
- # font = Fontisan::FontLoader.load("font.ttf")
24
- # result = Fontisan::Type1::Generator.generate(font)
25
- # result[:afm] # => AFM file content
26
- # result[:pfm] # => PFM file content
27
- # result[:pfb] # => PFB file content
28
- # result[:inf] # => INF file content
29
- #
30
- # @example Generate with specific options
31
- # options = Fontisan::Type1::ConversionOptions.windows_type1
32
- # result = Fontisan::Type1::Generator.generate(font, options)
33
- #
34
- # @see https://www.adobe.com/devnet/font/pdfs/Type1.pdf
35
24
  module Type1
25
+ autoload :AGL, "fontisan/type1/agl"
26
+ autoload :AFMGenerator, "fontisan/type1/afm_generator"
27
+ autoload :AFMParser, "fontisan/type1/afm_parser"
28
+ autoload :CffToType1Converter, "fontisan/type1/cff_to_type1_converter"
29
+ autoload :CharStringConverter, "fontisan/type1/charstring_converter"
30
+ autoload :CharStrings, "fontisan/type1/charstrings"
31
+ autoload :ConversionOptions, "fontisan/type1/conversion_options"
32
+ autoload :Decryptor, "fontisan/type1/decryptor"
33
+ autoload :Encodings, "fontisan/type1/encodings"
34
+ autoload :FontDictionary, "fontisan/type1/font_dictionary"
35
+ autoload :Generator, "fontisan/type1/generator"
36
+ autoload :INFGenerator, "fontisan/type1/inf_generator"
37
+ autoload :PFAGenerator, "fontisan/type1/pfa_generator"
38
+ autoload :PFAParser, "fontisan/type1/pfa_parser"
39
+ autoload :PFBGenerator, "fontisan/type1/pfb_generator"
40
+ autoload :PFBParser, "fontisan/type1/pfb_parser"
41
+ autoload :PFMGenerator, "fontisan/type1/pfm_generator"
42
+ autoload :PFMParser, "fontisan/type1/pfm_parser"
43
+ autoload :PrivateDict, "fontisan/type1/private_dict"
44
+ autoload :SeacExpander, "fontisan/type1/seac_expander"
45
+ autoload :TTFToType1Converter, "fontisan/type1/ttf_to_type1_converter"
46
+ autoload :UPMScaler, "fontisan/type1/upm_scaler"
36
47
  end
37
48
  end
38
-
39
- # Parsers
40
- require_relative "type1/pfb_parser"
41
- require_relative "type1/pfa_parser"
42
-
43
- # Core components
44
- require_relative "type1/decryptor"
45
- require_relative "type1/font_dictionary"
46
- require_relative "type1/private_dict"
47
- require_relative "type1/charstrings"
48
- require_relative "type1/charstring_converter"
49
- require_relative "type1/cff_to_type1_converter"
50
- require_relative "type1/seac_expander"
51
-
52
- # Infrastructure
53
- require_relative "type1/upm_scaler"
54
- require_relative "type1/agl"
55
- require_relative "type1/encodings"
56
- require_relative "type1/conversion_options"
57
-
58
- # TTF to Type 1 conversion
59
- require_relative "type1/ttf_to_type1_converter"
60
-
61
- # Metrics parsers
62
- require_relative "type1/afm_parser"
63
- require_relative "type1/pfm_parser"
64
-
65
- # Metrics generators
66
- require_relative "type1/afm_generator"
67
- require_relative "type1/pfm_generator"
68
-
69
- # Type 1 font generators
70
- require_relative "type1/pfa_generator"
71
- require_relative "type1/pfb_generator"
72
- require_relative "type1/inf_generator"
73
-
74
- # Unified generator interface
75
- require_relative "type1/generator"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "type1"
4
-
5
3
  module Fontisan
6
4
  # Adobe Type 1 Font handler
7
5
  #
@@ -34,8 +32,38 @@ module Fontisan
34
32
  # @return [String, nil] File path if loaded from file
35
33
  attr_reader :file_path
36
34
 
37
- # @return [Symbol] Format type (:pfb or :pfa)
38
- attr_reader :format
35
+ # @return [Symbol] Container variant (:pfb or :pfa) — the on-disk
36
+ # encoding of a Type 1 font (binary vs ASCII). Distinct from
37
+ # {#format}, which is the high-level pipeline format.
38
+ attr_reader :container_format
39
+
40
+ # High-level pipeline format identifier. Owned by the font class so
41
+ # the conversion pipeline can dispatch without case statements (OCP).
42
+ #
43
+ # @return [Symbol] :type1
44
+ def format = :type1
45
+
46
+ # Whether this object represents a font collection rather than a single
47
+ # font. Each font class is the authority on this question.
48
+ #
49
+ # @return [Boolean]
50
+ def collection? = false
51
+
52
+ # Type 1 fonts are not OpenType variable fonts.
53
+ #
54
+ # @return [Symbol] :static
55
+ def variation_type = :static
56
+
57
+ # Outline representation. Type 1 fonts use cubic PostScript CharStrings.
58
+ #
59
+ # @return [Symbol] :postscript
60
+ def outline_type = :postscript
61
+
62
+ # Type 1 fonts have no SFNT table directory; the table-oriented pipeline
63
+ # introspection does not apply.
64
+ #
65
+ # @return [Array<String>] empty
66
+ def table_names = []
39
67
 
40
68
  # @return [Symbol] Loading mode (:metadata or :full)
41
69
  attr_reader :loading_mode
@@ -64,12 +92,13 @@ module Fontisan
64
92
  # Initialize a new Type1Font instance
65
93
  #
66
94
  # @param data [String] Font file data (binary or text)
67
- # @param format [Symbol] Format type (:pfb or :pfa, auto-detected if nil)
95
+ # @param container_format [Symbol] Container variant (:pfb or :pfa,
96
+ # auto-detected if nil)
68
97
  # @param file_path [String, nil] Optional file path for reference
69
98
  # @param mode [Symbol] Loading mode (:metadata or :full, default: :full)
70
- def initialize(data, format: nil, file_path: nil, mode: :full)
99
+ def initialize(data, container_format: nil, file_path: nil, mode: :full)
71
100
  @file_path = file_path
72
- @format = format || detect_format(data)
101
+ @container_format = container_format || detect_format(data)
73
102
  @data = data
74
103
  @loading_mode = mode
75
104
 
@@ -139,7 +168,7 @@ module Fontisan
139
168
  if @encrypted_portion.nil? || @encrypted_portion.empty?
140
169
  @decrypted_data = @clear_text
141
170
  else
142
- encrypted_binary = if @format == :pfa
171
+ encrypted_binary = if @container_format == :pfa
143
172
  # Convert hex string to binary
144
173
  [@encrypted_portion.gsub(/\s/, "")].pack("H*")
145
174
  else
@@ -226,15 +255,15 @@ module Fontisan
226
255
 
227
256
  private
228
257
 
229
- # Parse font data based on format
258
+ # Parse font data based on container format
230
259
  def parse_font_data
231
- case @format
260
+ case @container_format
232
261
  when :pfb
233
262
  parse_pfb
234
263
  when :pfa
235
264
  parse_pfa
236
265
  else
237
- raise Fontisan::Error, "Unknown format: #{@format}"
266
+ raise Fontisan::Error, "Unknown container format: #{@container_format}"
238
267
  end
239
268
  end
240
269