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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +14 -90
- data/Gemfile +6 -3
- data/README.adoc +257 -1
- data/docs/.vitepress/config.ts +68 -8
- data/docs/.vitepress/theme/style.css +570 -272
- data/docs/CONVERSION_GUIDE.adoc +31 -8
- data/docs/EXTRACT_TTC_MIGRATION.md +1 -1
- data/docs/WOFF_WOFF2_FORMATS.adoc +53 -0
- data/docs/api/conversion-options.md +37 -14
- data/docs/api/font-loader.md +21 -15
- data/docs/cli/audit.md +337 -0
- data/docs/cli/convert.md +20 -1
- data/docs/cli/index.md +31 -0
- data/docs/guide/color.md +1 -1
- data/docs/guide/conversion/options.md +32 -3
- data/docs/guide/conversion/ttf-otf.md +1 -1
- data/docs/guide/conversion/type1.md +1 -1
- data/docs/guide/conversion/web.md +91 -32
- data/docs/guide/conversion.md +6 -5
- data/docs/guide/formats/woff.md +35 -11
- data/docs/guide/index.md +2 -2
- data/docs/guide/migrations/extract-ttc.md +1 -1
- data/docs/guide/quick-start.md +4 -4
- data/docs/guide/type1.md +4 -4
- data/docs/guide/woff.md +19 -17
- data/docs/index.md +2 -0
- data/docs/lychee.toml +5 -1
- data/docs/package.json +1 -1
- data/docs/public/robots.txt +4 -0
- data/docs/scripts/post-build.mjs +81 -0
- data/lib/fontisan/audit/codepoint_range_coalescer.rb +41 -0
- data/lib/fontisan/audit/context.rb +122 -0
- data/lib/fontisan/audit/differ.rb +124 -0
- data/lib/fontisan/audit/extractors/aggregations.rb +54 -0
- data/lib/fontisan/audit/extractors/base.rb +26 -0
- data/lib/fontisan/audit/extractors/color_capabilities.rb +141 -0
- data/lib/fontisan/audit/extractors/coverage.rb +48 -0
- data/lib/fontisan/audit/extractors/hinting.rb +197 -0
- data/lib/fontisan/audit/extractors/identity.rb +52 -0
- data/lib/fontisan/audit/extractors/language_coverage.rb +37 -0
- data/lib/fontisan/audit/extractors/licensing.rb +79 -0
- data/lib/fontisan/audit/extractors/metrics.rb +103 -0
- data/lib/fontisan/audit/extractors/opentype_layout.rb +69 -0
- data/lib/fontisan/audit/extractors/provenance.rb +29 -0
- data/lib/fontisan/audit/extractors/style.rb +32 -0
- data/lib/fontisan/audit/extractors/variation_detail.rb +99 -0
- data/lib/fontisan/audit/extractors.rb +27 -0
- data/lib/fontisan/audit/library_aggregator.rb +83 -0
- data/lib/fontisan/audit/library_auditor.rb +90 -0
- data/lib/fontisan/audit/registry.rb +60 -0
- data/lib/fontisan/audit/style_extractor.rb +80 -0
- data/lib/fontisan/audit.rb +20 -0
- data/lib/fontisan/base_collection.rb +23 -9
- data/lib/fontisan/binary/structures.rb +0 -2
- data/lib/fontisan/binary.rb +11 -0
- data/lib/fontisan/cldr/aggregator.rb +33 -0
- data/lib/fontisan/cldr/cache_manager.rb +110 -0
- data/lib/fontisan/cldr/config.rb +59 -0
- data/lib/fontisan/cldr/download_error.rb +9 -0
- data/lib/fontisan/cldr/downloader.rb +79 -0
- data/lib/fontisan/cldr/error.rb +8 -0
- data/lib/fontisan/cldr/index.rb +64 -0
- data/lib/fontisan/cldr/index_builder.rb +72 -0
- data/lib/fontisan/cldr/unicode_set_parser.rb +172 -0
- data/lib/fontisan/cldr/unknown_version_error.rb +9 -0
- data/lib/fontisan/cldr/version_resolver.rb +91 -0
- data/lib/fontisan/cldr.rb +23 -0
- data/lib/fontisan/cli/cldr_cli.rb +85 -0
- data/lib/fontisan/cli/ucd_cli.rb +97 -0
- data/lib/fontisan/cli.rb +201 -2
- data/lib/fontisan/collection/builder.rb +0 -4
- data/lib/fontisan/collection/dfont_builder.rb +0 -4
- data/lib/fontisan/collection/shared_logic.rb +0 -2
- data/lib/fontisan/collection/writer.rb +0 -3
- data/lib/fontisan/collection.rb +15 -0
- data/lib/fontisan/commands/audit_command.rb +123 -0
- data/lib/fontisan/commands/audit_compare_command.rb +66 -0
- data/lib/fontisan/commands/audit_library_command.rb +46 -0
- data/lib/fontisan/commands/base_command.rb +0 -3
- data/lib/fontisan/commands/convert_command.rb +25 -20
- data/lib/fontisan/commands/dump_table_command.rb +0 -3
- data/lib/fontisan/commands/export_command.rb +0 -4
- data/lib/fontisan/commands/features_command.rb +0 -3
- data/lib/fontisan/commands/instance_command.rb +0 -5
- data/lib/fontisan/commands/ls_command.rb +0 -6
- data/lib/fontisan/commands/optical_size_command.rb +0 -3
- data/lib/fontisan/commands/pack_command.rb +0 -5
- data/lib/fontisan/commands/scripts_command.rb +0 -2
- data/lib/fontisan/commands/subset_command.rb +0 -3
- data/lib/fontisan/commands/unicode_command.rb +0 -3
- data/lib/fontisan/commands/unpack_command.rb +0 -7
- data/lib/fontisan/commands/validate_command.rb +0 -8
- data/lib/fontisan/commands/variable_command.rb +0 -3
- data/lib/fontisan/commands.rb +29 -0
- data/lib/fontisan/config/cldr.yml +22 -0
- data/lib/fontisan/config/conversion_matrix.yml +38 -0
- data/lib/fontisan/config/ucd.yml +23 -0
- data/lib/fontisan/constants.rb +48 -6
- data/lib/fontisan/conversion_options.rb +30 -19
- data/lib/fontisan/converters/cff_table_builder.rb +0 -3
- data/lib/fontisan/converters/collection_converter.rb +0 -8
- data/lib/fontisan/converters/conversion_strategy.rb +161 -46
- data/lib/fontisan/converters/format_converter.rb +143 -32
- data/lib/fontisan/converters/glyf_table_builder.rb +0 -2
- data/lib/fontisan/converters/outline_converter.rb +0 -19
- data/lib/fontisan/converters/outline_extraction.rb +0 -5
- data/lib/fontisan/converters/outline_optimizer.rb +0 -5
- data/lib/fontisan/converters/svg_generator.rb +0 -4
- data/lib/fontisan/converters/table_copier.rb +0 -2
- data/lib/fontisan/converters/type1_converter.rb +0 -11
- data/lib/fontisan/converters/woff2_encoder.rb +49 -20
- data/lib/fontisan/converters/woff_writer.rb +211 -282
- data/lib/fontisan/converters.rb +21 -0
- data/lib/fontisan/dfont_collection.rb +29 -10
- data/lib/fontisan/export/exporter.rb +0 -6
- data/lib/fontisan/export/transformers/font_to_ttx.rb +0 -9
- data/lib/fontisan/export/transformers/head_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/hhea_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/maxp_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/name_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/os2_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/post_transformer.rb +0 -2
- data/lib/fontisan/export/transformers.rb +17 -0
- data/lib/fontisan/export.rb +13 -0
- data/lib/fontisan/font_loader.rb +189 -328
- data/lib/fontisan/font_writer.rb +0 -1
- data/lib/fontisan/formatters/audit_diff_text_renderer.rb +122 -0
- data/lib/fontisan/formatters/audit_text_renderer.rb +324 -0
- data/lib/fontisan/formatters/library_summary_text_renderer.rb +99 -0
- data/lib/fontisan/formatters/text_formatter.rb +6 -0
- data/lib/fontisan/formatters.rb +12 -0
- data/lib/fontisan/hints/hint_converter.rb +0 -1
- data/lib/fontisan/hints/postscript_hint_applier.rb +0 -9
- data/lib/fontisan/hints/postscript_hint_extractor.rb +0 -2
- data/lib/fontisan/hints/truetype_hint_extractor.rb +0 -2
- data/lib/fontisan/hints.rb +16 -0
- data/lib/fontisan/metrics_calculator.rb +0 -2
- data/lib/fontisan/models/all_scripts_features_info.rb +0 -1
- data/lib/fontisan/models/audit/audit_axis.rb +30 -0
- data/lib/fontisan/models/audit/audit_block.rb +32 -0
- data/lib/fontisan/models/audit/audit_diff.rb +77 -0
- data/lib/fontisan/models/audit/audit_report.rb +153 -0
- data/lib/fontisan/models/audit/codepoint_range.rb +40 -0
- data/lib/fontisan/models/audit/codepoint_set_diff.rb +34 -0
- data/lib/fontisan/models/audit/color_capabilities.rb +93 -0
- data/lib/fontisan/models/audit/duplicate_group.rb +23 -0
- data/lib/fontisan/models/audit/embedding_type.rb +76 -0
- data/lib/fontisan/models/audit/field_change.rb +28 -0
- data/lib/fontisan/models/audit/fs_selection_flags.rb +61 -0
- data/lib/fontisan/models/audit/gasp_range.rb +63 -0
- data/lib/fontisan/models/audit/hinting.rb +93 -0
- data/lib/fontisan/models/audit/library_summary.rb +40 -0
- data/lib/fontisan/models/audit/licensing.rb +48 -0
- data/lib/fontisan/models/audit/metrics.rb +111 -0
- data/lib/fontisan/models/audit/named_instance.rb +41 -0
- data/lib/fontisan/models/audit/opentype_layout.rb +40 -0
- data/lib/fontisan/models/audit/script_coverage_row.rb +26 -0
- data/lib/fontisan/models/audit/script_features.rb +28 -0
- data/lib/fontisan/models/audit/variation_detail.rb +44 -0
- data/lib/fontisan/models/audit.rb +33 -0
- data/lib/fontisan/models/cldr/language_coverage.rb +31 -0
- data/lib/fontisan/models/cldr.rb +12 -0
- data/lib/fontisan/models/collection_brief_info.rb +0 -1
- data/lib/fontisan/models/collection_info.rb +0 -2
- data/lib/fontisan/models/collection_list_info.rb +0 -1
- data/lib/fontisan/models/collection_validation_report.rb +0 -2
- data/lib/fontisan/models/color_glyph.rb +0 -1
- data/lib/fontisan/models/font_report.rb +0 -1
- data/lib/fontisan/models/ttx/tables.rb +21 -0
- data/lib/fontisan/models/ttx/ttfont.rb +0 -8
- data/lib/fontisan/models/ttx.rb +14 -0
- data/lib/fontisan/models/ucd/ucd.rb +38 -0
- data/lib/fontisan/models/ucd/ucd_char.rb +67 -0
- data/lib/fontisan/models/ucd.rb +19 -0
- data/lib/fontisan/models.rb +47 -0
- data/lib/fontisan/open_type_collection.rb +6 -5
- data/lib/fontisan/open_type_font.rb +8 -2
- data/lib/fontisan/open_type_font_extensions.rb +9 -9
- data/lib/fontisan/optimizers/pattern_analyzer.rb +0 -1
- data/lib/fontisan/optimizers.rb +14 -0
- data/lib/fontisan/outline_extractor.rb +0 -2
- data/lib/fontisan/parsers/dfont_parser.rb +0 -1
- data/lib/fontisan/parsers.rb +10 -0
- data/lib/fontisan/pipeline/format_detector.rb +29 -102
- data/lib/fontisan/pipeline/output_writer.rb +11 -9
- data/lib/fontisan/pipeline/strategies/instance_strategy.rb +0 -4
- data/lib/fontisan/pipeline/strategies/named_strategy.rb +0 -4
- data/lib/fontisan/pipeline/strategies/preserve_strategy.rb +0 -2
- data/lib/fontisan/pipeline/strategies.rb +14 -0
- data/lib/fontisan/pipeline/transformation_pipeline.rb +0 -7
- data/lib/fontisan/pipeline/variation_resolver.rb +0 -7
- data/lib/fontisan/pipeline.rb +13 -0
- data/lib/fontisan/sfnt_font.rb +29 -14
- data/lib/fontisan/sfnt_table.rb +0 -4
- data/lib/fontisan/subset/builder.rb +0 -6
- data/lib/fontisan/subset.rb +13 -0
- data/lib/fontisan/svg/font_generator.rb +0 -4
- data/lib/fontisan/svg/glyph_generator.rb +0 -2
- data/lib/fontisan/svg.rb +12 -0
- data/lib/fontisan/tables/cbdt.rb +0 -1
- data/lib/fontisan/tables/cblc.rb +0 -1
- data/lib/fontisan/tables/cff/charset.rb +0 -1
- data/lib/fontisan/tables/cff/charstring.rb +0 -1
- data/lib/fontisan/tables/cff/charstring_rebuilder.rb +0 -4
- data/lib/fontisan/tables/cff/charstrings_index.rb +0 -3
- data/lib/fontisan/tables/cff/dict.rb +0 -1
- data/lib/fontisan/tables/cff/encoding.rb +0 -1
- data/lib/fontisan/tables/cff/header.rb +0 -2
- data/lib/fontisan/tables/cff/hint_operation_injector.rb +0 -2
- data/lib/fontisan/tables/cff/index.rb +0 -1
- data/lib/fontisan/tables/cff/private_dict.rb +0 -2
- data/lib/fontisan/tables/cff/private_dict_writer.rb +0 -2
- data/lib/fontisan/tables/cff/table_builder.rb +0 -6
- data/lib/fontisan/tables/cff/top_dict.rb +0 -2
- data/lib/fontisan/tables/cff.rb +22 -15
- data/lib/fontisan/tables/cff2/charstring_parser.rb +0 -2
- data/lib/fontisan/tables/cff2/table_builder.rb +0 -11
- data/lib/fontisan/tables/cff2/table_reader.rb +0 -2
- data/lib/fontisan/tables/cff2.rb +13 -14
- data/lib/fontisan/tables/cmap.rb +24 -2
- data/lib/fontisan/tables/cmap_table.rb +0 -3
- data/lib/fontisan/tables/colr.rb +0 -1
- data/lib/fontisan/tables/cpal.rb +0 -1
- data/lib/fontisan/tables/cvar.rb +0 -2
- data/lib/fontisan/tables/fvar.rb +0 -1
- data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +0 -2
- data/lib/fontisan/tables/glyf/glyph_builder.rb +0 -3
- data/lib/fontisan/tables/glyf.rb +0 -6
- data/lib/fontisan/tables/glyf_table.rb +0 -3
- data/lib/fontisan/tables/gpos.rb +0 -2
- data/lib/fontisan/tables/gsub.rb +0 -2
- data/lib/fontisan/tables/gvar.rb +0 -2
- data/lib/fontisan/tables/head.rb +0 -2
- data/lib/fontisan/tables/head_table.rb +0 -3
- data/lib/fontisan/tables/hhea.rb +0 -2
- data/lib/fontisan/tables/hhea_table.rb +0 -3
- data/lib/fontisan/tables/hmtx.rb +0 -2
- data/lib/fontisan/tables/hmtx_table.rb +0 -3
- data/lib/fontisan/tables/hvar.rb +0 -3
- data/lib/fontisan/tables/loca.rb +0 -2
- data/lib/fontisan/tables/loca_table.rb +0 -3
- data/lib/fontisan/tables/maxp.rb +0 -2
- data/lib/fontisan/tables/maxp_table.rb +0 -3
- data/lib/fontisan/tables/mvar.rb +0 -3
- data/lib/fontisan/tables/name.rb +0 -2
- data/lib/fontisan/tables/name_table.rb +0 -3
- data/lib/fontisan/tables/os2_table.rb +0 -3
- data/lib/fontisan/tables/post_table.rb +0 -3
- data/lib/fontisan/tables/sbix.rb +0 -1
- data/lib/fontisan/tables/svg.rb +0 -1
- data/lib/fontisan/tables/variation_common.rb +0 -1
- data/lib/fontisan/tables/vvar.rb +0 -3
- data/lib/fontisan/tables.rb +54 -0
- data/lib/fontisan/true_type_collection.rb +6 -14
- data/lib/fontisan/true_type_font.rb +8 -2
- data/lib/fontisan/true_type_font_extensions.rb +9 -9
- data/lib/fontisan/type1/afm_generator.rb +0 -4
- data/lib/fontisan/type1/conversion_options.rb +0 -2
- data/lib/fontisan/type1/encodings.rb +0 -2
- data/lib/fontisan/type1/generator.rb +0 -8
- data/lib/fontisan/type1/pfa_generator.rb +0 -3
- data/lib/fontisan/type1/pfb_generator.rb +0 -5
- data/lib/fontisan/type1/pfm_generator.rb +0 -4
- data/lib/fontisan/type1.rb +42 -69
- data/lib/fontisan/type1_font.rb +40 -11
- data/lib/fontisan/ucd/aggregator.rb +73 -0
- data/lib/fontisan/ucd/cache_manager.rb +111 -0
- data/lib/fontisan/ucd/config.rb +59 -0
- data/lib/fontisan/ucd/download_error.rb +9 -0
- data/lib/fontisan/ucd/downloader.rb +88 -0
- data/lib/fontisan/ucd/error.rb +8 -0
- data/lib/fontisan/ucd/index.rb +103 -0
- data/lib/fontisan/ucd/index_builder.rb +107 -0
- data/lib/fontisan/ucd/range_entry.rb +56 -0
- data/lib/fontisan/ucd/unknown_version_error.rb +9 -0
- data/lib/fontisan/ucd/version_resolver.rb +79 -0
- data/lib/fontisan/ucd.rb +23 -0
- data/lib/fontisan/utilities/checksum_calculator.rb +0 -1
- data/lib/fontisan/utilities.rb +10 -0
- data/lib/fontisan/utils.rb +10 -0
- data/lib/fontisan/validation/collection_validator.rb +0 -2
- data/lib/fontisan/validation.rb +9 -0
- data/lib/fontisan/validators/basic_validator.rb +0 -2
- data/lib/fontisan/validators/font_book_validator.rb +0 -2
- data/lib/fontisan/validators/opentype_validator.rb +0 -2
- data/lib/fontisan/validators/profile_loader.rb +0 -5
- data/lib/fontisan/validators/validator.rb +0 -2
- data/lib/fontisan/validators/web_font_validator.rb +0 -2
- data/lib/fontisan/validators.rb +14 -0
- data/lib/fontisan/variable/delta_applicator.rb +0 -4
- data/lib/fontisan/variable/instancer.rb +0 -3
- data/lib/fontisan/variable/static_font_builder.rb +0 -3
- data/lib/fontisan/variable.rb +16 -0
- data/lib/fontisan/variation/blend_applier.rb +0 -2
- data/lib/fontisan/variation/cache.rb +0 -2
- data/lib/fontisan/variation/converter.rb +0 -3
- data/lib/fontisan/variation/data_extractor.rb +0 -2
- data/lib/fontisan/variation/delta_applier.rb +0 -5
- data/lib/fontisan/variation/inspector.rb +0 -1
- data/lib/fontisan/variation/instance_generator.rb +0 -6
- data/lib/fontisan/variation/instance_writer.rb +0 -5
- data/lib/fontisan/variation/metrics_adjuster.rb +0 -4
- data/lib/fontisan/variation/optimizer.rb +0 -3
- data/lib/fontisan/variation/parallel_generator.rb +0 -3
- data/lib/fontisan/variation/subsetter.rb +0 -4
- data/lib/fontisan/variation/tuple_variation_header.rb +0 -2
- data/lib/fontisan/variation/variable_svg_generator.rb +0 -3
- data/lib/fontisan/variation/variation_context.rb +0 -3
- data/lib/fontisan/variation/variation_preserver.rb +0 -3
- data/lib/fontisan/variation.rb +31 -0
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan/woff2.rb +13 -0
- data/lib/fontisan/woff2_font.rb +31 -9
- data/lib/fontisan/woff_font.rb +31 -2
- data/lib/fontisan.rb +124 -196
- metadata +128 -7
- data/fontisan.gemspec +0 -47
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_command"
|
|
4
|
-
require_relative "../pipeline/transformation_pipeline"
|
|
5
|
-
require_relative "../converters/collection_converter"
|
|
6
|
-
require_relative "../conversion_options"
|
|
7
|
-
require_relative "../font_loader"
|
|
8
|
-
|
|
9
3
|
module Fontisan
|
|
10
4
|
module Commands
|
|
11
5
|
# Command for converting fonts between formats
|
|
@@ -67,29 +61,33 @@ module Fontisan
|
|
|
67
61
|
def initialize(font_path, options = {})
|
|
68
62
|
super(font_path, options)
|
|
69
63
|
|
|
70
|
-
# Convert string keys to symbols for Thor compatibility
|
|
71
|
-
|
|
64
|
+
# Convert string keys to symbols for Thor compatibility. All command
|
|
65
|
+
# code reads @options with symbol keys (e.g., @options[:quiet]);
|
|
66
|
+
# normalizing once at construction is cleaner than threading a
|
|
67
|
+
# second opts hash alongside @options.
|
|
68
|
+
@options = options.transform_keys(&:to_sym)
|
|
72
69
|
|
|
73
|
-
@output_path =
|
|
70
|
+
@output_path = @options[:output]
|
|
74
71
|
|
|
75
72
|
# Parse target format
|
|
76
|
-
@target_format = parse_target_format(
|
|
73
|
+
@target_format = parse_target_format(@options[:to])
|
|
77
74
|
|
|
78
75
|
# Extract ConversionOptions if provided
|
|
79
|
-
@conv_options = extract_conversion_options(
|
|
76
|
+
@conv_options = extract_conversion_options(@options)
|
|
80
77
|
|
|
81
78
|
# Parse coordinates if string provided
|
|
82
|
-
@coordinates = if
|
|
83
|
-
parse_coordinates(
|
|
84
|
-
elsif
|
|
85
|
-
|
|
79
|
+
@coordinates = if @options[:coordinates]
|
|
80
|
+
parse_coordinates(@options[:coordinates])
|
|
81
|
+
elsif @options[:instance_coordinates]
|
|
82
|
+
@options[:instance_coordinates]
|
|
86
83
|
end
|
|
87
84
|
|
|
88
|
-
@instance_index =
|
|
89
|
-
@preserve_variation =
|
|
90
|
-
@preserve_hints =
|
|
91
|
-
@collection_target_format =
|
|
92
|
-
|
|
85
|
+
@instance_index = @options[:instance_index]
|
|
86
|
+
@preserve_variation = @options[:preserve_variation]
|
|
87
|
+
@preserve_hints = @options.fetch(:preserve_hints, false)
|
|
88
|
+
@collection_target_format = @options.fetch(:target_format,
|
|
89
|
+
"preserve").to_s
|
|
90
|
+
@validate = !@options[:no_validate]
|
|
93
91
|
end
|
|
94
92
|
|
|
95
93
|
# Execute the conversion
|
|
@@ -152,6 +150,13 @@ module Fontisan
|
|
|
152
150
|
# Add hint preservation option
|
|
153
151
|
pipeline_options[:preserve_hints] = @preserve_hints if @preserve_hints
|
|
154
152
|
|
|
153
|
+
# Forward format-specific compression knobs declared by strategies
|
|
154
|
+
# (zlib_level, brotli_quality, etc.). Cross-format misuse is caught
|
|
155
|
+
# downstream by FormatConverter.validate_options_for_target!.
|
|
156
|
+
Converters::FormatConverter.all_strategy_option_names.each do |opt|
|
|
157
|
+
pipeline_options[opt] = @options[opt] if @options.key?(opt)
|
|
158
|
+
end
|
|
159
|
+
|
|
155
160
|
# Use TransformationPipeline for universal conversion
|
|
156
161
|
pipeline = Pipeline::TransformationPipeline.new(
|
|
157
162
|
font_path,
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
|
-
require_relative "base_command"
|
|
5
|
-
require_relative "../variation/instance_generator"
|
|
6
|
-
require_relative "../variation/instance_writer"
|
|
7
|
-
require_relative "../variation/validator"
|
|
8
|
-
require_relative "../error"
|
|
9
4
|
|
|
10
5
|
module Fontisan
|
|
11
6
|
module Commands
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../font_loader"
|
|
4
|
-
require_relative "../models/collection_list_info"
|
|
5
|
-
require_relative "../models/font_summary"
|
|
6
|
-
require_relative "../tables/name"
|
|
7
|
-
require_relative "../error"
|
|
8
|
-
|
|
9
3
|
module Fontisan
|
|
10
4
|
module Commands
|
|
11
5
|
# Command to list contents of font files (collections or individual fonts).
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_command"
|
|
4
|
-
require_relative "../collection/builder"
|
|
5
|
-
require_relative "../collection/dfont_builder"
|
|
6
|
-
require_relative "../font_loader"
|
|
7
|
-
|
|
8
3
|
module Fontisan
|
|
9
4
|
module Commands
|
|
10
5
|
# Command for packing multiple fonts into a TTC/OTC collection
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_command"
|
|
4
|
-
require_relative "../font_loader"
|
|
5
|
-
require_relative "../font_writer"
|
|
6
3
|
require "fileutils"
|
|
7
4
|
|
|
8
5
|
module Fontisan
|
|
@@ -144,10 +141,8 @@ module Fontisan
|
|
|
144
141
|
# Load as TTC or OTC based on extension hint
|
|
145
142
|
# Both use same structure, main difference is expected font types
|
|
146
143
|
if ext == ".otc"
|
|
147
|
-
require_relative "../open_type_collection"
|
|
148
144
|
OpenTypeCollection.read(io)
|
|
149
145
|
else
|
|
150
|
-
require_relative "../true_type_collection"
|
|
151
146
|
TrueTypeCollection.read(io)
|
|
152
147
|
end
|
|
153
148
|
end
|
|
@@ -252,8 +247,6 @@ module Fontisan
|
|
|
252
247
|
# @param output_path [String] Output file path
|
|
253
248
|
# @return [void]
|
|
254
249
|
def convert_and_write(font, output_path)
|
|
255
|
-
require_relative "../converters/format_converter"
|
|
256
|
-
|
|
257
250
|
converter = Converters::FormatConverter.new
|
|
258
251
|
converter.convert(font, @format, output_path: output_path)
|
|
259
252
|
rescue StandardError => e
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_command"
|
|
4
|
-
require_relative "../validators/profile_loader"
|
|
5
|
-
require_relative "../font_loader"
|
|
6
|
-
require_relative "../tables/name"
|
|
7
|
-
|
|
8
3
|
module Fontisan
|
|
9
4
|
module Commands
|
|
10
5
|
# ValidateCommand provides CLI interface for font validation
|
|
@@ -138,9 +133,6 @@ module Fontisan
|
|
|
138
133
|
# @param mode [Symbol] Loading mode
|
|
139
134
|
# @return [Integer] Exit code
|
|
140
135
|
def validate_collection(mode)
|
|
141
|
-
require_relative "../models/collection_validation_report"
|
|
142
|
-
require_relative "../models/font_report"
|
|
143
|
-
|
|
144
136
|
# Load collection metadata
|
|
145
137
|
collection = FontLoader.load_collection(@input)
|
|
146
138
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Commands namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Commands
|
|
7
|
+
autoload :AuditCompareCommand, "fontisan/commands/audit_compare_command"
|
|
8
|
+
autoload :AuditCommand, "fontisan/commands/audit_command"
|
|
9
|
+
autoload :AuditLibraryCommand, "fontisan/commands/audit_library_command"
|
|
10
|
+
autoload :BaseCommand, "fontisan/commands/base_command"
|
|
11
|
+
autoload :ConvertCommand, "fontisan/commands/convert_command"
|
|
12
|
+
autoload :DumpTableCommand, "fontisan/commands/dump_table_command"
|
|
13
|
+
autoload :ExportCommand, "fontisan/commands/export_command"
|
|
14
|
+
autoload :FeaturesCommand, "fontisan/commands/features_command"
|
|
15
|
+
autoload :GlyphsCommand, "fontisan/commands/glyphs_command"
|
|
16
|
+
autoload :InfoCommand, "fontisan/commands/info_command"
|
|
17
|
+
autoload :InstanceCommand, "fontisan/commands/instance_command"
|
|
18
|
+
autoload :LsCommand, "fontisan/commands/ls_command"
|
|
19
|
+
autoload :OpticalSizeCommand, "fontisan/commands/optical_size_command"
|
|
20
|
+
autoload :PackCommand, "fontisan/commands/pack_command"
|
|
21
|
+
autoload :ScriptsCommand, "fontisan/commands/scripts_command"
|
|
22
|
+
autoload :SubsetCommand, "fontisan/commands/subset_command"
|
|
23
|
+
autoload :TablesCommand, "fontisan/commands/tables_command"
|
|
24
|
+
autoload :UnicodeCommand, "fontisan/commands/unicode_command"
|
|
25
|
+
autoload :UnpackCommand, "fontisan/commands/unpack_command"
|
|
26
|
+
autoload :ValidateCommand, "fontisan/commands/validate_command"
|
|
27
|
+
autoload :VariableCommand, "fontisan/commands/variable_command"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# UCD alternative: CLDR (Common Locale Data Repository) configuration.
|
|
2
|
+
#
|
|
3
|
+
# This file is the single source of truth for which CLDR version Fontisan
|
|
4
|
+
# uses by default, what versions are recognized, and where to fetch them.
|
|
5
|
+
#
|
|
6
|
+
# Update `default_version` and `known_versions` when a new CLDR release
|
|
7
|
+
# ships (typically 2× per year, alongside Unicode releases).
|
|
8
|
+
# Users override at runtime via `fontisan cldr download --version X.Y.Z`
|
|
9
|
+
# or `fontisan audit --cldr-version X.Y.Z`.
|
|
10
|
+
|
|
11
|
+
default_version: "46.0.0"
|
|
12
|
+
|
|
13
|
+
known_versions:
|
|
14
|
+
- "45.0.0"
|
|
15
|
+
- "46.0.0"
|
|
16
|
+
|
|
17
|
+
# CLDR JSON releases are published on GitHub.
|
|
18
|
+
# Full URL: <base_url>/<version>/cldr-<version>-json-full.zip
|
|
19
|
+
base_url: "https://github.com/unicode-org/cldr-json/releases/download"
|
|
20
|
+
|
|
21
|
+
# Releases listing URL for `--latest` probing. JSON API.
|
|
22
|
+
listing_url: "https://api.github.com/repos/unicode-org/cldr-json/releases"
|
|
@@ -174,6 +174,25 @@ conversions:
|
|
|
174
174
|
WOFF decompression with zlib. Preserves all font data and metadata.
|
|
175
175
|
Automatically detects font flavor from WOFF header.
|
|
176
176
|
|
|
177
|
+
- from: woff
|
|
178
|
+
to: woff2
|
|
179
|
+
strategy: woff_reader
|
|
180
|
+
description: "Transcode WOFF to WOFF2 (re-wrap with Brotli)"
|
|
181
|
+
status: implemented
|
|
182
|
+
notes: >
|
|
183
|
+
Web-format transcoding. The pipeline decodes WOFF (zlib) into its
|
|
184
|
+
underlying SFNT tables, then re-wraps them as WOFF2 with Brotli.
|
|
185
|
+
Useful for migrating legacy web fonts to the smaller WOFF2 format.
|
|
186
|
+
|
|
187
|
+
- from: woff
|
|
188
|
+
to: svg
|
|
189
|
+
strategy: svg_generator
|
|
190
|
+
description: "Generate SVG font from WOFF"
|
|
191
|
+
status: implemented
|
|
192
|
+
notes: >
|
|
193
|
+
Decodes WOFF (zlib) to SFNT tables, then renders glyph outlines as
|
|
194
|
+
SVG paths. Note: SVG fonts are deprecated in favor of WOFF2.
|
|
195
|
+
|
|
177
196
|
# Phase 2 conversions (Milestone 2.2) - SVG
|
|
178
197
|
- from: ttf
|
|
179
198
|
to: svg
|
|
@@ -254,6 +273,25 @@ conversions:
|
|
|
254
273
|
Same-format copy operation. Decompresses and re-compresses WOFF2 data
|
|
255
274
|
with Brotli, useful for normalizing compression or updating metadata.
|
|
256
275
|
|
|
276
|
+
- from: woff2
|
|
277
|
+
to: woff
|
|
278
|
+
strategy: woff2_decoder
|
|
279
|
+
description: "Transcode WOFF2 to WOFF (re-wrap with zlib)"
|
|
280
|
+
status: implemented
|
|
281
|
+
notes: >
|
|
282
|
+
Web-format transcoding. The pipeline decodes WOFF2 (Brotli) into its
|
|
283
|
+
underlying SFNT tables, then re-wraps them as WOFF with zlib. Useful
|
|
284
|
+
for legacy browser compatibility where WOFF2 is unavailable.
|
|
285
|
+
|
|
286
|
+
- from: woff2
|
|
287
|
+
to: svg
|
|
288
|
+
strategy: svg_generator
|
|
289
|
+
description: "Generate SVG font from WOFF2"
|
|
290
|
+
status: implemented
|
|
291
|
+
notes: >
|
|
292
|
+
Decodes WOFF2 (Brotli) to SFNT tables, then renders glyph outlines as
|
|
293
|
+
SVG paths. Note: SVG fonts are deprecated in favor of WOFF2.
|
|
294
|
+
|
|
257
295
|
# Collection format conversions (TTC/OTC/dfont)
|
|
258
296
|
# Same-format collection operations
|
|
259
297
|
- from: ttc
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# UCD (Unicode Character Database) configuration.
|
|
2
|
+
#
|
|
3
|
+
# This file is the single source of truth for which UCD version Fontisan
|
|
4
|
+
# uses by default, what versions are recognized, and where to fetch them.
|
|
5
|
+
#
|
|
6
|
+
# Update `default_version` and `known_versions` when a new Unicode version
|
|
7
|
+
# is released (typically twice a year). Users may override at runtime via
|
|
8
|
+
# `fontisan ucd download --version X.Y.Z` or `fontisan audit --ucd-version X.Y.Z`.
|
|
9
|
+
|
|
10
|
+
default_version: "17.0.0"
|
|
11
|
+
|
|
12
|
+
known_versions:
|
|
13
|
+
- "15.0.0"
|
|
14
|
+
- "15.1.0"
|
|
15
|
+
- "16.0.0"
|
|
16
|
+
- "17.0.0"
|
|
17
|
+
|
|
18
|
+
# Base URL for fetching UCDXML artifacts.
|
|
19
|
+
# Full URL: <base_url>/<version>/ucdxml/ucd.all.flat.zip
|
|
20
|
+
base_url: "https://www.unicode.org/Public"
|
|
21
|
+
|
|
22
|
+
# Listing URL for `--latest` probing. HTML scraping, best-effort.
|
|
23
|
+
listing_url: "https://www.unicode.org/Public/ucdxml/"
|
data/lib/fontisan/constants.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Fontisan
|
|
|
9
9
|
module Constants
|
|
10
10
|
# TrueType Collection file signature tag.
|
|
11
11
|
# All valid TTC files must begin with this 4-byte tag.
|
|
12
|
-
TTC_TAG = "ttcf"
|
|
12
|
+
TTC_TAG = "ttcf".b.freeze
|
|
13
13
|
|
|
14
14
|
# TrueType Collection Version 1.0 identifier.
|
|
15
15
|
# Represents the original TTC format version.
|
|
@@ -25,11 +25,23 @@ module Fontisan
|
|
|
25
25
|
# SFNT version for OpenType fonts with CFF outlines ('OTTO')
|
|
26
26
|
SFNT_VERSION_OTTO = 0x4F54544F
|
|
27
27
|
|
|
28
|
-
# Apple 'true' TrueType signature (alternate to 0x00010000)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
# Apple 'true' TrueType signature (alternate to 0x00010000).
|
|
29
|
+
# Bytes: 0x74 ('t') 0x72 ('r') 0x75 ('u') 0x65 ('e').
|
|
30
|
+
SFNT_VERSION_TRUE = 0x74727565
|
|
31
|
+
|
|
32
|
+
# Four-byte file signatures used for content-based format detection.
|
|
33
|
+
# Pre-packed once here so format detection doesn't repack on every call.
|
|
34
|
+
SFNT_TRUETYPE_MAGIC = "\x00\x01\x00\x00".b.freeze # packed SFNT_VERSION_TRUETYPE
|
|
35
|
+
SFNT_TRUE_MAGIC = "true".b.freeze # Apple legacy TrueType
|
|
36
|
+
SFNT_OTTO_MAGIC = "OTTO".b.freeze # OpenType / CFF
|
|
37
|
+
WOFF_MAGIC = "wOFF".b.freeze
|
|
38
|
+
WOFF2_MAGIC = "wOF2".b.freeze
|
|
39
|
+
|
|
40
|
+
# dfont resource fork signatures.
|
|
41
|
+
# Note: bytes differ from SFNT_TRUETYPE_MAGIC despite the visual similarity —
|
|
42
|
+
# dfont is "\x00\x00\x01\x00" (resource-data offset 256, big-endian),
|
|
43
|
+
# SFNT_TRUETYPE_MAGIC is "\x00\x01\x00\x00" (sfnt version 0x00010000).
|
|
44
|
+
DFONT_RESOURCE_HEADER = "\x00\x00\x01\x00".b.freeze
|
|
33
45
|
SFNT_RESOURCE_TYPE = "sfnt"
|
|
34
46
|
FOND_RESOURCE_TYPE = "FOND"
|
|
35
47
|
|
|
@@ -77,6 +89,9 @@ module Fontisan
|
|
|
77
89
|
# Fvar table tag identifier (Font Variations)
|
|
78
90
|
FVAR_TAG = "fvar"
|
|
79
91
|
|
|
92
|
+
# Avar table tag identifier (Axis Variation)
|
|
93
|
+
AVAR_TAG = "avar"
|
|
94
|
+
|
|
80
95
|
# Gvar table tag identifier (Glyph Variations for TrueType)
|
|
81
96
|
GVAR_TAG = "gvar"
|
|
82
97
|
|
|
@@ -117,6 +132,22 @@ module Fontisan
|
|
|
117
132
|
# Control Value Table (metrics used by TrueType hinting)
|
|
118
133
|
CVT_TAG = "cvt "
|
|
119
134
|
|
|
135
|
+
# Grid-fitting And Scan-conversion Procedure table (per-ppem hinting policy)
|
|
136
|
+
GASP_TAG = "gasp"
|
|
137
|
+
|
|
138
|
+
# Color font tables.
|
|
139
|
+
# COLR: COLR vector color glyph table (v0 or v1).
|
|
140
|
+
# CPAL: Color Palette table.
|
|
141
|
+
# SVG: SVG-in-OpenType color glyph table (tag is "SVG " — 4 bytes incl. trailing space).
|
|
142
|
+
# CBDT/CBLC: Color Bitmap Data / Location (paired — EBLC/EBDT equivalents for color).
|
|
143
|
+
# sbix: Apple bitmap glyph table.
|
|
144
|
+
COLR_TAG = "COLR"
|
|
145
|
+
CPAL_TAG = "CPAL"
|
|
146
|
+
SVG_TAG = "SVG "
|
|
147
|
+
CBDT_TAG = "CBDT"
|
|
148
|
+
CBLC_TAG = "CBLC"
|
|
149
|
+
SBIX_TAG = "sbix"
|
|
150
|
+
|
|
120
151
|
# Magic number used for font file checksum adjustment calculation.
|
|
121
152
|
# This constant is used in conjunction with the file checksum to compute
|
|
122
153
|
# the checksumAdjustment value stored in the 'head' table.
|
|
@@ -173,5 +204,16 @@ module Fontisan
|
|
|
173
204
|
def self.intern_string(str)
|
|
174
205
|
STRING_POOL[str] || str.freeze
|
|
175
206
|
end
|
|
207
|
+
|
|
208
|
+
# Classify a 4-byte SFNT-style signature read from a font file's magic.
|
|
209
|
+
#
|
|
210
|
+
# @param signature [String, nil]
|
|
211
|
+
# @return [Symbol, nil] :ttf, :otf, or nil for unrecognised signatures
|
|
212
|
+
def self.sfnt_format_for(signature)
|
|
213
|
+
case signature
|
|
214
|
+
when SFNT_TRUETYPE_MAGIC, SFNT_TRUE_MAGIC then :ttf
|
|
215
|
+
when SFNT_OTTO_MAGIC then :otf
|
|
216
|
+
end
|
|
217
|
+
end
|
|
176
218
|
end
|
|
177
219
|
end
|
|
@@ -35,8 +35,12 @@ module Fontisan
|
|
|
35
35
|
preserve_encoding
|
|
36
36
|
].freeze
|
|
37
37
|
|
|
38
|
-
# Generating options (output processing)
|
|
39
|
-
|
|
38
|
+
# Generating options (output processing) declared statically by
|
|
39
|
+
# ConversionOptions itself. Format-specific compression knobs (zlib_level,
|
|
40
|
+
# brotli_quality, transform_tables, etc.) are declared by each strategy
|
|
41
|
+
# via the ConversionStrategy DSL and discovered via
|
|
42
|
+
# FormatConverter.all_strategy_option_names — see `.generating_options`.
|
|
43
|
+
STATIC_GENERATING_OPTIONS = %i[
|
|
40
44
|
write_pfm
|
|
41
45
|
write_afm
|
|
42
46
|
write_inf
|
|
@@ -47,19 +51,28 @@ module Fontisan
|
|
|
47
51
|
optimize_tables
|
|
48
52
|
reencode_first_256
|
|
49
53
|
encoding_vector
|
|
50
|
-
compression
|
|
51
|
-
transform_tables
|
|
52
54
|
preserve_metadata
|
|
53
55
|
strip_metadata
|
|
54
56
|
target_format
|
|
55
57
|
].freeze
|
|
56
58
|
|
|
59
|
+
# Full list of recognized generating options, computed lazily because
|
|
60
|
+
# converters `require_relative` this file, creating a load cycle that
|
|
61
|
+
# prevents resolving `FormatConverter` at class-definition time. The first
|
|
62
|
+
# call resolves all strategies (which are loaded before any conversion
|
|
63
|
+
# actually runs) and caches the result.
|
|
64
|
+
#
|
|
65
|
+
# @return [Array<Symbol>]
|
|
66
|
+
def self.generating_options
|
|
67
|
+
@generating_options ||= (
|
|
68
|
+
STATIC_GENERATING_OPTIONS +
|
|
69
|
+
Converters::FormatConverter.all_strategy_option_names
|
|
70
|
+
).uniq.freeze
|
|
71
|
+
end
|
|
72
|
+
|
|
57
73
|
# Valid hinting modes
|
|
58
74
|
HINTING_MODES = %w[preserve auto none full].freeze
|
|
59
75
|
|
|
60
|
-
# Valid compression modes
|
|
61
|
-
COMPRESSION_MODES = %w[zlib brotli none].freeze
|
|
62
|
-
|
|
63
76
|
attr_reader :from, :to, :opening, :generating
|
|
64
77
|
|
|
65
78
|
# Initialize conversion options
|
|
@@ -199,9 +212,9 @@ module Fontisan
|
|
|
199
212
|
# Validate generating options
|
|
200
213
|
def validate_generating_options!
|
|
201
214
|
@generating.each_key do |key|
|
|
202
|
-
unless
|
|
215
|
+
unless self.class.generating_options.include?(key)
|
|
203
216
|
raise ArgumentError, "Unknown generating option: #{key}. " \
|
|
204
|
-
"Available: #{
|
|
217
|
+
"Available: #{self.class.generating_options.join(', ')}"
|
|
205
218
|
end
|
|
206
219
|
end
|
|
207
220
|
|
|
@@ -214,15 +227,6 @@ module Fontisan
|
|
|
214
227
|
end
|
|
215
228
|
end
|
|
216
229
|
|
|
217
|
-
# Validate compression mode
|
|
218
|
-
if @generating[:compression]
|
|
219
|
-
comp = @generating[:compression].to_s
|
|
220
|
-
unless COMPRESSION_MODES.include?(comp)
|
|
221
|
-
raise ArgumentError, "Invalid compression: #{comp}. " \
|
|
222
|
-
"Available: #{COMPRESSION_MODES.join(', ')}"
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
226
230
|
# Validate target_format for collection conversions
|
|
227
231
|
if @generating[:target_format]
|
|
228
232
|
target = @generating[:target_format].to_s
|
|
@@ -364,9 +368,16 @@ module Fontisan
|
|
|
364
368
|
from: :otf,
|
|
365
369
|
to: :woff2,
|
|
366
370
|
opening: {},
|
|
367
|
-
generating: {
|
|
371
|
+
generating: { brotli_quality: 11, transform_tables: true,
|
|
368
372
|
optimize_tables: true, preserve_metadata: true },
|
|
369
373
|
},
|
|
374
|
+
legacy_web: {
|
|
375
|
+
from: :otf,
|
|
376
|
+
to: :woff,
|
|
377
|
+
opening: {},
|
|
378
|
+
generating: { zlib_level: 9, optimize_tables: true,
|
|
379
|
+
preserve_metadata: true },
|
|
380
|
+
},
|
|
370
381
|
archive_to_modern: {
|
|
371
382
|
from: :ttc,
|
|
372
383
|
to: :otf,
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../conversion_options"
|
|
4
|
-
require_relative "format_converter"
|
|
5
|
-
require_relative "../collection/builder"
|
|
6
|
-
require_relative "../collection/dfont_builder"
|
|
7
|
-
require_relative "../parsers/dfont_parser"
|
|
8
|
-
require_relative "../font_loader"
|
|
9
|
-
|
|
10
3
|
module Fontisan
|
|
11
4
|
module Converters
|
|
12
5
|
# CollectionConverter handles conversion between collection formats
|
|
@@ -343,7 +336,6 @@ conv_options = nil)
|
|
|
343
336
|
# @return [Font] Font object
|
|
344
337
|
def build_font_from_tables(tables, format)
|
|
345
338
|
# Create temporary font from tables
|
|
346
|
-
require_relative "../font_writer"
|
|
347
339
|
require "stringio"
|
|
348
340
|
|
|
349
341
|
sfnt_version = format == :otf ? 0x4F54544F : 0x00010000
|