fontisan 0.2.22 → 0.2.23
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.yml +6 -0
- data/.rubocop_todo.yml +93 -17
- data/CHANGELOG.md +12 -2
- data/README.adoc +6 -210
- data/fontisan.gemspec +48 -0
- data/lib/fontisan/cldr/unicode_set_parser.rb +23 -6
- data/lib/fontisan/cldr/version_resolver.rb +1 -1
- data/lib/fontisan/cli.rb +0 -170
- data/lib/fontisan/commands.rb +0 -3
- data/lib/fontisan/formatters/text_formatter.rb +0 -6
- data/lib/fontisan/formatters.rb +0 -3
- data/lib/fontisan/hints.rb +6 -3
- data/lib/fontisan/models.rb +4 -4
- data/lib/fontisan/pipeline/strategies.rb +4 -2
- data/lib/fontisan/pipeline.rb +2 -1
- data/lib/fontisan/tables/cff.rb +2 -1
- data/lib/fontisan/tables.rb +2 -1
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan.rb +0 -3
- metadata +7 -70
- data/lib/fontisan/audit/codepoint_range_coalescer.rb +0 -41
- data/lib/fontisan/audit/context.rb +0 -122
- data/lib/fontisan/audit/differ.rb +0 -124
- data/lib/fontisan/audit/extractors/aggregations.rb +0 -54
- data/lib/fontisan/audit/extractors/base.rb +0 -26
- data/lib/fontisan/audit/extractors/color_capabilities.rb +0 -141
- data/lib/fontisan/audit/extractors/coverage.rb +0 -48
- data/lib/fontisan/audit/extractors/hinting.rb +0 -197
- data/lib/fontisan/audit/extractors/identity.rb +0 -52
- data/lib/fontisan/audit/extractors/language_coverage.rb +0 -37
- data/lib/fontisan/audit/extractors/licensing.rb +0 -79
- data/lib/fontisan/audit/extractors/metrics.rb +0 -103
- data/lib/fontisan/audit/extractors/opentype_layout.rb +0 -69
- data/lib/fontisan/audit/extractors/provenance.rb +0 -29
- data/lib/fontisan/audit/extractors/style.rb +0 -32
- data/lib/fontisan/audit/extractors/variation_detail.rb +0 -99
- data/lib/fontisan/audit/extractors.rb +0 -27
- data/lib/fontisan/audit/library_aggregator.rb +0 -83
- data/lib/fontisan/audit/library_auditor.rb +0 -90
- data/lib/fontisan/audit/registry.rb +0 -60
- data/lib/fontisan/audit/style_extractor.rb +0 -80
- data/lib/fontisan/audit.rb +0 -20
- data/lib/fontisan/cli/ucd_cli.rb +0 -97
- data/lib/fontisan/commands/audit_command.rb +0 -123
- data/lib/fontisan/commands/audit_compare_command.rb +0 -66
- data/lib/fontisan/commands/audit_library_command.rb +0 -46
- data/lib/fontisan/config/ucd.yml +0 -23
- data/lib/fontisan/formatters/audit_diff_text_renderer.rb +0 -122
- data/lib/fontisan/formatters/audit_text_renderer.rb +0 -324
- data/lib/fontisan/formatters/library_summary_text_renderer.rb +0 -99
- data/lib/fontisan/models/audit/audit_axis.rb +0 -30
- data/lib/fontisan/models/audit/audit_block.rb +0 -32
- data/lib/fontisan/models/audit/audit_diff.rb +0 -77
- data/lib/fontisan/models/audit/audit_report.rb +0 -153
- data/lib/fontisan/models/audit/codepoint_range.rb +0 -40
- data/lib/fontisan/models/audit/codepoint_set_diff.rb +0 -34
- data/lib/fontisan/models/audit/color_capabilities.rb +0 -93
- data/lib/fontisan/models/audit/duplicate_group.rb +0 -23
- data/lib/fontisan/models/audit/embedding_type.rb +0 -76
- data/lib/fontisan/models/audit/field_change.rb +0 -28
- data/lib/fontisan/models/audit/fs_selection_flags.rb +0 -61
- data/lib/fontisan/models/audit/gasp_range.rb +0 -63
- data/lib/fontisan/models/audit/hinting.rb +0 -93
- data/lib/fontisan/models/audit/library_summary.rb +0 -40
- data/lib/fontisan/models/audit/licensing.rb +0 -48
- data/lib/fontisan/models/audit/metrics.rb +0 -111
- data/lib/fontisan/models/audit/named_instance.rb +0 -41
- data/lib/fontisan/models/audit/opentype_layout.rb +0 -40
- data/lib/fontisan/models/audit/script_coverage_row.rb +0 -26
- data/lib/fontisan/models/audit/script_features.rb +0 -28
- data/lib/fontisan/models/audit/variation_detail.rb +0 -44
- data/lib/fontisan/models/audit.rb +0 -33
- data/lib/fontisan/models/ucd/ucd.rb +0 -38
- data/lib/fontisan/models/ucd/ucd_char.rb +0 -67
- data/lib/fontisan/models/ucd.rb +0 -19
- data/lib/fontisan/ucd/aggregator.rb +0 -73
- data/lib/fontisan/ucd/cache_manager.rb +0 -111
- data/lib/fontisan/ucd/config.rb +0 -59
- data/lib/fontisan/ucd/download_error.rb +0 -9
- data/lib/fontisan/ucd/downloader.rb +0 -88
- data/lib/fontisan/ucd/error.rb +0 -8
- data/lib/fontisan/ucd/index.rb +0 -103
- data/lib/fontisan/ucd/index_builder.rb +0 -107
- data/lib/fontisan/ucd/range_entry.rb +0 -56
- data/lib/fontisan/ucd/unknown_version_error.rb +0 -9
- data/lib/fontisan/ucd/version_resolver.rb +0 -79
- data/lib/fontisan/ucd.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f84b59fae400f9db9dd05b2ddebce11bedb865138026f7a3a6d1b7ce0b3d8f2a
|
|
4
|
+
data.tar.gz: 563b27ed9dc91412fb83d7769a72a0d618109e3a6394236c7648524a60ad4fb6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f2d94e40b9444414113ebf842a4a84e2188199829b4caf8b9e707bea6bca89c07b5e11fa04ba2f4aff1ce7ea658004385a5e2ae2ae4b4d4094d5bb90c4d5345
|
|
7
|
+
data.tar.gz: becf5ccba115f938caeb23d29e3cc0685edc9e0cb8452f8b1ed8b7e76cc8e742adcf3f9d1f5c8b1f01c1631fcb28a4ff2305068ce6b9677ef339d8f5fb4765b9
|
data/.rubocop.yml
CHANGED
|
@@ -114,3 +114,9 @@ Layout/LineEndStringConcatenationIndentation:
|
|
|
114
114
|
# Bitwise AND checks with != 0 are clearer for font bitmasks
|
|
115
115
|
Style/BitwisePredicate:
|
|
116
116
|
Enabled: false
|
|
117
|
+
|
|
118
|
+
# Allow short math-conventional parameter names in font geometry code.
|
|
119
|
+
# Point#x / Point#y are domain-standard coordinate names; renaming to
|
|
120
|
+
# x_coord/y_coord adds noise without aiding readers.
|
|
121
|
+
Naming/MethodParameterName:
|
|
122
|
+
AllowedNames: ["x", "y", "cp", "gid", "n"]
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-06-
|
|
3
|
+
# on 2026-06-29 07:08:46 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
|
|
@@ -12,13 +12,77 @@ Gemspec/RequiredRubyVersion:
|
|
|
12
12
|
- 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
|
|
13
13
|
- 'fontisan.gemspec'
|
|
14
14
|
|
|
15
|
-
# Offense count:
|
|
15
|
+
# Offense count: 21
|
|
16
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
17
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
18
|
+
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
19
|
+
Layout/ArgumentAlignment:
|
|
20
|
+
Exclude:
|
|
21
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
22
|
+
- 'lib/fontisan/hints.rb'
|
|
23
|
+
- 'lib/fontisan/models.rb'
|
|
24
|
+
- 'lib/fontisan/pipeline.rb'
|
|
25
|
+
- 'lib/fontisan/pipeline/strategies.rb'
|
|
26
|
+
- 'lib/fontisan/tables.rb'
|
|
27
|
+
- 'lib/fontisan/tables/cff.rb'
|
|
28
|
+
- 'spec/fontisan/cldr/config_spec.rb'
|
|
29
|
+
- 'spec/fontisan/cldr/unicode_set_parser_spec.rb'
|
|
30
|
+
- 'spec/fontisan/cli/cldr_cli_spec.rb'
|
|
31
|
+
|
|
32
|
+
# Offense count: 2
|
|
33
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
34
|
+
# Configuration parameters: EnforcedStyleAlignWith.
|
|
35
|
+
# SupportedStylesAlignWith: either, start_of_block, start_of_line
|
|
36
|
+
Layout/BlockAlignment:
|
|
37
|
+
Exclude:
|
|
38
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
39
|
+
- 'spec/fontisan/cldr/index_spec.rb'
|
|
40
|
+
|
|
41
|
+
# Offense count: 2
|
|
42
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
43
|
+
Layout/BlockEndNewline:
|
|
44
|
+
Exclude:
|
|
45
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
46
|
+
- 'spec/fontisan/cldr/index_spec.rb'
|
|
47
|
+
|
|
48
|
+
# Offense count: 2
|
|
49
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
50
|
+
Layout/EmptyLines:
|
|
51
|
+
Exclude:
|
|
52
|
+
- 'lib/fontisan/cli.rb'
|
|
53
|
+
|
|
54
|
+
# Offense count: 4
|
|
55
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
56
|
+
# Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
|
|
57
|
+
# SupportedStylesAlignWith: start_of_line, relative_to_receiver
|
|
58
|
+
Layout/IndentationWidth:
|
|
59
|
+
Exclude:
|
|
60
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
61
|
+
- 'spec/fontisan/cldr/index_spec.rb'
|
|
62
|
+
|
|
63
|
+
# Offense count: 1641
|
|
16
64
|
# This cop supports safe autocorrection (--autocorrect).
|
|
17
65
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
18
66
|
# URISchemes: http, https
|
|
19
67
|
Layout/LineLength:
|
|
20
68
|
Enabled: false
|
|
21
69
|
|
|
70
|
+
# Offense count: 21
|
|
71
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
72
|
+
# Configuration parameters: AllowInHeredoc.
|
|
73
|
+
Layout/TrailingWhitespace:
|
|
74
|
+
Exclude:
|
|
75
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
76
|
+
- 'lib/fontisan/hints.rb'
|
|
77
|
+
- 'lib/fontisan/models.rb'
|
|
78
|
+
- 'lib/fontisan/pipeline.rb'
|
|
79
|
+
- 'lib/fontisan/pipeline/strategies.rb'
|
|
80
|
+
- 'lib/fontisan/tables.rb'
|
|
81
|
+
- 'lib/fontisan/tables/cff.rb'
|
|
82
|
+
- 'spec/fontisan/cldr/config_spec.rb'
|
|
83
|
+
- 'spec/fontisan/cldr/unicode_set_parser_spec.rb'
|
|
84
|
+
- 'spec/fontisan/cli/cldr_cli_spec.rb'
|
|
85
|
+
|
|
22
86
|
# Offense count: 2
|
|
23
87
|
Lint/CopDirectiveSyntax:
|
|
24
88
|
Exclude:
|
|
@@ -97,7 +161,7 @@ Lint/UselessConstantScoping:
|
|
|
97
161
|
- 'lib/fontisan/conversion_options.rb'
|
|
98
162
|
- 'lib/fontisan/type1/charstrings.rb'
|
|
99
163
|
|
|
100
|
-
# Offense count:
|
|
164
|
+
# Offense count: 557
|
|
101
165
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
102
166
|
Metrics/AbcSize:
|
|
103
167
|
Enabled: false
|
|
@@ -120,12 +184,12 @@ Metrics/CollectionLiteralLength:
|
|
|
120
184
|
- 'lib/fontisan/type1/agl.rb'
|
|
121
185
|
- 'lib/fontisan/type1/encodings.rb'
|
|
122
186
|
|
|
123
|
-
# Offense count:
|
|
187
|
+
# Offense count: 308
|
|
124
188
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
125
189
|
Metrics/CyclomaticComplexity:
|
|
126
190
|
Enabled: false
|
|
127
191
|
|
|
128
|
-
# Offense count:
|
|
192
|
+
# Offense count: 849
|
|
129
193
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
130
194
|
Metrics/MethodLength:
|
|
131
195
|
Max: 135
|
|
@@ -136,22 +200,16 @@ Metrics/ParameterLists:
|
|
|
136
200
|
Max: 39
|
|
137
201
|
MaxOptionalParameters: 4
|
|
138
202
|
|
|
139
|
-
# Offense count:
|
|
203
|
+
# Offense count: 231
|
|
140
204
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
141
205
|
Metrics/PerceivedComplexity:
|
|
142
206
|
Enabled: false
|
|
143
207
|
|
|
144
|
-
# Offense count:
|
|
208
|
+
# Offense count: 166
|
|
145
209
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
|
146
210
|
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
|
147
211
|
Naming/MethodParameterName:
|
|
148
|
-
|
|
149
|
-
- 'lib/fontisan/optimizers/subroutine_optimizer.rb'
|
|
150
|
-
- 'lib/fontisan/tables/cff2/blend_operator.rb'
|
|
151
|
-
- 'lib/fontisan/tables/glyf/curve_converter.rb'
|
|
152
|
-
- 'lib/fontisan/type1/seac_expander.rb'
|
|
153
|
-
- 'lib/fontisan/type1/ttf_to_type1_converter.rb'
|
|
154
|
-
- 'lib/fontisan/variation/optimizer.rb'
|
|
212
|
+
Enabled: false
|
|
155
213
|
|
|
156
214
|
# Offense count: 13
|
|
157
215
|
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
@@ -229,7 +287,7 @@ RSpec/DescribeMethod:
|
|
|
229
287
|
- 'spec/fontisan/type1/seac_expander_spec.rb'
|
|
230
288
|
- 'spec/fontisan/type1_real_fonts_spec.rb'
|
|
231
289
|
|
|
232
|
-
# Offense count:
|
|
290
|
+
# Offense count: 1458
|
|
233
291
|
# Configuration parameters: CountAsOne.
|
|
234
292
|
RSpec/ExampleLength:
|
|
235
293
|
Max: 66
|
|
@@ -306,7 +364,7 @@ RSpec/MultipleDescribes:
|
|
|
306
364
|
- 'spec/fontisan/utils/thread_pool_spec.rb'
|
|
307
365
|
- 'spec/fontisan/variation/cache_spec.rb'
|
|
308
366
|
|
|
309
|
-
# Offense count:
|
|
367
|
+
# Offense count: 1902
|
|
310
368
|
RSpec/MultipleExpectations:
|
|
311
369
|
Max: 19
|
|
312
370
|
|
|
@@ -338,7 +396,7 @@ RSpec/RepeatedExample:
|
|
|
338
396
|
- 'spec/fontisan/metrics_calculator_spec.rb'
|
|
339
397
|
- 'spec/fontisan/tables/os2_spec.rb'
|
|
340
398
|
|
|
341
|
-
# Offense count:
|
|
399
|
+
# Offense count: 23
|
|
342
400
|
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
343
401
|
# SupportedInflectors: default, active_support
|
|
344
402
|
RSpec/SpecFilePathFormat:
|
|
@@ -374,6 +432,18 @@ Security/Open:
|
|
|
374
432
|
Exclude:
|
|
375
433
|
- 'Rakefile'
|
|
376
434
|
|
|
435
|
+
# Offense count: 2
|
|
436
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
437
|
+
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
|
|
438
|
+
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
|
439
|
+
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
|
440
|
+
# FunctionalMethods: let, let!, subject, watch
|
|
441
|
+
# AllowedMethods: lambda, proc, it
|
|
442
|
+
Style/BlockDelimiters:
|
|
443
|
+
Exclude:
|
|
444
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
445
|
+
- 'spec/fontisan/cldr/index_spec.rb'
|
|
446
|
+
|
|
377
447
|
# Offense count: 6
|
|
378
448
|
# This cop supports safe autocorrection (--autocorrect).
|
|
379
449
|
Style/ComparableClamp:
|
|
@@ -408,6 +478,12 @@ Style/HashLikeCase:
|
|
|
408
478
|
- 'lib/fontisan/commands/unpack_command.rb'
|
|
409
479
|
- 'lib/fontisan/models/validation_report.rb'
|
|
410
480
|
|
|
481
|
+
# Offense count: 9
|
|
482
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
483
|
+
Style/MultilineIfModifier:
|
|
484
|
+
Exclude:
|
|
485
|
+
- 'lib/fontisan/cldr/unicode_set_parser.rb'
|
|
486
|
+
|
|
411
487
|
# Offense count: 1
|
|
412
488
|
# Configuration parameters: AllowedMethods.
|
|
413
489
|
# AllowedMethods: respond_to_missing?
|
data/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### Removed
|
|
11
|
+
|
|
12
|
+
- Audit subsystem (`Fontisan::Audit`, `Fontisan::Commands::Audit*`,
|
|
13
|
+
`Formatters::AuditTextRenderer` / `AuditDiffTextRenderer` /
|
|
14
|
+
`LibrarySummaryTextRenderer`, `Models::Audit::*`) — moved to ucode.
|
|
15
|
+
Never had external consumers.
|
|
16
|
+
- UCD/UCDXML subsystem (`Fontisan::Ucd`, `config/ucd.yml`) — moved to
|
|
17
|
+
ucode. Never released in a published gem version.
|
|
18
|
+
- `fontisan audit` and `fontisan ucd` CLI subcommands.
|
|
19
|
+
|
|
20
|
+
### Added (documentation)
|
|
11
21
|
- Comprehensive documentation for WOFF/WOFF2 format support
|
|
12
22
|
- Color fonts documentation (COLR/CPAL, sbix, SVG tables)
|
|
13
23
|
- Font validation framework documentation
|
|
@@ -16,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
16
26
|
- Updated font hinting documentation
|
|
17
27
|
- Enhanced README with all v0.2.1-v0.2.7 features
|
|
18
28
|
|
|
19
|
-
### Changed
|
|
29
|
+
### Changed (documentation)
|
|
20
30
|
- Improved documentation organization with dedicated feature guides
|
|
21
31
|
- Added more examples for command-line and Ruby API usage
|
|
22
32
|
|
data/README.adoc
CHANGED
|
@@ -61,7 +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
|
|
64
|
+
* Comprehensive per-face font metadata extraction (replaces `otfinfo`) covering identity, style, metrics, codepoint coverage, licensing, hinting, color capabilities, variable-font detail, and OpenType layout features
|
|
65
65
|
* Bidirectional font hint conversion (see link:docs/FONT_HINTING.adoc[Font Hinting Guide])
|
|
66
66
|
* Extract comprehensive font metadata (name, version, designer, license, etc.)
|
|
67
67
|
* Brief mode for fast font indexing (5x faster, metadata-only loading)
|
|
@@ -107,215 +107,11 @@ Export and interfaces::
|
|
|
107
107
|
|
|
108
108
|
== Font audit
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
The `audit`
|
|
113
|
-
the
|
|
114
|
-
|
|
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`.
|
|
110
|
+
[NOTE]
|
|
111
|
+
====
|
|
112
|
+
The `audit` and `ucd` subsystems have moved to the `ucode` gem. See
|
|
113
|
+
the `ucode` documentation for the equivalent commands.
|
|
114
|
+
====
|
|
319
115
|
|
|
320
116
|
|
|
321
117
|
== Font information
|
data/fontisan.gemspec
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/fontisan/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "fontisan"
|
|
7
|
+
spec.version = Fontisan::VERSION
|
|
8
|
+
spec.authors = ["Ribose Inc."]
|
|
9
|
+
spec.email = ["open.source@ribose.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Font analysis tools and utilities for OpenType fonts"
|
|
12
|
+
spec.description = <<~HEREDOC
|
|
13
|
+
Fontisan provides font analysis tools and utilities. It is
|
|
14
|
+
designed as a pure Ruby implementation with full object-oriented architecture,
|
|
15
|
+
supporting extraction of information from OpenType and TrueType fonts (OTF, TTF, OTC, TTC).
|
|
16
|
+
|
|
17
|
+
The gem provides both a Ruby library API and a command-line interface,
|
|
18
|
+
with structured output formats (YAML, JSON, text).
|
|
19
|
+
HEREDOC
|
|
20
|
+
|
|
21
|
+
spec.homepage = "https://github.com/fontist/fontisan"
|
|
22
|
+
spec.license = "BSD-2-Clause"
|
|
23
|
+
spec.required_ruby_version = ">= 3.0.0"
|
|
24
|
+
|
|
25
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/fontist/fontisan"
|
|
27
|
+
spec.metadata["changelog_uri"] = "https://github.com/fontist/fontisan/blob/main/CHANGELOG.md"
|
|
28
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
29
|
+
|
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
32
|
+
spec.files = Dir.chdir(__dir__) do
|
|
33
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
34
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
spec.bindir = "exe"
|
|
38
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
39
|
+
spec.require_paths = ["lib"]
|
|
40
|
+
|
|
41
|
+
spec.add_dependency "base64"
|
|
42
|
+
spec.add_dependency "bindata", "~> 2.5"
|
|
43
|
+
spec.add_dependency "brotli", "~> 0.5"
|
|
44
|
+
spec.add_dependency "logger"
|
|
45
|
+
spec.add_dependency "lutaml-model", "~> 0.8"
|
|
46
|
+
spec.add_dependency "nokogiri", "~> 1.16"
|
|
47
|
+
spec.add_dependency "thor", "~> 1.3"
|
|
48
|
+
end
|
|
@@ -28,7 +28,10 @@ module Fontisan
|
|
|
28
28
|
# @param set_string [String] bracketed ICU UnicodeSet, e.g. "[a-zà]"
|
|
29
29
|
# @return [Array<Integer>] sorted, deduplicated codepoints
|
|
30
30
|
def call(set_string)
|
|
31
|
-
|
|
31
|
+
unless set_string.start_with?("[") && set_string.end_with?("]")
|
|
32
|
+
raise ParseError,
|
|
33
|
+
"input must be bracketed"
|
|
34
|
+
end
|
|
32
35
|
|
|
33
36
|
body = set_string[1..-2]
|
|
34
37
|
negate = body.start_with?("^")
|
|
@@ -125,8 +128,13 @@ module Fontisan
|
|
|
125
128
|
return nil unless chars[start + 2] == "{"
|
|
126
129
|
|
|
127
130
|
# \u{XXX...} variable hex
|
|
128
|
-
end_idx = (start + 3..).find
|
|
129
|
-
|
|
131
|
+
end_idx = (start + 3..).find do |j|
|
|
132
|
+
j >= chars.length || chars[j] == "}"
|
|
133
|
+
end
|
|
134
|
+
if end_idx.nil? || chars[end_idx] != "}"
|
|
135
|
+
raise ParseError,
|
|
136
|
+
"unclosed \\u{ escape"
|
|
137
|
+
end
|
|
130
138
|
|
|
131
139
|
hex = chars[(start + 3)...end_idx].join
|
|
132
140
|
cp = hex.to_i(16)
|
|
@@ -139,10 +147,16 @@ module Fontisan
|
|
|
139
147
|
def four_hex(chars, start, marker)
|
|
140
148
|
# \uXXXX — exactly 4 hex digits
|
|
141
149
|
hex = chars[(start + 2), 4]&.join
|
|
142
|
-
|
|
150
|
+
if hex.nil? || hex.length < 4
|
|
151
|
+
raise ParseError,
|
|
152
|
+
"truncated \\#{marker} escape"
|
|
153
|
+
end
|
|
143
154
|
|
|
144
155
|
cp = hex.to_i(16)
|
|
145
|
-
|
|
156
|
+
if cp.zero? && !hex.match?(/\A0+\z/)
|
|
157
|
+
raise ParseError,
|
|
158
|
+
"\\#{marker} escape with non-hex digits"
|
|
159
|
+
end
|
|
146
160
|
|
|
147
161
|
[cp, 6]
|
|
148
162
|
end
|
|
@@ -154,7 +168,10 @@ module Fontisan
|
|
|
154
168
|
raise ParseError, "truncated \\U escape" if hex.nil? || hex.length < 8
|
|
155
169
|
|
|
156
170
|
cp = hex.to_i(16)
|
|
157
|
-
|
|
171
|
+
if cp.zero? && !hex.match?(/\A0+\z/)
|
|
172
|
+
raise ParseError,
|
|
173
|
+
"\\U escape with non-hex digits"
|
|
174
|
+
end
|
|
158
175
|
|
|
159
176
|
[cp, 10]
|
|
160
177
|
end
|
|
@@ -9,7 +9,7 @@ module Fontisan
|
|
|
9
9
|
module Cldr
|
|
10
10
|
# Resolves a user-supplied version intent to a concrete CLDR version.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
12
|
+
# Three input modes:
|
|
13
13
|
#
|
|
14
14
|
# resolve(nil) # default_version from config
|
|
15
15
|
# resolve(:default) # default_version from config
|