fontisan 0.2.17 → 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/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/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 +19 -0
- 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 +14 -19
- 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 +114 -7
- data/fontisan.gemspec +0 -48
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../font_loader"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
module Pipeline
|
|
7
5
|
# Detects font format and capabilities
|
|
@@ -50,107 +48,62 @@ module Fontisan
|
|
|
50
48
|
|
|
51
49
|
# Detect font format
|
|
52
50
|
#
|
|
53
|
-
#
|
|
51
|
+
# Delegates to the loaded font object's own `#format` method.
|
|
52
|
+
# Each font class (TrueTypeFont, OpenTypeFont, WoffFont, Woff2Font,
|
|
53
|
+
# Type1Font, *Collection) is the single source of truth for its
|
|
54
|
+
# format identifier. This keeps FormatDetector closed for modification
|
|
55
|
+
# when new font classes are added (OCP): no case statement to edit.
|
|
56
|
+
#
|
|
57
|
+
# @return [Symbol] One of :ttf, :otf, :ttc, :otc, :woff, :woff2,
|
|
58
|
+
# :type1, :dfont, or :unknown
|
|
54
59
|
def detect_format
|
|
55
|
-
#
|
|
60
|
+
# SVG fonts are an export-only target; no font object exists yet.
|
|
56
61
|
return :svg if @file_path.end_with?(".svg")
|
|
57
62
|
|
|
58
63
|
return :unknown unless @font
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
case @font
|
|
62
|
-
when Fontisan::TrueTypeCollection
|
|
63
|
-
:ttc
|
|
64
|
-
when Fontisan::OpenTypeCollection
|
|
65
|
-
:otc
|
|
66
|
-
when Fontisan::TrueTypeFont
|
|
67
|
-
if @file_path.end_with?(".woff")
|
|
68
|
-
:woff
|
|
69
|
-
elsif @file_path.end_with?(".woff2")
|
|
70
|
-
:woff2
|
|
71
|
-
else
|
|
72
|
-
:ttf
|
|
73
|
-
end
|
|
74
|
-
when Fontisan::OpenTypeFont
|
|
75
|
-
if @file_path.end_with?(".woff")
|
|
76
|
-
:woff
|
|
77
|
-
elsif @file_path.end_with?(".woff2")
|
|
78
|
-
:woff2
|
|
79
|
-
else
|
|
80
|
-
:otf
|
|
81
|
-
end
|
|
82
|
-
else
|
|
83
|
-
:unknown
|
|
84
|
-
end
|
|
65
|
+
@font.format
|
|
85
66
|
end
|
|
86
67
|
|
|
87
68
|
# Detect variation type
|
|
88
69
|
#
|
|
89
|
-
#
|
|
70
|
+
# Delegates to the loaded font object's own `#variation_type` method.
|
|
71
|
+
# Each font class is the single source of truth for its variation
|
|
72
|
+
# profile, so this method needs no class-specific branching.
|
|
73
|
+
#
|
|
74
|
+
# @return [Symbol] :static, :gvar (TrueType variable), or :cff2
|
|
90
75
|
def detect_variation
|
|
91
76
|
return :static unless @font
|
|
92
77
|
|
|
93
|
-
|
|
94
|
-
# Return :static for collections (variation detection would need to load first font)
|
|
95
|
-
return :static if collection?
|
|
96
|
-
|
|
97
|
-
# Check for variable font tables
|
|
98
|
-
if @font.has_table?("fvar")
|
|
99
|
-
# Variable font detected - check variation type
|
|
100
|
-
if @font.has_table?("gvar")
|
|
101
|
-
:gvar # TrueType variable font
|
|
102
|
-
elsif @font.has_table?("CFF2")
|
|
103
|
-
:cff2 # OpenType variable font (CFF2)
|
|
104
|
-
else
|
|
105
|
-
:static # Has fvar but no variation data (shouldn't happen)
|
|
106
|
-
end
|
|
107
|
-
else
|
|
108
|
-
:static
|
|
109
|
-
end
|
|
78
|
+
@font.variation_type
|
|
110
79
|
end
|
|
111
80
|
|
|
112
81
|
# Detect font capabilities
|
|
113
82
|
#
|
|
83
|
+
# Aggregates four pieces of self-knowledge owned by the font class:
|
|
84
|
+
# outline representation, variation support, collection status, and
|
|
85
|
+
# the table directory. Each is exposed as a method on the font object
|
|
86
|
+
# so this method stays free of class-specific branching.
|
|
87
|
+
#
|
|
114
88
|
# @return [Hash] Capabilities hash
|
|
115
89
|
def detect_capabilities
|
|
116
90
|
return default_capabilities unless @font
|
|
117
91
|
|
|
118
|
-
# Check if this is a collection
|
|
119
|
-
is_collection = collection?
|
|
120
|
-
|
|
121
|
-
font_to_check = if is_collection
|
|
122
|
-
# Collections don't have fonts method, need to load first font
|
|
123
|
-
nil # Will handle in API usage
|
|
124
|
-
else
|
|
125
|
-
@font
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# For collections, return basic capabilities
|
|
129
|
-
if is_collection
|
|
130
|
-
return {
|
|
131
|
-
outline: :unknown, # Would need to load first font to know
|
|
132
|
-
variation: false, # Would need to load first font to know
|
|
133
|
-
collection: true,
|
|
134
|
-
tables: [],
|
|
135
|
-
}
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
return default_capabilities unless font_to_check
|
|
139
|
-
|
|
140
92
|
{
|
|
141
|
-
outline:
|
|
142
|
-
variation:
|
|
143
|
-
collection:
|
|
144
|
-
tables:
|
|
93
|
+
outline: @font.outline_type,
|
|
94
|
+
variation: @font.variation_type != :static,
|
|
95
|
+
collection: @font.collection?,
|
|
96
|
+
tables: @font.table_names,
|
|
145
97
|
}
|
|
146
98
|
end
|
|
147
99
|
|
|
148
100
|
# Check if font is a collection
|
|
149
101
|
#
|
|
150
|
-
# @return [Boolean] True if collection
|
|
102
|
+
# @return [Boolean] True if the loaded object is a font collection
|
|
151
103
|
def collection?
|
|
152
|
-
@font
|
|
153
|
-
|
|
104
|
+
return false unless @font
|
|
105
|
+
|
|
106
|
+
@font.collection?
|
|
154
107
|
end
|
|
155
108
|
|
|
156
109
|
# Check if font is variable
|
|
@@ -207,32 +160,6 @@ module Fontisan
|
|
|
207
160
|
@font = nil
|
|
208
161
|
end
|
|
209
162
|
|
|
210
|
-
# Detect outline type
|
|
211
|
-
#
|
|
212
|
-
# @param font [Font] Font object
|
|
213
|
-
# @return [Symbol] :truetype or :cff
|
|
214
|
-
def detect_outline_type(font)
|
|
215
|
-
if font.has_table?("glyf") || font.has_table?("gvar")
|
|
216
|
-
:truetype
|
|
217
|
-
elsif font.has_table?("CFF ") || font.has_table?("CFF2")
|
|
218
|
-
:cff
|
|
219
|
-
else
|
|
220
|
-
:unknown
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# Get available tables
|
|
225
|
-
#
|
|
226
|
-
# @param font [Font] Font object
|
|
227
|
-
# @return [Array<String>] List of table tags
|
|
228
|
-
def available_tables(font)
|
|
229
|
-
return [] unless font.respond_to?(:table_names)
|
|
230
|
-
|
|
231
|
-
font.table_names
|
|
232
|
-
rescue StandardError
|
|
233
|
-
[]
|
|
234
|
-
end
|
|
235
|
-
|
|
236
163
|
# Default capabilities when font cannot be loaded
|
|
237
164
|
#
|
|
238
165
|
# @return [Hash] Default capabilities
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../font_writer"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
module Pipeline
|
|
7
5
|
# Handles writing font tables to various output formats
|
|
@@ -33,8 +31,9 @@ module Fontisan
|
|
|
33
31
|
# Initialize output writer
|
|
34
32
|
#
|
|
35
33
|
# @param output_path [String] Path to write output
|
|
36
|
-
# @param format [Symbol] Target format (:ttf, :otf, :woff, :woff2)
|
|
37
|
-
# @param options [Hash] Writing options
|
|
34
|
+
# @param format [Symbol] Target format (:ttf, :otf, :woff, :woff2, :svg)
|
|
35
|
+
# @param options [Hash] Writing options. Format-specific compression
|
|
36
|
+
# knobs (zlib_level, brotli_quality, etc.) pass through to the strategy.
|
|
38
37
|
def initialize(output_path, format, options = {})
|
|
39
38
|
@output_path = output_path
|
|
40
39
|
@format = format
|
|
@@ -45,8 +44,15 @@ module Fontisan
|
|
|
45
44
|
#
|
|
46
45
|
# @param tables [Hash<String, String>, Hash] Font tables (tag => binary data) or special format result
|
|
47
46
|
# @return [Integer] Number of bytes written
|
|
48
|
-
# @raise [ArgumentError] If format is unsupported
|
|
47
|
+
# @raise [ArgumentError] If format is unsupported or options don't apply
|
|
49
48
|
def write(tables)
|
|
49
|
+
# Catch cross-format misuse before delegating, so the error message
|
|
50
|
+
# is consistent regardless of whether the format goes through
|
|
51
|
+
# FormatConverter (outline conversions) or this writer (packaging
|
|
52
|
+
# changes for WOFF/WOFF2).
|
|
53
|
+
Converters::FormatConverter.validate_options_for_target!(@format,
|
|
54
|
+
@options)
|
|
55
|
+
|
|
50
56
|
case @format
|
|
51
57
|
when :ttf, :otf
|
|
52
58
|
write_sfnt(tables)
|
|
@@ -92,8 +98,6 @@ module Fontisan
|
|
|
92
98
|
# @param tables [Hash<String, String>] Font tables
|
|
93
99
|
# @return [Integer] Number of bytes written
|
|
94
100
|
def write_woff(tables)
|
|
95
|
-
require_relative "../converters/woff_writer"
|
|
96
|
-
|
|
97
101
|
writer = Converters::WoffWriter.new
|
|
98
102
|
font = build_font_from_tables(tables)
|
|
99
103
|
woff_data = writer.convert(font, @options)
|
|
@@ -106,8 +110,6 @@ module Fontisan
|
|
|
106
110
|
# @param tables [Hash<String, String>] Font tables
|
|
107
111
|
# @return [Integer] Number of bytes written
|
|
108
112
|
def write_woff2(tables)
|
|
109
|
-
require_relative "../converters/woff2_encoder"
|
|
110
|
-
|
|
111
113
|
encoder = Converters::Woff2Encoder.new
|
|
112
114
|
font = build_font_from_tables(tables)
|
|
113
115
|
result = encoder.convert(font, @options)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Pipeline::Strategies namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Pipeline
|
|
7
|
+
module Strategies
|
|
8
|
+
autoload :BaseStrategy, "fontisan/pipeline/strategies/base_strategy"
|
|
9
|
+
autoload :InstanceStrategy, "fontisan/pipeline/strategies/instance_strategy"
|
|
10
|
+
autoload :NamedStrategy, "fontisan/pipeline/strategies/named_strategy"
|
|
11
|
+
autoload :PreserveStrategy, "fontisan/pipeline/strategies/preserve_strategy"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "format_detector"
|
|
4
|
-
require_relative "variation_resolver"
|
|
5
|
-
require_relative "../converters/format_converter"
|
|
6
|
-
require_relative "../font_loader"
|
|
7
|
-
require_relative "../font_writer"
|
|
8
|
-
require_relative "output_writer"
|
|
9
|
-
|
|
10
3
|
module Fontisan
|
|
11
4
|
module Pipeline
|
|
12
5
|
# Orchestrates universal font transformation pipeline
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "strategies/base_strategy"
|
|
4
|
-
require_relative "strategies/preserve_strategy"
|
|
5
|
-
require_relative "strategies/instance_strategy"
|
|
6
|
-
require_relative "strategies/named_strategy"
|
|
7
|
-
|
|
8
3
|
module Fontisan
|
|
9
4
|
module Pipeline
|
|
10
5
|
# Resolves variation data using strategy pattern
|
|
@@ -136,7 +131,6 @@ module Fontisan
|
|
|
136
131
|
def validate_instance_coordinates(coordinates)
|
|
137
132
|
return if coordinates.empty?
|
|
138
133
|
|
|
139
|
-
require_relative "../variation/variation_context"
|
|
140
134
|
context = Variation::VariationContext.new(@font)
|
|
141
135
|
context.validate_coordinates(coordinates)
|
|
142
136
|
end
|
|
@@ -146,7 +140,6 @@ module Fontisan
|
|
|
146
140
|
# @param instance_index [Integer] Instance index to validate
|
|
147
141
|
# @raise [ArgumentError] If index invalid
|
|
148
142
|
def validate_named_instance_index(instance_index)
|
|
149
|
-
require_relative "../variation/variation_context"
|
|
150
143
|
context = Variation::VariationContext.new(@font)
|
|
151
144
|
|
|
152
145
|
unless context.fvar
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Pipeline namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Pipeline
|
|
7
|
+
autoload :FormatDetector, "fontisan/pipeline/format_detector"
|
|
8
|
+
autoload :OutputWriter, "fontisan/pipeline/output_writer"
|
|
9
|
+
autoload :Strategies, "fontisan/pipeline/strategies/base_strategy"
|
|
10
|
+
autoload :TransformationPipeline, "fontisan/pipeline/transformation_pipeline"
|
|
11
|
+
autoload :VariationResolver, "fontisan/pipeline/variation_resolver"
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/fontisan/sfnt_font.rb
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
-
require_relative "constants"
|
|
5
|
-
require_relative "loading_modes"
|
|
6
|
-
require_relative "utilities/checksum_calculator"
|
|
7
|
-
require_relative "sfnt_table"
|
|
8
|
-
require_relative "tables/head_table"
|
|
9
|
-
require_relative "tables/name_table"
|
|
10
|
-
require_relative "tables/os2_table"
|
|
11
|
-
require_relative "tables/cmap_table"
|
|
12
|
-
require_relative "tables/glyf_table"
|
|
13
|
-
require_relative "tables/hhea_table"
|
|
14
|
-
require_relative "tables/maxp_table"
|
|
15
|
-
require_relative "tables/post_table"
|
|
16
|
-
require_relative "tables/hmtx_table"
|
|
17
|
-
require_relative "tables/loca_table"
|
|
18
4
|
|
|
19
5
|
module Fontisan
|
|
20
6
|
# SFNT Offset Table structure
|
|
@@ -377,6 +363,35 @@ module Fontisan
|
|
|
377
363
|
!find_table_entry(tag).nil?
|
|
378
364
|
end
|
|
379
365
|
|
|
366
|
+
# Whether this object represents a font collection rather than a single
|
|
367
|
+
# font. Each font class is the authority on this question.
|
|
368
|
+
#
|
|
369
|
+
# @return [Boolean]
|
|
370
|
+
def collection? = false
|
|
371
|
+
|
|
372
|
+
# Variation profile of the font, derived from its table set. Used by the
|
|
373
|
+
# conversion pipeline to choose between preserving variation tables and
|
|
374
|
+
# generating a static instance.
|
|
375
|
+
#
|
|
376
|
+
# @return [Symbol] :static, :gvar (TrueType variable), or :cff2 (CFF2 variable)
|
|
377
|
+
def variation_type
|
|
378
|
+
return :static unless has_table?("fvar")
|
|
379
|
+
return :gvar if has_table?("gvar")
|
|
380
|
+
return :cff2 if has_table?("CFF2")
|
|
381
|
+
|
|
382
|
+
:static
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Outline representation used by the font. Derived from the table set.
|
|
386
|
+
#
|
|
387
|
+
# @return [Symbol] :truetype (glyf/gvar) or :cff (CFF/CFF2)
|
|
388
|
+
def outline_type
|
|
389
|
+
return :truetype if has_table?("glyf") || has_table?("gvar")
|
|
390
|
+
return :cff if has_table?("CFF ") || has_table?("CFF2")
|
|
391
|
+
|
|
392
|
+
:unknown
|
|
393
|
+
end
|
|
394
|
+
|
|
380
395
|
# Check if a table is available in the current loading mode
|
|
381
396
|
#
|
|
382
397
|
# @param tag [String] The table tag to check
|
data/lib/fontisan/sfnt_table.rb
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "constants"
|
|
4
|
-
require_relative "loading_modes"
|
|
5
|
-
|
|
6
3
|
module Fontisan
|
|
7
4
|
# Base class for SFNT font tables
|
|
8
5
|
#
|
|
@@ -198,7 +195,6 @@ module Fontisan
|
|
|
198
195
|
def calculate_checksum
|
|
199
196
|
load_data! unless data_loaded?
|
|
200
197
|
|
|
201
|
-
require_relative "utilities/checksum_calculator"
|
|
202
198
|
Utilities::ChecksumCalculator.calculate_table_checksum(@data)
|
|
203
199
|
end
|
|
204
200
|
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "options"
|
|
4
|
-
require_relative "profile"
|
|
5
|
-
require_relative "glyph_mapping"
|
|
6
|
-
require_relative "table_subsetter"
|
|
7
|
-
require_relative "../font_writer"
|
|
8
|
-
|
|
9
3
|
module Fontisan
|
|
10
4
|
module Subset
|
|
11
5
|
# Main font subsetting engine
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Subset namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Subset
|
|
7
|
+
autoload :Builder, "fontisan/subset/builder"
|
|
8
|
+
autoload :GlyphMapping, "fontisan/subset/glyph_mapping"
|
|
9
|
+
autoload :Options, "fontisan/subset/options"
|
|
10
|
+
autoload :Profile, "fontisan/subset/profile"
|
|
11
|
+
autoload :TableSubsetter, "fontisan/subset/table_subsetter"
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/fontisan/svg.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Svg namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Svg
|
|
7
|
+
autoload :FontFaceGenerator, "fontisan/svg/font_face_generator"
|
|
8
|
+
autoload :FontGenerator, "fontisan/svg/font_generator"
|
|
9
|
+
autoload :GlyphGenerator, "fontisan/svg/glyph_generator"
|
|
10
|
+
autoload :ViewBoxCalculator, "fontisan/svg/view_box_calculator"
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/fontisan/tables/cbdt.rb
CHANGED
data/lib/fontisan/tables/cblc.rb
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "private_dict_writer"
|
|
4
|
-
require_relative "offset_recalculator"
|
|
5
|
-
require_relative "index_builder"
|
|
6
|
-
require_relative "dict_builder"
|
|
7
|
-
require_relative "charstring_rebuilder"
|
|
8
|
-
require_relative "hint_operation_injector"
|
|
9
3
|
require "stringio"
|
|
10
4
|
|
|
11
5
|
module Fontisan
|
data/lib/fontisan/tables/cff.rb
CHANGED
|
@@ -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
|
|
@@ -42,6 +41,28 @@ module Fontisan
|
|
|
42
41
|
# puts cff.font_count # => 1
|
|
43
42
|
# puts cff.header.version # => "1.0"
|
|
44
43
|
class Cff < Binary::BaseRecord
|
|
44
|
+
# Inner namespace autoloads — declared here so Cff::* constants
|
|
45
|
+
# resolve on first reference without require_relative.
|
|
46
|
+
autoload :CFFGlyph, "fontisan/tables/cff/cff_glyph"
|
|
47
|
+
autoload :Charset, "fontisan/tables/cff/charset"
|
|
48
|
+
autoload :CharString, "fontisan/tables/cff/charstring"
|
|
49
|
+
autoload :CharStringBuilder, "fontisan/tables/cff/charstring_builder"
|
|
50
|
+
autoload :CharStringParser, "fontisan/tables/cff/charstring_parser"
|
|
51
|
+
autoload :CharStringRebuilder, "fontisan/tables/cff/charstring_rebuilder"
|
|
52
|
+
autoload :CharstringsIndex, "fontisan/tables/cff/charstrings_index"
|
|
53
|
+
autoload :Dict, "fontisan/tables/cff/dict"
|
|
54
|
+
autoload :DictBuilder, "fontisan/tables/cff/dict_builder"
|
|
55
|
+
autoload :Encoding, "fontisan/tables/cff/encoding"
|
|
56
|
+
autoload :Header, "fontisan/tables/cff/header"
|
|
57
|
+
autoload :HintOperationInjector, "fontisan/tables/cff/hint_operation_injector"
|
|
58
|
+
autoload :Index, "fontisan/tables/cff/index"
|
|
59
|
+
autoload :IndexBuilder, "fontisan/tables/cff/index_builder"
|
|
60
|
+
autoload :OffsetRecalculator, "fontisan/tables/cff/offset_recalculator"
|
|
61
|
+
autoload :PrivateDict, "fontisan/tables/cff/private_dict"
|
|
62
|
+
autoload :PrivateDictWriter, "fontisan/tables/cff/private_dict_writer"
|
|
63
|
+
autoload :TableBuilder, "fontisan/tables/cff/table_builder"
|
|
64
|
+
autoload :TopDict, "fontisan/tables/cff/top_dict"
|
|
65
|
+
|
|
45
66
|
# OpenType table tag for CFF
|
|
46
67
|
TAG = "CFF "
|
|
47
68
|
|
|
@@ -468,19 +489,5 @@ module Fontisan
|
|
|
468
489
|
raise CorruptedTableError, "Failed to parse Encoding: #{e.message}"
|
|
469
490
|
end
|
|
470
491
|
end
|
|
471
|
-
|
|
472
|
-
# Load nested class definitions after the main class is defined
|
|
473
|
-
require_relative "cff/header"
|
|
474
|
-
require_relative "cff/index"
|
|
475
|
-
require_relative "cff/dict"
|
|
476
|
-
require_relative "cff/top_dict"
|
|
477
|
-
require_relative "cff/private_dict"
|
|
478
|
-
require_relative "cff/charstring"
|
|
479
|
-
require_relative "cff/charstring_parser"
|
|
480
|
-
require_relative "cff/charstring_rebuilder"
|
|
481
|
-
require_relative "cff/charstrings_index"
|
|
482
|
-
require_relative "cff/charset"
|
|
483
|
-
require_relative "cff/encoding"
|
|
484
|
-
require_relative "cff/cff_glyph"
|
|
485
492
|
end
|
|
486
493
|
end
|