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
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "rubygems"
6
+
7
+ module Fontisan
8
+ module Ucd
9
+ # Resolves a user-supplied version intent to a concrete version string.
10
+ #
11
+ # Three input modes:
12
+ #
13
+ # resolve(nil) # default_version from config
14
+ # resolve(:default) # default_version from config
15
+ # resolve("17.0.0") # explicit; validated against known_versions
16
+ # resolve(:latest) # probes listing_url, picks highest; falls
17
+ # # back to default on failure
18
+ #
19
+ module VersionResolver
20
+ class << self
21
+ # @param intent [nil, :default, :latest, String]
22
+ # @return [String] a concrete version string
23
+ def resolve(intent)
24
+ case intent
25
+ when nil, :default
26
+ Config.default_version
27
+ when :latest
28
+ probe_latest
29
+ else
30
+ validate!(intent)
31
+ intent
32
+ end
33
+ end
34
+
35
+ # Raise UnknownVersionError unless `version` is in known_versions.
36
+ # @param version [String]
37
+ # @return [void]
38
+ def validate!(version)
39
+ return if Config.known?(version)
40
+
41
+ raise UnknownVersionError,
42
+ "UCD version #{version.inspect} is not recognized. " \
43
+ "Known versions: #{Config.known_versions.join(', ')}"
44
+ end
45
+
46
+ private
47
+
48
+ # Best-effort scrape of the unicode.org ucdxml directory listing.
49
+ # Returns the highest semver found, or Config.default_version on
50
+ # any failure.
51
+ def probe_latest
52
+ versions = fetch_directory_versions
53
+ return fallback_latest("directory listing was empty") if versions.empty?
54
+
55
+ highest = versions.max_by { |v| Gem::Version.new(v) }
56
+ if Config.known?(highest)
57
+ highest
58
+ else
59
+ fallback_latest("#{highest.inspect} is not in known_versions; using default")
60
+ end
61
+ rescue StandardError => e
62
+ fallback_latest(e.message)
63
+ end
64
+
65
+ def fallback_latest(reason)
66
+ warn "Ucd::VersionResolver: --latest probe failed (#{reason}); " \
67
+ "falling back to default #{Config.default_version.inspect}"
68
+ Config.default_version
69
+ end
70
+
71
+ def fetch_directory_versions
72
+ uri = URI(Config.listing_url)
73
+ html = Net::HTTP.get(uri)
74
+ html.scan(%r{href="(\d+\.\d+\.\d+)/?"}i).flatten.uniq
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Namespace file for UCD (Unicode Character Database) support.
4
+ #
5
+ # All Ucd::* constants are autoloaded from here. Top-level callers
6
+ # (`lib/fontisan.rb`) require this file; downstream files reference
7
+ # constants like Ucd::CacheManager and let autoload do the work.
8
+
9
+ module Fontisan
10
+ module Ucd
11
+ autoload :Config, "fontisan/ucd/config"
12
+ autoload :CacheManager, "fontisan/ucd/cache_manager"
13
+ autoload :Downloader, "fontisan/ucd/downloader"
14
+ autoload :VersionResolver, "fontisan/ucd/version_resolver"
15
+ autoload :IndexBuilder, "fontisan/ucd/index_builder"
16
+ autoload :Index, "fontisan/ucd/index"
17
+ autoload :Aggregator, "fontisan/ucd/aggregator"
18
+ autoload :RangeEntry, "fontisan/ucd/range_entry"
19
+ autoload :Error, "fontisan/ucd/error"
20
+ autoload :DownloadError, "fontisan/ucd/download_error"
21
+ autoload :UnknownVersionError, "fontisan/ucd/unknown_version_error"
22
+ end
23
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require_relative "../constants"
5
4
 
6
5
  module Fontisan
7
6
  module Utilities
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Utilities namespace.
4
+
5
+ module Fontisan
6
+ module Utilities
7
+ autoload :BrotliWrapper, "fontisan/utilities/brotli_wrapper"
8
+ autoload :ChecksumCalculator, "fontisan/utilities/checksum_calculator"
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Utils namespace.
4
+
5
+ module Fontisan
6
+ module Utils
7
+ autoload :Future, "fontisan/utils/thread_pool"
8
+ autoload :ThreadPool, "fontisan/utils/thread_pool"
9
+ end
10
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../error"
4
-
5
3
  module Fontisan
6
4
  module Validation
