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
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Audit
|
|
8
|
+
# Per-script breakdown of OpenType features.
|
|
9
|
+
#
|
|
10
|
+
# Pairs a script tag (e.g. "latn", "kana ") with the GSUB features
|
|
11
|
+
# and GPOS features that apply to it. The two collections are
|
|
12
|
+
# kept separate because substitution and positioning have different
|
|
13
|
+
# semantics — consumers answering "does this font support kerning
|
|
14
|
+
# for Latin?" want to look at GPOS only.
|
|
15
|
+
class ScriptFeatures < Lutaml::Model::Serializable
|
|
16
|
+
attribute :script, :string
|
|
17
|
+
attribute :gsub_features, :string, collection: true
|
|
18
|
+
attribute :gpos_features, :string, collection: true
|
|
19
|
+
|
|
20
|
+
key_value do
|
|
21
|
+
map "script", to: :script
|
|
22
|
+
map "gsub_features", to: :gsub_features
|
|
23
|
+
map "gpos_features", to: :gpos_features
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Audit
|
|
8
|
+
# Variable-font detail for one face.
|
|
9
|
+
#
|
|
10
|
+
# Bundles everything fvar-derived (axes + named instances) with the
|
|
11
|
+
# presence flags for every variation side-table (avar/cvar/HVAR/VVAR/
|
|
12
|
+
# MVAR/gvar). Replaces the previous flat `axes` + `is_variable` pair
|
|
13
|
+
# on AuditReport for MECE cleanliness — a face is variable iff this
|
|
14
|
+
# object is non-nil.
|
|
15
|
+
#
|
|
16
|
+
# `axes` reuses the existing AuditAxis shape; `named_instances` is a
|
|
17
|
+
# parallel NamedInstance collection. The has_* booleans are presence
|
|
18
|
+
# checks only — they don't validate the table contents.
|
|
19
|
+
class VariationDetail < Lutaml::Model::Serializable
|
|
20
|
+
attribute :axes, AuditAxis, collection: true
|
|
21
|
+
attribute :named_instances, NamedInstance, collection: true
|
|
22
|
+
|
|
23
|
+
# Variation side-table presence flags.
|
|
24
|
+
attribute :has_avar, Lutaml::Model::Type::Boolean # axis variation
|
|
25
|
+
attribute :has_cvar, Lutaml::Model::Type::Boolean # CVT variation
|
|
26
|
+
attribute :has_hvar, Lutaml::Model::Type::Boolean # horizontal metrics
|
|
27
|
+
attribute :has_vvar, Lutaml::Model::Type::Boolean # vertical metrics
|
|
28
|
+
attribute :has_mvar, Lutaml::Model::Type::Boolean # metrics variation
|
|
29
|
+
attribute :has_gvar, Lutaml::Model::Type::Boolean # glyph variation (TT)
|
|
30
|
+
|
|
31
|
+
key_value do
|
|
32
|
+
map "axes", to: :axes
|
|
33
|
+
map "named_instances", to: :named_instances
|
|
34
|
+
map "has_avar", to: :has_avar
|
|
35
|
+
map "has_cvar", to: :has_cvar
|
|
36
|
+
map "has_hvar", to: :has_hvar
|
|
37
|
+
map "has_vvar", to: :has_vvar
|
|
38
|
+
map "has_mvar", to: :has_mvar
|
|
39
|
+
map "has_gvar", to: :has_gvar
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Namespace hub for audit-related models.
|
|
4
|
+
#
|
|
5
|
+
# All Models::Audit::* constants are autoloaded from here.
|
|
6
|
+
|
|
7
|
+
module Fontisan
|
|
8
|
+
module Models
|
|
9
|
+
module Audit
|
|
10
|
+
autoload :AuditBlock, "fontisan/models/audit/audit_block"
|
|
11
|
+
autoload :AuditAxis, "fontisan/models/audit/audit_axis"
|
|
12
|
+
autoload :AuditDiff, "fontisan/models/audit/audit_diff"
|
|
13
|
+
autoload :AuditReport, "fontisan/models/audit/audit_report"
|
|
14
|
+
autoload :CodepointRange, "fontisan/models/audit/codepoint_range"
|
|
15
|
+
autoload :CodepointSetDiff, "fontisan/models/audit/codepoint_set_diff"
|
|
16
|
+
autoload :ColorCapabilities, "fontisan/models/audit/color_capabilities"
|
|
17
|
+
autoload :DuplicateGroup, "fontisan/models/audit/duplicate_group"
|
|
18
|
+
autoload :EmbeddingType, "fontisan/models/audit/embedding_type"
|
|
19
|
+
autoload :FieldChange, "fontisan/models/audit/field_change"
|
|
20
|
+
autoload :FsSelectionFlags, "fontisan/models/audit/fs_selection_flags"
|
|
21
|
+
autoload :GaspRange, "fontisan/models/audit/gasp_range"
|
|
22
|
+
autoload :Hinting, "fontisan/models/audit/hinting"
|
|
23
|
+
autoload :LibrarySummary, "fontisan/models/audit/library_summary"
|
|
24
|
+
autoload :Licensing, "fontisan/models/audit/licensing"
|
|
25
|
+
autoload :Metrics, "fontisan/models/audit/metrics"
|
|
26
|
+
autoload :NamedInstance, "fontisan/models/audit/named_instance"
|
|
27
|
+
autoload :OpenTypeLayout, "fontisan/models/audit/opentype_layout"
|
|
28
|
+
autoload :ScriptCoverageRow, "fontisan/models/audit/script_coverage_row"
|
|
29
|
+
autoload :ScriptFeatures, "fontisan/models/audit/script_features"
|
|
30
|
+
autoload :VariationDetail, "fontisan/models/audit/variation_detail"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Cldr
|
|
8
|
+
# Per-language coverage for one face against a CLDR exemplar set.
|
|
9
|
+
#
|
|
10
|
+
# `coverage_ratio` is in [0.0, 1.0] rounded to 4 decimal places;
|
|
11
|
+
# `fully_supported` is true only when every required codepoint
|
|
12
|
+
# (total > 0) is covered. A language with total == 0 (empty exemplar
|
|
13
|
+
# set in the index) is reported as ratio 0.0, fully_supported false.
|
|
14
|
+
class LanguageCoverage < Lutaml::Model::Serializable
|
|
15
|
+
attribute :language, :string
|
|
16
|
+
attribute :covered, :integer
|
|
17
|
+
attribute :total, :integer
|
|
18
|
+
attribute :coverage_ratio, :float
|
|
19
|
+
attribute :fully_supported, Lutaml::Model::Type::Boolean
|
|
20
|
+
|
|
21
|
+
key_value do
|
|
22
|
+
map "language", to: :language
|
|
23
|
+
map "covered", to: :covered
|
|
24
|
+
map "total", to: :total
|
|
25
|
+
map "coverage_ratio", to: :coverage_ratio
|
|
26
|
+
map "fully_supported", to: :fully_supported
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models::Ttx::Tables namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ttx
|
|
8
|
+
module Tables
|
|
9
|
+
autoload :BinaryTable, "fontisan/models/ttx/tables/binary_table"
|
|
10
|
+
autoload :HeadTable, "fontisan/models/ttx/tables/head_table"
|
|
11
|
+
autoload :HheaTable, "fontisan/models/ttx/tables/hhea_table"
|
|
12
|
+
autoload :MaxpTable, "fontisan/models/ttx/tables/maxp_table"
|
|
13
|
+
autoload :NameRecord, "fontisan/models/ttx/tables/name_table"
|
|
14
|
+
autoload :NameTable, "fontisan/models/ttx/tables/name_table"
|
|
15
|
+
autoload :Os2Table, "fontisan/models/ttx/tables/os2_table"
|
|
16
|
+
autoload :Panose, "fontisan/models/ttx/tables/os2_table"
|
|
17
|
+
autoload :PostTable, "fontisan/models/ttx/tables/post_table"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
|
-
require_relative "glyph_order"
|
|
5
|
-
require_relative "tables/head_table"
|
|
6
|
-
require_relative "tables/name_table"
|
|
7
|
-
require_relative "tables/maxp_table"
|
|
8
|
-
require_relative "tables/hhea_table"
|
|
9
|
-
require_relative "tables/os2_table"
|
|
10
|
-
require_relative "tables/post_table"
|
|
11
|
-
require_relative "tables/binary_table"
|
|
12
4
|
|
|
13
5
|
module Fontisan
|
|
14
6
|
module Models
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models::Ttx namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ttx
|
|
8
|
+
autoload :GlyphId, "fontisan/models/ttx/glyph_order"
|
|
9
|
+
autoload :GlyphOrder, "fontisan/models/ttx/glyph_order"
|
|
10
|
+
autoload :Tables, "fontisan/models/ttx/tables/os2_table"
|
|
11
|
+
autoload :TtFont, "fontisan/models/ttx/ttfont"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ucd
|
|
8
|
+
# Root <ucd> element of the UCDXML flat file.
|
|
9
|
+
#
|
|
10
|
+
# The flat UCDXML file has the structure:
|
|
11
|
+
#
|
|
12
|
+
# <ucd>
|
|
13
|
+
# <description>...</description>
|
|
14
|
+
# <last_revision date="2025-..." version="17.0.0" />
|
|
15
|
+
# <char cp="0000" .../>
|
|
16
|
+
# <char cp="0001" .../>
|
|
17
|
+
# ...
|
|
18
|
+
# <char first-cp="3400" last-cp="4DBF" .../>
|
|
19
|
+
# ...
|
|
20
|
+
# </ucd>
|
|
21
|
+
#
|
|
22
|
+
# The flat variant merges all per-category UCD files (Blocks.txt,
|
|
23
|
+
# Scripts.txt, UnicodeData.txt, etc.) into one stream of <char>
|
|
24
|
+
# elements. Roughly 340,000 entries for Unicode 17.0.0.
|
|
25
|
+
class Ucd < Lutaml::Model::Serializable
|
|
26
|
+
attribute :last_revision, :string
|
|
27
|
+
attribute :chars, UcdChar, collection: true
|
|
28
|
+
|
|
29
|
+
xml do
|
|
30
|
+
element "ucd"
|
|
31
|
+
|
|
32
|
+
map_element "last_revision", to: :last_revision
|
|
33
|
+
map_element "char", to: :chars
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ucd
|
|
8
|
+
# Single <char> element from the UCDXML flat file.
|
|
9
|
+
#
|
|
10
|
+
# UCDXML uses two forms:
|
|
11
|
+
# <char cp="0041" name="..." script="Latin" block="Basic Latin" .../>
|
|
12
|
+
# <char first-cp="3400" last-cp="4DBF" name="..." script="Han" .../>
|
|
13
|
+
#
|
|
14
|
+
# The first form describes one codepoint. The second form describes a
|
|
15
|
+
# closed range of codepoints that share the same properties (used for
|
|
16
|
+
# CJK ideograph ranges where each codepoint would otherwise need its
|
|
17
|
+
# own <char> entry).
|
|
18
|
+
#
|
|
19
|
+
# Both forms can appear in the same document; `cp` is mutually
|
|
20
|
+
# exclusive with `first-cp`/`last-cp`.
|
|
21
|
+
class UcdChar < Lutaml::Model::Serializable
|
|
22
|
+
attribute :cp, :string
|
|
23
|
+
attribute :first_cp, :string
|
|
24
|
+
attribute :last_cp, :string
|
|
25
|
+
attribute :name, :string
|
|
26
|
+
attribute :general_category, :string
|
|
27
|
+
attribute :script, :string
|
|
28
|
+
attribute :block, :string
|
|
29
|
+
attribute :age, :string
|
|
30
|
+
|
|
31
|
+
xml do
|
|
32
|
+
element "char"
|
|
33
|
+
|
|
34
|
+
map_attribute "cp", to: :cp
|
|
35
|
+
map_attribute "first-cp", to: :first_cp
|
|
36
|
+
map_attribute "last-cp", to: :last_cp
|
|
37
|
+
map_attribute "name", to: :name
|
|
38
|
+
map_attribute "general-category", to: :general_category
|
|
39
|
+
map_attribute "script", to: :script
|
|
40
|
+
map_attribute "block", to: :block
|
|
41
|
+
map_attribute "age", to: :age
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# True if this entry describes a codepoint range rather than a
|
|
45
|
+
# single codepoint.
|
|
46
|
+
def range?
|
|
47
|
+
!first_cp.nil? && !last_cp.nil?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The codepoints covered by this entry, as Integers.
|
|
51
|
+
# For a single-codepoint entry, returns a one-element array.
|
|
52
|
+
# For a range entry, returns the inclusive range as an array
|
|
53
|
+
# (caller should treat this lazily if the range is huge — CJK
|
|
54
|
+
# ranges can have tens of thousands of codepoints).
|
|
55
|
+
def codepoints
|
|
56
|
+
if range?
|
|
57
|
+
(first_cp.to_i(16)..last_cp.to_i(16)).to_a
|
|
58
|
+
elsif cp
|
|
59
|
+
[cp.to_i(16)]
|
|
60
|
+
else
|
|
61
|
+
[]
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
# Namespace for UCDXML deserialization models.
|
|
8
|
+
#
|
|
9
|
+
# These classes deserialize the upstream UCDXML flat file
|
|
10
|
+
# (https://www.unicode.org/Public/<version>/ucdxml/ucd.all.flat.zip)
|
|
11
|
+
# into Ruby objects. They are used by Fontisan::Ucd::IndexBuilder to
|
|
12
|
+
# derive compact run-length-encoded indices for Unicode block and
|
|
13
|
+
# script lookup.
|
|
14
|
+
module Ucd
|
|
15
|
+
autoload :UcdChar, "fontisan/models/ucd/ucd_char"
|
|
16
|
+
autoload :Ucd, "fontisan/models/ucd/ucd"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
autoload :AllScriptsFeaturesInfo, "fontisan/models/all_scripts_features_info"
|
|
8
|
+
autoload :Audit, "fontisan/models/audit"
|
|
9
|
+
autoload :AxisInfo, "fontisan/models/variable_font_info"
|
|
10
|
+
autoload :BitmapGlyph, "fontisan/models/bitmap_glyph"
|
|
11
|
+
autoload :BitmapStrike, "fontisan/models/bitmap_strike"
|
|
12
|
+
autoload :CollectionBriefInfo, "fontisan/models/collection_brief_info"
|
|
13
|
+
autoload :CollectionFontSummary, "fontisan/models/collection_font_summary"
|
|
14
|
+
autoload :CollectionInfo, "fontisan/models/collection_info"
|
|
15
|
+
autoload :CollectionListInfo, "fontisan/models/collection_list_info"
|
|
16
|
+
autoload :CollectionValidationReport, "fontisan/models/collection_validation_report"
|
|
17
|
+
autoload :Cldr, "fontisan/models/cldr"
|
|
18
|
+
autoload :ColorGlyph, "fontisan/models/color_glyph"
|
|
19
|
+
autoload :ColorLayer, "fontisan/models/color_layer"
|
|
20
|
+
autoload :ColorPalette, "fontisan/models/color_palette"
|
|
21
|
+
autoload :FeatureRecord, "fontisan/models/features_info"
|
|
22
|
+
autoload :FeaturesInfo, "fontisan/models/features_info"
|
|
23
|
+
autoload :FontExport, "fontisan/models/font_export"
|
|
24
|
+
autoload :FontInfo, "fontisan/models/font_info"
|
|
25
|
+
autoload :FontReport, "fontisan/models/font_report"
|
|
26
|
+
autoload :FontSummary, "fontisan/models/font_summary"
|
|
27
|
+
autoload :GlyphInfo, "fontisan/models/glyph_info"
|
|
28
|
+
autoload :GlyphOutline, "fontisan/models/glyph_outline"
|
|
29
|
+
autoload :Hint, "fontisan/models/hint"
|
|
30
|
+
autoload :HintSet, "fontisan/models/hint"
|
|
31
|
+
autoload :InstanceInfo, "fontisan/models/variable_font_info"
|
|
32
|
+
autoload :OpticalSizeInfo, "fontisan/models/optical_size_info"
|
|
33
|
+
autoload :Outline, "fontisan/models/outline"
|
|
34
|
+
autoload :ScriptRecord, "fontisan/models/scripts_info"
|
|
35
|
+
autoload :ScriptsInfo, "fontisan/models/scripts_info"
|
|
36
|
+
autoload :SvgGlyph, "fontisan/models/svg_glyph"
|
|
37
|
+
autoload :TableEntry, "fontisan/models/table_info"
|
|
38
|
+
autoload :TableInfo, "fontisan/models/table_info"
|
|
39
|
+
autoload :TableSharingInfo, "fontisan/models/table_sharing_info"
|
|
40
|
+
autoload :Ttx, "fontisan/models/ttx/ttfont"
|
|
41
|
+
autoload :Ucd, "fontisan/models/ucd"
|
|
42
|
+
autoload :UnicodeMapping, "fontisan/models/unicode_mappings"
|
|
43
|
+
autoload :UnicodeMappings, "fontisan/models/unicode_mappings"
|
|
44
|
+
autoload :ValidationReport, "fontisan/models/validation_report"
|
|
45
|
+
autoload :VariableFontInfo, "fontisan/models/variable_font_info"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_collection"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
# OpenType Collection domain object
|
|
7
5
|
#
|
|
@@ -15,11 +13,16 @@ module Fontisan
|
|
|
15
13
|
# fonts = otc.extract_fonts(io) # => [OpenTypeFont, OpenTypeFont, ...]
|
|
16
14
|
# end
|
|
17
15
|
class OpenTypeCollection < BaseCollection
|
|
16
|
+
# High-level pipeline format identifier. Owned by the collection class
|
|
17
|
+
# so the conversion pipeline can dispatch without case statements (OCP).
|
|
18
|
+
#
|
|
19
|
+
# @return [Symbol] :otc
|
|
20
|
+
def format = :otc
|
|
21
|
+
|
|
18
22
|
# Get the font class for OpenType collections
|
|
19
23
|
#
|
|
20
24
|
# @return [Class] OpenTypeFont class
|
|
21
25
|
def self.font_class
|
|
22
|
-
require_relative "open_type_font"
|
|
23
26
|
OpenTypeFont
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -38,8 +41,6 @@ module Fontisan
|
|
|
38
41
|
# @param io [IO] Open file handle to read fonts from
|
|
39
42
|
# @return [Array<OpenTypeFont>] Array of font objects
|
|
40
43
|
def extract_fonts(io)
|
|
41
|
-
require_relative "open_type_font"
|
|
42
|
-
|
|
43
44
|
font_offsets.map do |offset|
|
|
44
45
|
OpenTypeFont.from_collection(io, offset)
|
|
45
46
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "sfnt_font"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
# OpenType Font domain object
|
|
7
5
|
#
|
|
@@ -26,6 +24,14 @@ module Fontisan
|
|
|
26
24
|
# @example Reading from TTC collection
|
|
27
25
|
# otf = OpenTypeFont.from_collection(io, offset)
|
|
28
26
|
class OpenTypeFont < SfntFont
|
|
27
|
+
extend OpenTypeFontExtensions
|
|
28
|
+
|
|
29
|
+
# High-level pipeline format identifier. Owned by the font class so the
|
|
30
|
+
# conversion pipeline can dispatch without case statements (OCP).
|
|
31
|
+
#
|
|
32
|
+
# @return [Symbol] :otf
|
|
33
|
+
def format = :otf
|
|
34
|
+
|
|
29
35
|
# Page cache for lazy loading (maps page_start_offset => page_data)
|
|
30
36
|
attr_accessor :page_cache
|
|
31
37
|
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Fontisan
|
|
4
|
-
#
|
|
5
|
-
|
|
4
|
+
# Extension module for {OpenTypeFont} providing table-based construction.
|
|
5
|
+
#
|
|
6
|
+
# Extended into OpenTypeFont from +open_type_font.rb+ so that
|
|
7
|
+
# +OpenTypeFont.from_tables(...)+ is available whenever the class
|
|
8
|
+
# itself is loaded.
|
|
9
|
+
module OpenTypeFontExtensions
|
|
6
10
|
# Create font from hash of tables
|
|
7
11
|
#
|
|
8
12
|
# This is used during font conversion when we have tables but not a file.
|
|
9
13
|
#
|
|
10
14
|
# @param tables [Hash<String, String>] Map of table tag to binary data
|
|
11
15
|
# @return [OpenTypeFont] New font instance
|
|
12
|
-
def
|
|
13
|
-
# Create minimal header structure
|
|
16
|
+
def from_tables(tables)
|
|
14
17
|
font = new
|
|
15
18
|
font.initialize_storage
|
|
16
19
|
font.loading_mode = LoadingModes::FULL
|
|
17
20
|
|
|
18
|
-
# Store table data
|
|
19
21
|
font.table_data = tables
|
|
20
22
|
|
|
21
|
-
# Build header from tables
|
|
22
23
|
num_tables = tables.size
|
|
23
24
|
max_power = 0
|
|
24
25
|
n = num_tables
|
|
@@ -37,13 +38,12 @@ module Fontisan
|
|
|
37
38
|
font.header.entry_selector = entry_selector
|
|
38
39
|
font.header.range_shift = range_shift
|
|
39
40
|
|
|
40
|
-
# Build table directory
|
|
41
41
|
font.tables.clear
|
|
42
42
|
tables.each_key do |tag|
|
|
43
43
|
entry = TableDirectory.new
|
|
44
44
|
entry.tag = tag
|
|
45
|
-
entry.checksum = 0
|
|
46
|
-
entry.offset = 0
|
|
45
|
+
entry.checksum = 0
|
|
46
|
+
entry.offset = 0
|
|
47
47
|
entry.table_length = tables[tag].bytesize
|
|
48
48
|
font.tables << entry
|
|
49
49
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Optimizers namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Optimizers
|
|
7
|
+
autoload :CharstringRewriter, "fontisan/optimizers/charstring_rewriter"
|
|
8
|
+
autoload :PatternAnalyzer, "fontisan/optimizers/pattern_analyzer"
|
|
9
|
+
autoload :StackTracker, "fontisan/optimizers/stack_tracker"
|
|
10
|
+
autoload :SubroutineBuilder, "fontisan/optimizers/subroutine_builder"
|
|
11
|
+
autoload :SubroutineGenerator, "fontisan/optimizers/subroutine_generator"
|
|
12
|
+
autoload :SubroutineOptimizer, "fontisan/optimizers/subroutine_optimizer"
|
|
13
|
+
end
|
|
14
|
+
end
|