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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 215de38977d0c94ac54def7b0aef0cc200e326172fd71b30912f6484ae122320
|
|
4
|
+
data.tar.gz: da89a4c238f617179e0da73377b83ae088d292c9e337cbc5c18832308864d970
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e18eef08d7be3ddd02e465497971cc020c7c5b03f40e4d92f02cf1c696d6553c9aa75b75cbea5ce4a5e43f0a7d683e57d7f1efada42b8d02b0b55da91837221
|
|
7
|
+
data.tar.gz: '02830dec034211c50cad0d5ebef7c771276808f815e5487e0a012bf08cd0b820eac0570befc0eb5a1b0bc518f5f906b5bfa3012de5d13ebe20a67cd42fb79a7c'
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,68 +1,27 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-
|
|
3
|
+
# on 2026-06-24 11:12:20 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count: 1
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
Gemspec/RequireMFA:
|
|
12
|
-
Exclude:
|
|
13
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
14
|
-
|
|
15
9
|
# Offense count: 2
|
|
16
10
|
Gemspec/RequiredRubyVersion:
|
|
17
11
|
Exclude:
|
|
18
12
|
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
19
13
|
- 'fontisan.gemspec'
|
|
20
14
|
|
|
21
|
-
# Offense count:
|
|
22
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
23
|
-
Layout/EmptyLines:
|
|
24
|
-
Exclude:
|
|
25
|
-
- 'lib/fontisan/loading_modes.rb'
|
|
26
|
-
|
|
27
|
-
# Offense count: 4
|
|
28
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
29
|
-
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
|
|
30
|
-
Layout/ExtraSpacing:
|
|
31
|
-
Exclude:
|
|
32
|
-
- 'docs/node_modules/speakingurl/lib/speakingurl-rails.rb'
|
|
33
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
34
|
-
|
|
35
|
-
# Offense count: 1
|
|
36
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
37
|
-
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
|
38
|
-
# SupportedHashRocketStyles: key, separator, table
|
|
39
|
-
# SupportedColonStyles: key, separator, table
|
|
40
|
-
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
|
41
|
-
Layout/HashAlignment:
|
|
42
|
-
Exclude:
|
|
43
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
44
|
-
|
|
45
|
-
# Offense count: 1585
|
|
15
|
+
# Offense count: 1606
|
|
46
16
|
# This cop supports safe autocorrection (--autocorrect).
|
|
47
17
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
48
18
|
# URISchemes: http, https
|
|
49
19
|
Layout/LineLength:
|
|
50
20
|
Enabled: false
|
|
51
21
|
|
|
52
|
-
# Offense count:
|
|
53
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
54
|
-
# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator, EnforcedStyleForRationalLiterals.
|
|
55
|
-
# SupportedStylesForExponentOperator: space, no_space
|
|
56
|
-
# SupportedStylesForRationalLiterals: space, no_space
|
|
57
|
-
Layout/SpaceAroundOperators:
|
|
58
|
-
Exclude:
|
|
59
|
-
- 'docs/node_modules/speakingurl/lib/speakingurl-rails.rb'
|
|
60
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
61
|
-
|
|
62
|
-
# Offense count: 3
|
|
22
|
+
# Offense count: 2
|
|
63
23
|
Lint/CopDirectiveSyntax:
|
|
64
24
|
Exclude:
|
|
65
|
-
- 'lib/fontisan/converters/woff_writer.rb'
|
|
66
25
|
- 'lib/fontisan/woff2_font.rb'
|
|
67
26
|
- 'spec/fontisan/variation/cache_spec.rb'
|
|
68
27
|
|
|
@@ -114,28 +73,18 @@ Lint/MissingSuper:
|
|
|
114
73
|
- 'lib/fontisan/commands/validate_command.rb'
|
|
115
74
|
- 'lib/fontisan/tables/cff2/table_builder.rb'
|
|
116
75
|
|
|
117
|
-
# Offense count: 4
|
|
118
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
119
|
-
Lint/RedundantRequireStatement:
|
|
120
|
-
Exclude:
|
|
121
|
-
- 'lib/fontisan/commands/features_command.rb'
|
|
122
|
-
- 'lib/fontisan/commands/scripts_command.rb'
|
|
123
|
-
- 'lib/fontisan/loading_modes.rb'
|
|
124
|
-
- 'lib/fontisan/variation/optimizer.rb'
|
|
125
|
-
|
|
126
76
|
# Offense count: 1
|
|
127
77
|
Lint/StructNewOverride:
|
|
128
78
|
Exclude:
|
|
129
79
|
- 'lib/fontisan/optimizers/pattern_analyzer.rb'
|
|
130
80
|
|
|
131
|
-
# Offense count:
|
|
81
|
+
# Offense count: 7
|
|
132
82
|
# This cop supports safe autocorrection (--autocorrect).
|
|
133
83
|
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
|
134
84
|
# NotImplementedExceptions: NotImplementedError
|
|
135
85
|
Lint/UnusedMethodArgument:
|
|
136
86
|
Exclude:
|
|
137
87
|
- 'lib/fontisan.rb'
|
|
138
|
-
- 'lib/fontisan/font_loader.rb'
|
|
139
88
|
- 'lib/fontisan/tables/cff2/private_dict_blend_handler.rb'
|
|
140
89
|
- 'lib/fontisan/utilities/brotli_wrapper.rb'
|
|
141
90
|
- 'lib/fontisan/variation/table_accessor.rb'
|
|
@@ -148,12 +97,12 @@ Lint/UselessConstantScoping:
|
|
|
148
97
|
- 'lib/fontisan/conversion_options.rb'
|
|
149
98
|
- 'lib/fontisan/type1/charstrings.rb'
|
|
150
99
|
|
|
151
|
-
# Offense count:
|
|
100
|
+
# Offense count: 552
|
|
152
101
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
153
102
|
Metrics/AbcSize:
|
|
154
103
|
Enabled: false
|
|
155
104
|
|
|
156
|
-
# Offense count:
|
|
105
|
+
# Offense count: 31
|
|
157
106
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
|
158
107
|
# AllowedMethods: refine
|
|
159
108
|
Metrics/BlockLength:
|
|
@@ -171,17 +120,17 @@ Metrics/CollectionLiteralLength:
|
|
|
171
120
|
- 'lib/fontisan/type1/agl.rb'
|
|
172
121
|
- 'lib/fontisan/type1/encodings.rb'
|
|
173
122
|
|
|
174
|
-
# Offense count:
|
|
123
|
+
# Offense count: 304
|
|
175
124
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
176
125
|
Metrics/CyclomaticComplexity:
|
|
177
126
|
Enabled: false
|
|
178
127
|
|
|
179
|
-
# Offense count:
|
|
128
|
+
# Offense count: 844
|
|
180
129
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
181
130
|
Metrics/MethodLength:
|
|
182
131
|
Max: 135
|
|
183
132
|
|
|
184
|
-
# Offense count:
|
|
133
|
+
# Offense count: 24
|
|
185
134
|
# Configuration parameters: CountKeywordArgs.
|
|
186
135
|
Metrics/ParameterLists:
|
|
187
136
|
Max: 39
|
|
@@ -241,7 +190,7 @@ Naming/VariableName:
|
|
|
241
190
|
- 'lib/fontisan/type1/pfm_generator.rb'
|
|
242
191
|
- 'lib/fontisan/type1/pfm_parser.rb'
|
|
243
192
|
|
|
244
|
-
# Offense count:
|
|
193
|
+
# Offense count: 111
|
|
245
194
|
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
|
246
195
|
# SupportedStyles: snake_case, normalcase, non_integer
|
|
247
196
|
# AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
|
|
@@ -264,7 +213,7 @@ RSpec/AnyInstance:
|
|
|
264
213
|
RSpec/ContextWording:
|
|
265
214
|
Enabled: false
|
|
266
215
|
|
|
267
|
-
# Offense count:
|
|
216
|
+
# Offense count: 28
|
|
268
217
|
# Configuration parameters: IgnoredMetadata.
|
|
269
218
|
RSpec/DescribeClass:
|
|
270
219
|
Enabled: false
|
|
@@ -280,7 +229,7 @@ RSpec/DescribeMethod:
|
|
|
280
229
|
- 'spec/fontisan/type1/seac_expander_spec.rb'
|
|
281
230
|
- 'spec/fontisan/type1_real_fonts_spec.rb'
|
|
282
231
|
|
|
283
|
-
# Offense count:
|
|
232
|
+
# Offense count: 1446
|
|
284
233
|
# Configuration parameters: CountAsOne.
|
|
285
234
|
RSpec/ExampleLength:
|
|
286
235
|
Max: 66
|
|
@@ -357,11 +306,11 @@ RSpec/MultipleDescribes:
|
|
|
357
306
|
- 'spec/fontisan/utils/thread_pool_spec.rb'
|
|
358
307
|
- 'spec/fontisan/variation/cache_spec.rb'
|
|
359
308
|
|
|
360
|
-
# Offense count:
|
|
309
|
+
# Offense count: 1868
|
|
361
310
|
RSpec/MultipleExpectations:
|
|
362
311
|
Max: 19
|
|
363
312
|
|
|
364
|
-
# Offense count:
|
|
313
|
+
# Offense count: 154
|
|
365
314
|
# Configuration parameters: AllowSubject.
|
|
366
315
|
RSpec/MultipleMemoizedHelpers:
|
|
367
316
|
Max: 13
|
|
@@ -442,13 +391,6 @@ Style/EmptyElse:
|
|
|
442
391
|
Exclude:
|
|
443
392
|
- 'lib/fontisan/type1/seac_expander.rb'
|
|
444
393
|
|
|
445
|
-
# Offense count: 2
|
|
446
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
447
|
-
Style/ExpandPathArguments:
|
|
448
|
-
Exclude:
|
|
449
|
-
- 'docs/node_modules/speakingurl/lib/speakingurl-rails.rb'
|
|
450
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
451
|
-
|
|
452
394
|
# Offense count: 11
|
|
453
395
|
# This cop supports safe autocorrection (--autocorrect).
|
|
454
396
|
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
|
|
@@ -466,27 +408,9 @@ Style/HashLikeCase:
|
|
|
466
408
|
- 'lib/fontisan/commands/unpack_command.rb'
|
|
467
409
|
- 'lib/fontisan/models/validation_report.rb'
|
|
468
410
|
|
|
469
|
-
# Offense count: 1
|
|
470
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
471
|
-
# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
|
|
472
|
-
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
|
|
473
|
-
# SupportedShorthandSyntax: always, never, either, consistent, either_consistent
|
|
474
|
-
Style/HashSyntax:
|
|
475
|
-
Exclude:
|
|
476
|
-
- 'docs/node_modules/speakingurl/lib/speakingurl-rails.rb'
|
|
477
|
-
|
|
478
411
|
# Offense count: 1
|
|
479
412
|
# Configuration parameters: AllowedMethods.
|
|
480
413
|
# AllowedMethods: respond_to_missing?
|
|
481
414
|
Style/OptionalBooleanParameter:
|
|
482
415
|
Exclude:
|
|
483
416
|
- 'lib/fontisan/conversion_options.rb'
|
|
484
|
-
|
|
485
|
-
# Offense count: 7
|
|
486
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
487
|
-
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
|
488
|
-
# SupportedStyles: single_quotes, double_quotes
|
|
489
|
-
Style/StringLiterals:
|
|
490
|
-
Exclude:
|
|
491
|
-
- 'docs/node_modules/speakingurl/lib/speakingurl-rails.rb'
|
|
492
|
-
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
data/Gemfile
CHANGED
|
@@ -5,12 +5,12 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in fontisan.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem "
|
|
9
|
-
gem "get_process_mem", "~> 0.2"
|
|
8
|
+
gem "benchmark"
|
|
10
9
|
# bigdecimal is required by get_process_mem for Ruby 3.4+ compatibility
|
|
11
10
|
gem "bigdecimal"
|
|
11
|
+
gem "canon", "~> 0.1.3"
|
|
12
|
+
gem "get_process_mem", "~> 0.2"
|
|
12
13
|
gem "openssl", "~> 3.0"
|
|
13
|
-
# sys-proctable is required by get_process_mem on Windows
|
|
14
14
|
gem "rake"
|
|
15
15
|
gem "rspec"
|
|
16
16
|
gem "rubocop"
|
|
@@ -18,4 +18,7 @@ gem "rubocop-performance"
|
|
|
18
18
|
gem "rubocop-rake"
|
|
19
19
|
gem "rubocop-rspec"
|
|
20
20
|
gem "rubyzip"
|
|
21
|
+
# sys-proctable is required by get_process_mem on Windows
|
|
21
22
|
gem "sys-proctable", platforms: %i[mswin mingw mswin64]
|
|
23
|
+
# win32ole was a default gem until Ruby 4.0 — pin it for Windows runners
|
|
24
|
+
gem "win32ole", platforms: %i[mswin mingw mswin64]
|
data/README.adoc
CHANGED
|
@@ -61,6 +61,7 @@ Color fonts and collections::
|
|
|
61
61
|
* Font collection validation with per-font reporting (see link:docs/COLLECTION_VALIDATION.adoc[Collection Validation Guide])
|
|
62
62
|
|
|
63
63
|
Font analysis and information::
|
|
64
|
+
* Comprehensive per-face font audit (replaces `otfinfo`) covering identity, style, metrics, codepoint coverage, licensing, hinting, color capabilities, variable-font detail, OpenType layout features, UCD block/script aggregation, and CLDR language coverage — plus `--compare` mode and whole-library `--recursive --summary` mode
|
|
64
65
|
* Bidirectional font hint conversion (see link:docs/FONT_HINTING.adoc[Font Hinting Guide])
|
|
65
66
|
* Extract comprehensive font metadata (name, version, designer, license, etc.)
|
|
66
67
|
* Brief mode for fast font indexing (5x faster, metadata-only loading)
|
|
@@ -99,11 +100,224 @@ Font engineering::
|
|
|
99
100
|
|
|
100
101
|
Export and interfaces::
|
|
101
102
|
* TTX/YAML/JSON export (complete)
|
|
102
|
-
* Command-line interface with
|
|
103
|
+
* Command-line interface with 19 commands
|
|
103
104
|
* Ruby library API for programmatic access
|
|
104
105
|
* Structured output in YAML, JSON, and text formats
|
|
105
106
|
|
|
106
107
|
|
|
108
|
+
== Font audit
|
|
109
|
+
|
|
110
|
+
=== General
|
|
111
|
+
|
|
112
|
+
The `audit` command produces a complete per-face font audit report —
|
|
113
|
+
the successor to `otfinfo`, covering everything `otfinfo` reports plus
|
|
114
|
+
codepoint coverage, licensing, hinting, color capabilities, variable-font
|
|
115
|
+
detail, OpenType layout, UCD block/script aggregation, and CLDR language
|
|
116
|
+
coverage. It also supports collections, `--compare` mode, and whole-
|
|
117
|
+
library `--recursive --summary` mode.
|
|
118
|
+
|
|
119
|
+
For each face, audit reports:
|
|
120
|
+
|
|
121
|
+
Identity & provenance:: `family_name`, `subfamily_name`, `full_name`,
|
|
122
|
+
`postscript_name`, `version`, `font_revision`, `source_sha256`,
|
|
123
|
+
`source_format`, `fontisan_version`, `generated_at`.
|
|
124
|
+
Style:: `weight_class` (+ human label), `width_class`, `bold`, `italic`,
|
|
125
|
+
`panose`, `fs_selection_flags`.
|
|
126
|
+
Coverage:: `total_codepoints`, `total_glyphs`, `cmap_subtables`,
|
|
127
|
+
`codepoint_ranges` (compact by default; `--all-codepoints` for the
|
|
128
|
+
flat list).
|
|
129
|
+
Licensing:: `license_url`, `license_description`, `embedding_type`
|
|
130
|
+
(decoded `fsType`).
|
|
131
|
+
Metrics:: `units_per_em`, ascender/descender/etc., x-height, cap height,
|
|
132
|
+
`metrics_consistent?` flag.
|
|
133
|
+
Hinting:: `has_fpgm`, `has_prep`, `gasp_ranges`, TrueType vs PostScript
|
|
134
|
+
hint presence.
|
|
135
|
+
Color capabilities:: COLR/CPAL, sbix, CBDT/CBLC, SVG table presence.
|
|
136
|
+
Variable-font detail:: axes (`fvar`), named instances.
|
|
137
|
+
OpenType layout:: scripts/features in GSUB and GPOS.
|
|
138
|
+
Aggregations (UCD):: per-block coverage rows, per-script roll-up.
|
|
139
|
+
Language coverage (opt-in via `--with-language-coverage`):: per-language
|
|
140
|
+
coverage % using CLDR exemplar sets.
|
|
141
|
+
|
|
142
|
+
[source,shell]
|
|
143
|
+
----
|
|
144
|
+
$ fontisan audit PATH [--compare LEFT RIGHT] [--recursive] [--summary]
|
|
145
|
+
[--brief] [--all-codepoints]
|
|
146
|
+
[--ucd-version VERSION] [--with-language-coverage]
|
|
147
|
+
[--cldr-version VERSION]
|
|
148
|
+
[--font-index N] [--output PATH] [--format FORMAT]
|
|
149
|
+
----
|
|
150
|
+
|
|
151
|
+
Where,
|
|
152
|
+
|
|
153
|
+
`PATH`:: Path to a font file (single-face audit), collection
|
|
154
|
+
(`TTC`/`OTC`/`dfont` — one report per face), or directory
|
|
155
|
+
(library mode with `--recursive`/`--summary`).
|
|
156
|
+
`--compare`:: Diff two inputs (each is a font file or a saved
|
|
157
|
+
`.yaml`/`.yml`/`.json` audit report). Requires exactly two paths.
|
|
158
|
+
`--recursive`:: Library mode: walk subdirectories.
|
|
159
|
+
`--summary`:: Library mode: produce a `LibrarySummary`.
|
|
160
|
+
`--brief`:: Fast inventory: skip metrics, hinting, color, variation,
|
|
161
|
+
OpenType layout, and UCD/CLDR aggregation. Note: distinct from
|
|
162
|
+
`info --brief` — `audit --brief` still loads the full font.
|
|
163
|
+
`--all-codepoints`:: Include the full per-codepoint list (default is a
|
|
164
|
+
compact range view).
|
|
165
|
+
`--ucd-version VERSION`:: Aggregate against this UCD version
|
|
166
|
+
(`latest` probes upstream).
|
|
167
|
+
`--with-language-coverage`:: Compute CLDR per-language coverage %
|
|
168
|
+
(auto-downloads CLDR on first use).
|
|
169
|
+
`--cldr-version VERSION`:: CLDR version (`latest` probes upstream).
|
|
170
|
+
`--font-index N`:: Audit only face N of a collection.
|
|
171
|
+
`--output PATH`:: Write to a directory (collection/library), file
|
|
172
|
+
(single/compare), or stdout.
|
|
173
|
+
`--format FORMAT`:: `text` (default), `yaml`, or `json`.
|
|
174
|
+
|
|
175
|
+
=== Command-line usage
|
|
176
|
+
|
|
177
|
+
Single face:
|
|
178
|
+
|
|
179
|
+
[source,shell]
|
|
180
|
+
----
|
|
181
|
+
$ fontisan audit NotoSans-Regular.ttf
|
|
182
|
+
$ fontisan audit NotoSans-Regular.ttf --format yaml
|
|
183
|
+
$ fontisan audit NotoSans-Regular.ttf --brief
|
|
184
|
+
$ fontisan audit NotoSans-Regular.ttf --with-language-coverage
|
|
185
|
+
----
|
|
186
|
+
|
|
187
|
+
Collection (one report per face):
|
|
188
|
+
|
|
189
|
+
[source,shell]
|
|
190
|
+
----
|
|
191
|
+
$ fontisan audit Family.ttc
|
|
192
|
+
$ fontisan audit Family.ttc --font-index 2
|
|
193
|
+
$ fontisan audit Family.ttc --output reports/
|
|
194
|
+
----
|
|
195
|
+
|
|
196
|
+
Compare two fonts or saved reports:
|
|
197
|
+
|
|
198
|
+
[source,shell]
|
|
199
|
+
----
|
|
200
|
+
$ fontisan audit --compare a.ttf b.ttf
|
|
201
|
+
$ fontisan audit --compare baseline.yaml new.ttf
|
|
202
|
+
$ fontisan audit --compare v1.yaml v2.yaml --output diff.yaml
|
|
203
|
+
----
|
|
204
|
+
|
|
205
|
+
Library summary:
|
|
206
|
+
|
|
207
|
+
[source,shell]
|
|
208
|
+
----
|
|
209
|
+
$ fontisan audit lib/ --summary
|
|
210
|
+
$ fontisan audit lib/ --recursive --summary
|
|
211
|
+
$ fontisan audit lib/ --recursive --summary --format yaml --output library.yaml
|
|
212
|
+
----
|
|
213
|
+
|
|
214
|
+
The library summary includes:
|
|
215
|
+
|
|
216
|
+
* `root_path`, `total_files`, `total_faces`, `scanned_extensions`
|
|
217
|
+
* `aggregate_metrics` — summed codepoints/glyphs/bytes
|
|
218
|
+
* `script_coverage` — per-script face counts and face lists
|
|
219
|
+
* `duplicate_groups` — files grouped by `source_sha256` (size > 1)
|
|
220
|
+
* `license_distribution` — face counts per `license_url`
|
|
221
|
+
* `per_face_reports` — the full per-face reports
|
|
222
|
+
|
|
223
|
+
Files that fail to load (corrupt, unsupported) are reported on stderr
|
|
224
|
+
as `skipped <path>` and excluded from the summary.
|
|
225
|
+
|
|
226
|
+
UCD/CLDR cache management:
|
|
227
|
+
|
|
228
|
+
[source,shell]
|
|
229
|
+
----
|
|
230
|
+
$ fontisan ucd status
|
|
231
|
+
$ fontisan ucd list
|
|
232
|
+
$ fontisan ucd download 17.0.0
|
|
233
|
+
$ fontisan cldr status
|
|
234
|
+
$ fontisan cldr list
|
|
235
|
+
$ fontisan cldr download 45
|
|
236
|
+
----
|
|
237
|
+
|
|
238
|
+
=== Ruby API usage
|
|
239
|
+
|
|
240
|
+
Single face:
|
|
241
|
+
|
|
242
|
+
[source,ruby]
|
|
243
|
+
----
|
|
244
|
+
require "fontisan"
|
|
245
|
+
|
|
246
|
+
# Returns an AuditReport for a single font, or an Array<AuditReport>
|
|
247
|
+
# for a collection (one per face, in source order).
|
|
248
|
+
report = Fontisan::Commands::AuditCommand.new(
|
|
249
|
+
"NotoSans-Regular.ttf", ucd_version: "17.0.0"
|
|
250
|
+
).run
|
|
251
|
+
|
|
252
|
+
report.family_name # => "Noto Sans"
|
|
253
|
+
report.licensing.license_url # => "https://scripts.sil.org/OFL"
|
|
254
|
+
report.blocks.first.fill_ratio # => 0.742
|
|
255
|
+
report.opentype_layout.features # => ["c2sc", "calt", "case", ...]
|
|
256
|
+
----
|
|
257
|
+
|
|
258
|
+
Compare:
|
|
259
|
+
|
|
260
|
+
[source,ruby]
|
|
261
|
+
----
|
|
262
|
+
diff = Fontisan::Commands::AuditCompareCommand.new(
|
|
263
|
+
"baseline.yaml", "new.ttf", ucd_version: "17.0.0"
|
|
264
|
+
).run
|
|
265
|
+
|
|
266
|
+
diff.field_changes.each { |c| puts "#{c.field}: #{c.left} -> #{c.right}" }
|
|
267
|
+
puts "added codepoints: #{diff.codepoints.added_count}"
|
|
268
|
+
----
|
|
269
|
+
|
|
270
|
+
Library summary:
|
|
271
|
+
|
|
272
|
+
[source,ruby]
|
|
273
|
+
----
|
|
274
|
+
cmd = Fontisan::Commands::AuditLibraryCommand.new(
|
|
275
|
+
"lib/", recursive: true, options: { ucd_version: "17.0.0" }
|
|
276
|
+
)
|
|
277
|
+
summary = cmd.run
|
|
278
|
+
cmd.skipped.each { |path| warn "skipped #{path}" }
|
|
279
|
+
|
|
280
|
+
summary.script_coverage.each do |row|
|
|
281
|
+
puts "#{row.script}: #{row.face_count} faces"
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
summary.duplicate_groups.each do |group|
|
|
285
|
+
puts "duplicate #{group.source_sha256[0, 8]}: #{group.files.join(', ')}"
|
|
286
|
+
end
|
|
287
|
+
----
|
|
288
|
+
|
|
289
|
+
Brief mode (note the `audit_brief:` key — `brief:` would trigger
|
|
290
|
+
metadata-only font loading via `BaseCommand`):
|
|
291
|
+
|
|
292
|
+
[source,ruby]
|
|
293
|
+
----
|
|
294
|
+
report = Fontisan::Commands::AuditCommand.new(
|
|
295
|
+
"NotoSans-Regular.ttf", audit_brief: true, ucd_version: "17.0.0"
|
|
296
|
+
).run
|
|
297
|
+
----
|
|
298
|
+
|
|
299
|
+
=== Architecture
|
|
300
|
+
|
|
301
|
+
Each audit concern is implemented as a small extractor class
|
|
302
|
+
registered in `Fontisan::Audit::Registry`. `AuditCommand` builds an
|
|
303
|
+
`Audit::Context` and iterates the registry, merging each extractor's
|
|
304
|
+
output into a single `Models::Audit::AuditReport`. Adding a new field
|
|
305
|
+
group means adding one extractor class and one line in the registry —
|
|
306
|
+
`AuditCommand` itself never changes (open/closed).
|
|
307
|
+
|
|
308
|
+
Two extractor sets are defined:
|
|
309
|
+
|
|
310
|
+
* `ORDERED_EXTRACTORS` — the full set (default).
|
|
311
|
+
* `BRIEF_EXTRACTORS` — a cheap subset for `--brief` (provenance,
|
|
312
|
+
identity, style, licensing, coverage).
|
|
313
|
+
|
|
314
|
+
Sub-models (`Licensing`, `Metrics`, `Hinting`, `ColorCapabilities`,
|
|
315
|
+
`VariationDetail`, `OpenTypeLayout`, `CodepointRange`, `AuditBlock`,
|
|
316
|
+
`NamedInstance`, `AuditAxis`, `ScriptFeatures`) group related fields
|
|
317
|
+
on `AuditReport` (MECE). Compare mode produces an `AuditDiff`; library
|
|
318
|
+
mode produces a `LibrarySummary`.
|
|
319
|
+
|
|
320
|
+
|
|
107
321
|
== Font information
|
|
108
322
|
|
|
109
323
|
=== General
|
|
@@ -2133,11 +2347,33 @@ Generating options (control how the output font is written):
|
|
|
2133
2347
|
* `--optimize-tables` - Enable table optimization
|
|
2134
2348
|
* `--decompose-on-output` - Decompose composites in output
|
|
2135
2349
|
|
|
2350
|
+
WOFF compression knobs (apply to `--to woff` only):
|
|
2351
|
+
|
|
2352
|
+
* `--zlib-level=N` - zlib level (0–9, default 6)
|
|
2353
|
+
* `--uncompressed` - store tables uncompressed (legal per WOFF 1.0 §5.1)
|
|
2354
|
+
* `--compression-threshold=N` - skip compression for tables smaller than N bytes
|
|
2355
|
+
|
|
2356
|
+
WOFF2 compression knobs (apply to `--to woff2` only):
|
|
2357
|
+
|
|
2358
|
+
* `--brotli-quality=N` - Brotli quality (0–11, default 11)
|
|
2359
|
+
* `--transform-tables` / `--no-transform-tables` - apply glyf/loca + hmtx transformations
|
|
2360
|
+
|
|
2361
|
+
The format selection (`--to woff` vs `--to woff2`) **is** the algorithm
|
|
2362
|
+
choice: WOFF mandates zlib, WOFF2 mandates Brotli. Passing a knob that
|
|
2363
|
+
doesn't apply to the requested target exits 1 with a clear error.
|
|
2364
|
+
|
|
2136
2365
|
[source,shell]
|
|
2137
2366
|
----
|
|
2138
2367
|
# Convert with autohinting and optimization
|
|
2139
2368
|
fontisan convert font.ttf --to otf --output font.otf \
|
|
2140
2369
|
--autohint --hinting-mode auto --optimize-tables
|
|
2370
|
+
|
|
2371
|
+
# Smallest WOFF2 (max Brotli + table transforms)
|
|
2372
|
+
fontisan convert font.ttf --to woff2 --output font.woff2 \
|
|
2373
|
+
--brotli-quality 11 --transform-tables
|
|
2374
|
+
|
|
2375
|
+
# WOFF for IE 9+ legacy reach (max zlib)
|
|
2376
|
+
fontisan convert font.ttf --to woff --output font.woff --zlib-level 9
|
|
2141
2377
|
----
|
|
2142
2378
|
|
|
2143
2379
|
For detailed information on all available options and conversion scenarios,
|
|
@@ -2206,6 +2442,26 @@ tables = converter.convert(font, options: options)
|
|
|
2206
2442
|
====
|
|
2207
2443
|
|
|
2208
2444
|
|
|
2445
|
+
.One-shot conversion via Fontisan.convert
|
|
2446
|
+
[example]
|
|
2447
|
+
====
|
|
2448
|
+
[source,ruby]
|
|
2449
|
+
----
|
|
2450
|
+
require 'fontisan'
|
|
2451
|
+
|
|
2452
|
+
# TTF → WOFF2 (modern browsers)
|
|
2453
|
+
Fontisan.convert('font.ttf', to: :woff2, output: 'font.woff2',
|
|
2454
|
+
brotli_quality: 11, transform_tables: true)
|
|
2455
|
+
|
|
2456
|
+
# TTF → WOFF (IE 9+ legacy reach, max zlib)
|
|
2457
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff', zlib_level: 9)
|
|
2458
|
+
|
|
2459
|
+
# WOFF stored uncompressed (legal per WOFF 1.0 §5.1; useful for tooling)
|
|
2460
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff', uncompressed: true)
|
|
2461
|
+
----
|
|
2462
|
+
====
|
|
2463
|
+
|
|
2464
|
+
|
|
2209
2465
|
== Round-Trip validation
|
|
2210
2466
|
|
|
2211
2467
|
=== General
|
data/docs/.vitepress/config.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import { defineConfig } from "vitepress";
|
|
1
|
+
import { defineConfig, type HeadConfig } from "vitepress";
|
|
2
|
+
|
|
3
|
+
const SITE_ORIGIN = "https://www.fontist.org";
|
|
4
|
+
const BASE_PATH = "/fontisan/";
|
|
5
|
+
const DEFAULT_DESCRIPTION =
|
|
6
|
+
"The most comprehensive font processing library for Ruby — 100% Pure Ruby, no Python, no C++, no C# dependencies.";
|
|
7
|
+
const DEFAULT_OG_IMAGE = `${SITE_ORIGIN}/og-image.png`;
|
|
8
|
+
|
|
9
|
+
// Map a page's source path to its canonical public URL (origin + base + clean path).
|
|
10
|
+
function pathToUrl(relativePath: string): string {
|
|
11
|
+
const bare = relativePath.replace(/\.md$/, "").replace(/\\/g, "/");
|
|
12
|
+
if (bare === "index") return `${SITE_ORIGIN}${BASE_PATH}`;
|
|
13
|
+
if (bare.endsWith("/index"))
|
|
14
|
+
return `${SITE_ORIGIN}${BASE_PATH}${bare.slice(0, -6)}/`;
|
|
15
|
+
return `${SITE_ORIGIN}${BASE_PATH}${bare}`;
|
|
16
|
+
}
|
|
2
17
|
|
|
3
18
|
// https://vitepress.dev/reference/site-config
|
|
4
19
|
export default defineConfig({
|
|
@@ -7,12 +22,29 @@ export default defineConfig({
|
|
|
7
22
|
// https://vitepress.dev/guide/routing#generating-clean-url
|
|
8
23
|
cleanUrls: true,
|
|
9
24
|
|
|
25
|
+
// Exclude standalone guide stubs that collide with directory routes.
|
|
26
|
+
// Both guide/<name>.md and guide/<name>/index.md exist for these three
|
|
27
|
+
// (hinting, validation, conversion); the directory version is the canonical
|
|
28
|
+
// one (sidebar-linked, richer content). Excluding the standalone stub from
|
|
29
|
+
// the build resolves the duplicate-route collision while keeping the source
|
|
30
|
+
// files in the repo.
|
|
31
|
+
srcExclude: [
|
|
32
|
+
"guide/hinting.md",
|
|
33
|
+
"guide/validation.md",
|
|
34
|
+
"guide/conversion.md",
|
|
35
|
+
],
|
|
36
|
+
|
|
10
37
|
title: "Fontisan",
|
|
11
38
|
description:
|
|
12
39
|
"The most comprehensive font processing library for Ruby — 100% Pure Ruby, no Python, no C++, no C# dependencies.",
|
|
13
40
|
|
|
14
41
|
lastUpdated: true,
|
|
15
42
|
|
|
43
|
+
// https://vitepress.dev/reference/site-config#sitemap
|
|
44
|
+
sitemap: {
|
|
45
|
+
hostname: SITE_ORIGIN,
|
|
46
|
+
},
|
|
47
|
+
|
|
16
48
|
// Base path for deployment (e.g., /fontisan/ for fontist.org/fontisan/)
|
|
17
49
|
base: process.env.BASE_PATH || "/fontisan/",
|
|
18
50
|
|
|
@@ -29,19 +61,40 @@ export default defineConfig({
|
|
|
29
61
|
],
|
|
30
62
|
["link", { rel: "manifest", href: "/site.webmanifest" }],
|
|
31
63
|
["meta", { property: "og:type", content: "website" }],
|
|
32
|
-
["
|
|
64
|
+
["link", { rel: "preconnect", href: "https://fonts.googleapis.com" }],
|
|
65
|
+
["link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "" }],
|
|
33
66
|
[
|
|
34
|
-
"
|
|
67
|
+
"link",
|
|
35
68
|
{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"The most comprehensive font processing library for Ruby — 100% Pure Ruby.",
|
|
69
|
+
rel: "stylesheet",
|
|
70
|
+
href: "https://fonts.googleapis.com/css2?family=Spectral:ital,opsz,wght@0,7..72,200..800;1,7..72,200..800&family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap",
|
|
39
71
|
},
|
|
40
72
|
],
|
|
41
|
-
["meta", { property: "og:image", content: "/logo-full.svg" }],
|
|
42
|
-
["meta", { name: "twitter:card", content: "summary_large_image" }],
|
|
43
73
|
],
|
|
44
74
|
|
|
75
|
+
// Per-page og:* and twitter:* tags are derived from each page's frontmatter.
|
|
76
|
+
// https://vitepress.dev/reference/site-config#transformhead
|
|
77
|
+
transformHead(ctx) {
|
|
78
|
+
const { pageData } = ctx;
|
|
79
|
+
const url = pathToUrl(pageData.relativePath);
|
|
80
|
+
const title = pageData.title || "Fontisan";
|
|
81
|
+
const description = pageData.description || DEFAULT_DESCRIPTION;
|
|
82
|
+
const image = pageData.frontmatter.image || DEFAULT_OG_IMAGE;
|
|
83
|
+
|
|
84
|
+
const tags: HeadConfig[] = [
|
|
85
|
+
["meta", { property: "og:title", content: title }],
|
|
86
|
+
["meta", { property: "og:description", content: description }],
|
|
87
|
+
["meta", { property: "og:url", content: url }],
|
|
88
|
+
["meta", { property: "og:image", content: image }],
|
|
89
|
+
["meta", { name: "twitter:card", content: "summary_large_image" }],
|
|
90
|
+
["meta", { name: "twitter:title", content: title }],
|
|
91
|
+
["meta", { name: "twitter:description", content: description }],
|
|
92
|
+
["meta", { name: "twitter:image", content: image }],
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
return tags;
|
|
96
|
+
},
|
|
97
|
+
|
|
45
98
|
// https://vitepress.dev/reference/default-theme-config
|
|
46
99
|
themeConfig: {
|
|
47
100
|
logo: "/logo-full.svg",
|
|
@@ -210,6 +263,13 @@ export default defineConfig({
|
|
|
210
263
|
{ text: "Overview", link: "/cli/" },
|
|
211
264
|
],
|
|
212
265
|
},
|
|
266
|
+
{
|
|
267
|
+
text: "Font Audit",
|
|
268
|
+
collapsed: true,
|
|
269
|
+
items: [
|
|
270
|
+
{ text: "audit", link: "/cli/audit" },
|
|
271
|
+
],
|
|
272
|
+
},
|
|
213
273
|
{
|
|
214
274
|
text: "Font Information",
|
|
215
275
|
collapsed: true,
|