7
5
  # CollectionValidator validates font compatibility for collection formats
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Validation namespace.
4
+
5
+ module Fontisan
6
+ module Validation
7
+ autoload :CollectionValidator, "fontisan/validation/collection_validator"
8
+ end
9
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "validator"
4
-
5
3
  module Fontisan
6
4
  module Validators
7
5
  # BasicValidator provides minimal validation for fast font indexing
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "basic_validator"
4
-
5
3
  module Fontisan
6
4
  module Validators
7
5
  # FontBookValidator provides macOS Font Book installation compatibility checks
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "font_book_validator"
4
-
5
3
  module Fontisan
6
4
  module Validators
7
5
  # OpenTypeValidator provides comprehensive OpenType specification compliance checks
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "basic_validator"
4
- require_relative "font_book_validator"
5
- require_relative "opentype_validator"
6
- require_relative "web_font_validator"
7
-
8
3
  module Fontisan
9
4
  module Validators
10
5
  # ProfileLoader manages validation profiles and loads appropriate validators
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../models/validation_report"
4
-
5
3
  module Fontisan
6
4
  module Validators
7
5
  # Base class for all validators using block-based DSL
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "basic_validator"
4
-
5
3
  module Fontisan
6
4
  module Validators
7
5
  # WebFontValidator provides web font optimization and embedding compatibility checks
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Validators namespace.
4
+
5
+ module Fontisan
6
+ module Validators
7
+ autoload :BasicValidator, "fontisan/validators/basic_validator"
8
+ autoload :FontBookValidator, "fontisan/validators/font_book_validator"
9
+ autoload :OpenTypeValidator, "fontisan/validators/opentype_validator"
10
+ autoload :ProfileLoader, "fontisan/validators/profile_loader"
11
+ autoload :Validator, "fontisan/validators/validator"
12
+ autoload :WebFontValidator, "fontisan/validators/web_font_validator"
13
+ end
14
+ end
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "yaml"
4
- require_relative "axis_normalizer"
5
- require_relative "region_matcher"
6
- require_relative "glyph_delta_processor"
7
- require_relative "metric_delta_processor"
8
4
 
9
5
  module Fontisan
10
6
  module Variable
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "delta_applicator"
4
- require_relative "static_font_builder"
5
-
6
3
  module Fontisan
7
4
  module Variable
8
5
  # Main entry point for variable font instancing
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "table_updater"
4
- require_relative "../font_writer"
5
-
6
3
  module Fontisan
7
4
  module Variable
8
5
  # Builds static font instances from variable font data
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Variable namespace.
4
+
5
+ module Fontisan
6
+ module Variable
7
+ autoload :AxisNormalizer, "fontisan/variable/axis_normalizer"
8
+ autoload :DeltaApplicator, "fontisan/variable/delta_applicator"
9
+ autoload :GlyphDeltaProcessor, "fontisan/variable/glyph_delta_processor"
10
+ autoload :Instancer, "fontisan/variable/instancer"
11
+ autoload :MetricDeltaProcessor, "fontisan/variable/metric_delta_processor"
12
+ autoload :RegionMatcher, "fontisan/variable/region_matcher"
13
+ autoload :StaticFontBuilder, "fontisan/variable/static_font_builder"
14
+ autoload :TableUpdater, "fontisan/variable/table_updater"
15
+ end
16
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "interpolator"
4
-
5
3
  module Fontisan
6
4
  module Variation
7
5
  # Applies CFF2 blend operators during CharString execution
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "cache_key_builder"
4
-
5
3
  module Fontisan
6
4
  module Variation
7
5
  # Caches variation calculations for performance
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "interpolator"
4
- require_relative "table_accessor"
5
-
6
3
  module Fontisan
7
4
  module Variation
8
5
  # Converts variation data between TrueType (gvar) and CFF2 (blend) formats
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "variation_context"
4
-
5
3
  module Fontisan
6
4
  module Variation
7
5
  # Extracts variation data from OpenType variable fonts
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "delta_parser"
4
- require_relative "interpolator"
5
- require_relative "region_matcher"
6
- require_relative "table_accessor"
7
-
8
3
  module Fontisan
9
4
  module Variation
10
5
  # Applies variation deltas to glyph outlines
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "json"
4
4
  require "yaml"
5
- require_relative "variation_context"
6
5
 
7
6
  module Fontisan
8
7
  module Variation
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "interpolator"
4
- require_relative "region_matcher"
5
- require_relative "metrics_adjuster"
6
- require_relative "variation_context"
7
- require_relative "table_accessor"
8
-
9
3
  module Fontisan
10
4
  module Variation
11
5
  # Generates static font instances from variable fonts
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../font_writer"
4
- require_relative "../converters/outline_converter"
5
- require_relative "../converters/woff_writer"
6
- require_relative "../error"
7
-
8
3
  module Fontisan
9
4
  module Variation
10
5
  # Writes generated static font instances to files in various formats
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "interpolator"
4
- require_relative "region_matcher"
5
- require_relative "table_accessor"
6
-
7
3
  module Fontisan
8
4
  module Variation
9
5
  # Applies metrics variation deltas to font metrics tables
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../optimizers/pattern_analyzer"
4
- require_relative "../optimizers/subroutine_optimizer"
5
-
6
3
  module Fontisan
7
4
  module Variation
8
5
  # Optimizes CFF subroutines for variable fonts
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "instance_generator"
4
- require_relative "cache"
5
- require_relative "../utils/thread_pool"
6
3
  require "etc"
7
4
 
8
5
  module Fontisan
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "validator"
4
- require_relative "optimizer"
5
- require_relative "table_accessor"
6
-
7
3
  module Fontisan
8
4
  module Variation
9
5
  # Subset variable fonts while preserving variation
@@ -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 Variation
7
5
  # Tuple variation header structure
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "instance_generator"
4
- require_relative "../converters/svg_generator"
5
-
6
3
  module Fontisan
7
4
  module Variation
8
5
  # Generates SVG fonts from variable fonts at specific coordinates
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "interpolator"
4
- require_relative "region_matcher"
5
-
6
3
  module Fontisan
7
4
  module Variation
8
5
  # Provides shared context for variation operations
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "variation_context"
4
- require_relative "../error"
5
-
6
3
  module Fontisan
7
4
  module Variation
8
5
  # Preserves variation data when converting between compatible font formats
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Variation namespace.
4
+
5
+ module Fontisan
6
+ module Variation
7
+ autoload :BlendApplier, "fontisan/variation/blend_applier"
8
+ autoload :Cache, "fontisan/variation/cache"
9
+ autoload :CacheKeyBuilder, "fontisan/variation/cache_key_builder"
10
+ autoload :Converter, "fontisan/variation/converter"
11
+ autoload :DataExtractor, "fontisan/variation/data_extractor"
12
+ autoload :DeltaApplier, "fontisan/variation/delta_applier"
13
+ autoload :DeltaParser, "fontisan/variation/delta_parser"
14
+ autoload :Inspector, "fontisan/variation/inspector"
15
+ autoload :InstanceGenerator, "fontisan/variation/instance_generator"
16
+ autoload :InstanceWriter, "fontisan/variation/instance_writer"
17
+ autoload :Interpolator, "fontisan/variation/interpolator"
18
+ autoload :MetricsAdjuster, "fontisan/variation/metrics_adjuster"
19
+ autoload :Optimizer, "fontisan/variation/optimizer"
20
+ autoload :ParallelGenerator, "fontisan/variation/parallel_generator"
21
+ autoload :RegionMatcher, "fontisan/variation/region_matcher"
22
+ autoload :Subsetter, "fontisan/variation/subsetter"
23
+ autoload :TableAccessor, "fontisan/variation/table_accessor"
24
+ autoload :ThreadSafeCache, "fontisan/variation/cache"
25
+ autoload :TupleVariationHeader, "fontisan/variation/tuple_variation_header"
26
+ autoload :Validator, "fontisan/variation/validator"
27
+ autoload :VariableSvgGenerator, "fontisan/variation/variable_svg_generator"
28
+ autoload :VariationContext, "fontisan/variation/variation_context"
29
+ autoload :VariationPreserver, "fontisan/variation/variation_preserver"
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- VERSION = "0.2.16"
4
+ VERSION = "0.2.22"
5
5
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Autoload hub for the Fontisan::Woff2 namespace.
4
+
5
+ module Fontisan
6
+ module Woff2
7
+ autoload :Directory, "fontisan/woff2/directory"
8
+ autoload :GlyfTransformer, "fontisan/woff2/glyf_transformer"
9
+ autoload :HmtxTransformer, "fontisan/woff2/hmtx_transformer"
10
+ autoload :TableTransformer, "fontisan/woff2/table_transformer"
11
+ autoload :Woff2Header, "fontisan/woff2/header"
12
+ end
13
+ end
@@ -3,15 +3,6 @@
3
3
  require "bindata"
4
4
  require "brotli"
5
5
  require "stringio"
6
- require_relative "constants"
7
- require_relative "loading_modes"
8
- require_relative "utilities/checksum_calculator"
9
- require_relative "woff2/header"
10
- require_relative "woff2/glyf_transformer"
11
- require_relative "woff2/hmtx_transformer"
12
- require_relative "true_type_font"
13
- require_relative "open_type_font"
14
- require_relative "error"
15
6
 
16
7
  module Fontisan
17
8
  # WOFF2 Table Directory Entry structure
@@ -82,6 +73,12 @@ module Fontisan
82
73
  # puts font.header.flavor
83
74
  # puts font.table_names
84
75
  class Woff2Font
76
+ # High-level pipeline format identifier. Owned by the font class so the
77
+ # conversion pipeline can dispatch without case statements (OCP).
78
+ #
79
+ # @return [Symbol] :woff2
80
+ def format = :woff2
81
+
85
82
  # Simple struct for storing file path
86
83
  IOSource = Struct.new(:path)
87
84
 
@@ -145,6 +142,31 @@ module Fontisan
145
142
  @table_entries.any? { |entry| entry.tag == tag }
146
143
  end
147
144
 
145
+ # Whether this object represents a font collection rather than a single
146
+ # font. Each font class is the authority on this question.
147
+ #
148
+ # @return [Boolean]
149
+ def collection? = false
150
+
151
+ # Variation profile. WOFF2 wraps a single SFNT font; variation tables, if
152
+ # present on the wrapped font, are reported here.
153
+ #
154
+ # @return [Symbol] :static, :gvar, or :cff2
155
+ def variation_type
156
+ return :static unless has_table?("fvar")
157
+ return :gvar if has_table?("gvar")
158
+ return :cff2 if has_table?("CFF2")
159
+
160
+ :static
161
+ end
162
+
163
+ # Outline representation, derived from the wrapped SFNT flavor.
164
+ #
165
+ # @return [Symbol] :truetype or :cff
166
+ def outline_type
167
+ truetype? ? :truetype : :cff
168
+ end
169
+
148
170
  # Find table entry by tag
149
171
  def find_table_entry(tag)
150
172
  @table_entries.find { |entry| entry.tag == tag }
@@ -2,8 +2,6 @@
2
2
 
3
3
  require "bindata"
4
4
  require "zlib"
5
- require_relative "constants"
6
- require_relative "utilities/checksum_calculator"
7
5
 
8
6
  module Fontisan
9
7
  # WOFF Header structure
@@ -55,6 +53,12 @@ module Fontisan
55
53
  # woff.to_ttf("output.ttf") # if TrueType flavored
56
54
  # woff.to_otf("output.otf") # if CFF flavored
57
55
  class WoffFont < BinData::Record
56
+ # High-level pipeline format identifier. Owned by the font class so the
57
+ # conversion pipeline can dispatch without case statements (OCP).
58
+ #
59
+ # @return [Symbol] :woff
60
+ def format = :woff
61
+
58
62
  endian :big
59
63
 
60
64
  woff_header :header
@@ -142,6 +146,31 @@ module Fontisan
142
146
  end
143
147
  end
144
148
 
149
+ # Whether this object represents a font collection rather than a single
150
+ # font. Each font class is the authority on this question.
151
+ #
152
+ # @return [Boolean]
153
+ def collection? = false
154
+
155
+ # Variation profile. WOFF wraps a single SFNT font; variation tables, if
156
+ # present on the wrapped font, are reported here.
157
+ #
158
+ # @return [Symbol] :static, :gvar, or :cff2
159
+ def variation_type
160
+ return :static unless has_table?("fvar")
161
+ return :gvar if has_table?("gvar")
162
+ return :cff2 if has_table?("CFF2")
163
+
164
+ :static
165
+ end
166
+
167
+ # Outline representation, derived from the wrapped SFNT flavor.
168
+ #
169
+ # @return [Symbol] :truetype or :cff
170
+ def outline_type
171
+ truetype? ? :truetype : :cff
172
+ end
173
+
145
174
  # Check if font is TrueType flavored
146
175
  #
147
176
  # @return [Boolean] true if TrueType, false if CFF