fontisan 0.2.22 → 0.3.0
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 +4 -168
- 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/stitcher/selector/codepoints.rb +29 -0
- data/lib/fontisan/stitcher/selector/gid.rb +25 -0
- data/lib/fontisan/stitcher/selector/range.rb +30 -0
- data/lib/fontisan/stitcher/selector.rb +26 -0
- data/lib/fontisan/stitcher/source.rb +97 -0
- data/lib/fontisan/stitcher.rb +182 -0
- data/lib/fontisan/stitcher_cli.rb +69 -0
- data/lib/fontisan/tables/cff.rb +2 -1
- data/lib/fontisan/tables.rb +2 -1
- data/lib/fontisan/ufo/anchor.rb +17 -0
- data/lib/fontisan/ufo/cli.rb +85 -0
- data/lib/fontisan/ufo/compile/base_compiler.rb +81 -0
- data/lib/fontisan/ufo/compile/cff.rb +224 -0
- data/lib/fontisan/ufo/compile/cmap.rb +129 -0
- data/lib/fontisan/ufo/compile/filters/cubic_to_quadratic.rb +174 -0
- data/lib/fontisan/ufo/compile/filters/decompose_components.rb +33 -0
- data/lib/fontisan/ufo/compile/filters/flatten_components.rb +22 -0
- data/lib/fontisan/ufo/compile/filters/reverse_contour_direction.rb +27 -0
- data/lib/fontisan/ufo/compile/filters.rb +57 -0
- data/lib/fontisan/ufo/compile/glyf_loca.rb +145 -0
- data/lib/fontisan/ufo/compile/head.rb +98 -0
- data/lib/fontisan/ufo/compile/hhea.rb +36 -0
- data/lib/fontisan/ufo/compile/hmtx.rb +27 -0
- data/lib/fontisan/ufo/compile/maxp.rb +57 -0
- data/lib/fontisan/ufo/compile/name.rb +79 -0
- data/lib/fontisan/ufo/compile/os2.rb +81 -0
- data/lib/fontisan/ufo/compile/otf_compiler.rb +43 -0
- data/lib/fontisan/ufo/compile/post.rb +32 -0
- data/lib/fontisan/ufo/compile/ttf_compiler.rb +69 -0
- data/lib/fontisan/ufo/compile.rb +48 -0
- data/lib/fontisan/ufo/component.rb +18 -0
- data/lib/fontisan/ufo/contour.rb +29 -0
- data/lib/fontisan/ufo/convert/from_bin_data.rb +246 -0
- data/lib/fontisan/ufo/convert.rb +18 -0
- data/lib/fontisan/ufo/data_set.rb +21 -0
- data/lib/fontisan/ufo/features.rb +17 -0
- data/lib/fontisan/ufo/font.rb +61 -0
- data/lib/fontisan/ufo/glyph.rb +421 -0
- data/lib/fontisan/ufo/guideline.rb +19 -0
- data/lib/fontisan/ufo/image.rb +16 -0
- data/lib/fontisan/ufo/image_set.rb +19 -0
- data/lib/fontisan/ufo/info.rb +79 -0
- data/lib/fontisan/ufo/kerning.rb +32 -0
- data/lib/fontisan/ufo/layer.rb +38 -0
- data/lib/fontisan/ufo/layer_set.rb +37 -0
- data/lib/fontisan/ufo/lib.rb +24 -0
- data/lib/fontisan/ufo/plist.rb +118 -0
- data/lib/fontisan/ufo/point.rb +38 -0
- data/lib/fontisan/ufo/reader.rb +144 -0
- data/lib/fontisan/ufo/transformation.rb +39 -0
- data/lib/fontisan/ufo/writer.rb +115 -0
- data/lib/fontisan/ufo.rb +44 -0
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan.rb +3 -3
- metadata +57 -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
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fontisan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-06-29 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: base64
|
|
@@ -262,29 +263,8 @@ files:
|
|
|
262
263
|
- docs/public/web-app-manifest-512x512.png
|
|
263
264
|
- docs/scripts/post-build.mjs
|
|
264
265
|
- exe/fontisan
|
|
266
|
+
- fontisan.gemspec
|
|
265
267
|
- lib/fontisan.rb
|
|
266
|
-
- lib/fontisan/audit.rb
|
|
267
|
-
- lib/fontisan/audit/codepoint_range_coalescer.rb
|
|
268
|
-
- lib/fontisan/audit/context.rb
|
|
269
|
-
- lib/fontisan/audit/differ.rb
|
|
270
|
-
- lib/fontisan/audit/extractors.rb
|
|
271
|
-
- lib/fontisan/audit/extractors/aggregations.rb
|
|
272
|
-
- lib/fontisan/audit/extractors/base.rb
|
|
273
|
-
- lib/fontisan/audit/extractors/color_capabilities.rb
|
|
274
|
-
- lib/fontisan/audit/extractors/coverage.rb
|
|
275
|
-
- lib/fontisan/audit/extractors/hinting.rb
|
|
276
|
-
- lib/fontisan/audit/extractors/identity.rb
|
|
277
|
-
- lib/fontisan/audit/extractors/language_coverage.rb
|
|
278
|
-
- lib/fontisan/audit/extractors/licensing.rb
|
|
279
|
-
- lib/fontisan/audit/extractors/metrics.rb
|
|
280
|
-
- lib/fontisan/audit/extractors/opentype_layout.rb
|
|
281
|
-
- lib/fontisan/audit/extractors/provenance.rb
|
|
282
|
-
- lib/fontisan/audit/extractors/style.rb
|
|
283
|
-
- lib/fontisan/audit/extractors/variation_detail.rb
|
|
284
|
-
- lib/fontisan/audit/library_aggregator.rb
|
|
285
|
-
- lib/fontisan/audit/library_auditor.rb
|
|
286
|
-
- lib/fontisan/audit/registry.rb
|
|
287
|
-
- lib/fontisan/audit/style_extractor.rb
|
|
288
268
|
- lib/fontisan/base_collection.rb
|
|
289
269
|
- lib/fontisan/binary.rb
|
|
290
270
|
- lib/fontisan/binary/base_record.rb
|
|
@@ -303,7 +283,6 @@ files:
|
|
|
303
283
|
- lib/fontisan/cldr/version_resolver.rb
|
|
304
284
|
- lib/fontisan/cli.rb
|
|
305
285
|
- lib/fontisan/cli/cldr_cli.rb
|
|
306
|
-
- lib/fontisan/cli/ucd_cli.rb
|
|
307
286
|
- lib/fontisan/collection.rb
|
|
308
287
|
- lib/fontisan/collection/builder.rb
|
|
309
288
|
- lib/fontisan/collection/dfont_builder.rb
|
|
@@ -313,9 +292,6 @@ files:
|
|
|
313
292
|
- lib/fontisan/collection/table_deduplicator.rb
|
|
314
293
|
- lib/fontisan/collection/writer.rb
|
|
315
294
|
- lib/fontisan/commands.rb
|
|
316
|
-
- lib/fontisan/commands/audit_command.rb
|
|
317
|
-
- lib/fontisan/commands/audit_compare_command.rb
|
|
318
|
-
- lib/fontisan/commands/audit_library_command.rb
|
|
319
295
|
- lib/fontisan/commands/base_command.rb
|
|
320
296
|
- lib/fontisan/commands/convert_command.rb
|
|
321
297
|
- lib/fontisan/commands/dump_table_command.rb
|
|
@@ -342,7 +318,6 @@ files:
|
|
|
342
318
|
- lib/fontisan/config/scripts.yml
|
|
343
319
|
- lib/fontisan/config/subset_profiles.yml
|
|
344
320
|
- lib/fontisan/config/svg_settings.yml
|
|
345
|
-
- lib/fontisan/config/ucd.yml
|
|
346
321
|
- lib/fontisan/config/variable_settings.yml
|
|
347
322
|
- lib/fontisan/config/woff2_settings.yml
|
|
348
323
|
- lib/fontisan/constants.rb
|
|
@@ -379,9 +354,6 @@ files:
|
|
|
379
354
|
- lib/fontisan/font_loader.rb
|
|
380
355
|
- lib/fontisan/font_writer.rb
|
|
381
356
|
- lib/fontisan/formatters.rb
|
|
382
|
-
- lib/fontisan/formatters/audit_diff_text_renderer.rb
|
|
383
|
-
- lib/fontisan/formatters/audit_text_renderer.rb
|
|
384
|
-
- lib/fontisan/formatters/library_summary_text_renderer.rb
|
|
385
357
|
- lib/fontisan/formatters/text_formatter.rb
|
|
386
358
|
- lib/fontisan/glyph_accessor.rb
|
|
387
359
|
- lib/fontisan/hints.rb
|
|
@@ -397,28 +369,6 @@ files:
|
|
|
397
369
|
- lib/fontisan/metrics_calculator.rb
|
|
398
370
|
- lib/fontisan/models.rb
|
|
399
371
|
- lib/fontisan/models/all_scripts_features_info.rb
|
|
400
|
-
- lib/fontisan/models/audit.rb
|
|
401
|
-
- lib/fontisan/models/audit/audit_axis.rb
|
|
402
|
-
- lib/fontisan/models/audit/audit_block.rb
|
|
403
|
-
- lib/fontisan/models/audit/audit_diff.rb
|
|
404
|
-
- lib/fontisan/models/audit/audit_report.rb
|
|
405
|
-
- lib/fontisan/models/audit/codepoint_range.rb
|
|
406
|
-
- lib/fontisan/models/audit/codepoint_set_diff.rb
|
|
407
|
-
- lib/fontisan/models/audit/color_capabilities.rb
|
|
408
|
-
- lib/fontisan/models/audit/duplicate_group.rb
|
|
409
|
-
- lib/fontisan/models/audit/embedding_type.rb
|
|
410
|
-
- lib/fontisan/models/audit/field_change.rb
|
|
411
|
-
- lib/fontisan/models/audit/fs_selection_flags.rb
|
|
412
|
-
- lib/fontisan/models/audit/gasp_range.rb
|
|
413
|
-
- lib/fontisan/models/audit/hinting.rb
|
|
414
|
-
- lib/fontisan/models/audit/library_summary.rb
|
|
415
|
-
- lib/fontisan/models/audit/licensing.rb
|
|
416
|
-
- lib/fontisan/models/audit/metrics.rb
|
|
417
|
-
- lib/fontisan/models/audit/named_instance.rb
|
|
418
|
-
- lib/fontisan/models/audit/opentype_layout.rb
|
|
419
|
-
- lib/fontisan/models/audit/script_coverage_row.rb
|
|
420
|
-
- lib/fontisan/models/audit/script_features.rb
|
|
421
|
-
- lib/fontisan/models/audit/variation_detail.rb
|
|
422
372
|
- lib/fontisan/models/bitmap_glyph.rb
|
|
423
373
|
- lib/fontisan/models/bitmap_strike.rb
|
|
424
374
|
- lib/fontisan/models/cldr.rb
|
|
@@ -456,9 +406,6 @@ files:
|
|
|
456
406
|
- lib/fontisan/models/ttx/tables/os2_table.rb
|
|
457
407
|
- lib/fontisan/models/ttx/tables/post_table.rb
|
|
458
408
|
- lib/fontisan/models/ttx/ttfont.rb
|
|
459
|
-
- lib/fontisan/models/ucd.rb
|
|
460
|
-
- lib/fontisan/models/ucd/ucd.rb
|
|
461
|
-
- lib/fontisan/models/ucd/ucd_char.rb
|
|
462
409
|
- lib/fontisan/models/unicode_mappings.rb
|
|
463
410
|
- lib/fontisan/models/validation_report.rb
|
|
464
411
|
- lib/fontisan/models/variable_font_info.rb
|
|
@@ -488,6 +435,13 @@ files:
|
|
|
488
435
|
- lib/fontisan/pipeline/variation_resolver.rb
|
|
489
436
|
- lib/fontisan/sfnt_font.rb
|
|
490
437
|
- lib/fontisan/sfnt_table.rb
|
|
438
|
+
- lib/fontisan/stitcher.rb
|
|
439
|
+
- lib/fontisan/stitcher/selector.rb
|
|
440
|
+
- lib/fontisan/stitcher/selector/codepoints.rb
|
|
441
|
+
- lib/fontisan/stitcher/selector/gid.rb
|
|
442
|
+
- lib/fontisan/stitcher/selector/range.rb
|
|
443
|
+
- lib/fontisan/stitcher/source.rb
|
|
444
|
+
- lib/fontisan/stitcher_cli.rb
|
|
491
445
|
- lib/fontisan/subset.rb
|
|
492
446
|
- lib/fontisan/subset/builder.rb
|
|
493
447
|
- lib/fontisan/subset/glyph_mapping.rb
|
|
@@ -597,18 +551,49 @@ files:
|
|
|
597
551
|
- lib/fontisan/type1/ttf_to_type1_converter.rb
|
|
598
552
|
- lib/fontisan/type1/upm_scaler.rb
|
|
599
553
|
- lib/fontisan/type1_font.rb
|
|
600
|
-
- lib/fontisan/
|
|
601
|
-
- lib/fontisan/
|
|
602
|
-
- lib/fontisan/
|
|
603
|
-
- lib/fontisan/
|
|
604
|
-
- lib/fontisan/
|
|
605
|
-
- lib/fontisan/
|
|
606
|
-
- lib/fontisan/
|
|
607
|
-
- lib/fontisan/
|
|
608
|
-
- lib/fontisan/
|
|
609
|
-
- lib/fontisan/
|
|
610
|
-
- lib/fontisan/
|
|
611
|
-
- lib/fontisan/
|
|
554
|
+
- lib/fontisan/ufo.rb
|
|
555
|
+
- lib/fontisan/ufo/anchor.rb
|
|
556
|
+
- lib/fontisan/ufo/cli.rb
|
|
557
|
+
- lib/fontisan/ufo/compile.rb
|
|
558
|
+
- lib/fontisan/ufo/compile/base_compiler.rb
|
|
559
|
+
- lib/fontisan/ufo/compile/cff.rb
|
|
560
|
+
- lib/fontisan/ufo/compile/cmap.rb
|
|
561
|
+
- lib/fontisan/ufo/compile/filters.rb
|
|
562
|
+
- lib/fontisan/ufo/compile/filters/cubic_to_quadratic.rb
|
|
563
|
+
- lib/fontisan/ufo/compile/filters/decompose_components.rb
|
|
564
|
+
- lib/fontisan/ufo/compile/filters/flatten_components.rb
|
|
565
|
+
- lib/fontisan/ufo/compile/filters/reverse_contour_direction.rb
|
|
566
|
+
- lib/fontisan/ufo/compile/glyf_loca.rb
|
|
567
|
+
- lib/fontisan/ufo/compile/head.rb
|
|
568
|
+
- lib/fontisan/ufo/compile/hhea.rb
|
|
569
|
+
- lib/fontisan/ufo/compile/hmtx.rb
|
|
570
|
+
- lib/fontisan/ufo/compile/maxp.rb
|
|
571
|
+
- lib/fontisan/ufo/compile/name.rb
|
|
572
|
+
- lib/fontisan/ufo/compile/os2.rb
|
|
573
|
+
- lib/fontisan/ufo/compile/otf_compiler.rb
|
|
574
|
+
- lib/fontisan/ufo/compile/post.rb
|
|
575
|
+
- lib/fontisan/ufo/compile/ttf_compiler.rb
|
|
576
|
+
- lib/fontisan/ufo/component.rb
|
|
577
|
+
- lib/fontisan/ufo/contour.rb
|
|
578
|
+
- lib/fontisan/ufo/convert.rb
|
|
579
|
+
- lib/fontisan/ufo/convert/from_bin_data.rb
|
|
580
|
+
- lib/fontisan/ufo/data_set.rb
|
|
581
|
+
- lib/fontisan/ufo/features.rb
|
|
582
|
+
- lib/fontisan/ufo/font.rb
|
|
583
|
+
- lib/fontisan/ufo/glyph.rb
|
|
584
|
+
- lib/fontisan/ufo/guideline.rb
|
|
585
|
+
- lib/fontisan/ufo/image.rb
|
|
586
|
+
- lib/fontisan/ufo/image_set.rb
|
|
587
|
+
- lib/fontisan/ufo/info.rb
|
|
588
|
+
- lib/fontisan/ufo/kerning.rb
|
|
589
|
+
- lib/fontisan/ufo/layer.rb
|
|
590
|
+
- lib/fontisan/ufo/layer_set.rb
|
|
591
|
+
- lib/fontisan/ufo/lib.rb
|
|
592
|
+
- lib/fontisan/ufo/plist.rb
|
|
593
|
+
- lib/fontisan/ufo/point.rb
|
|
594
|
+
- lib/fontisan/ufo/reader.rb
|
|
595
|
+
- lib/fontisan/ufo/transformation.rb
|
|
596
|
+
- lib/fontisan/ufo/writer.rb
|
|
612
597
|
- lib/fontisan/utilities.rb
|
|
613
598
|
- lib/fontisan/utilities/brotli_wrapper.rb
|
|
614
599
|
- lib/fontisan/utilities/checksum_calculator.rb
|
|
@@ -675,6 +660,7 @@ metadata:
|
|
|
675
660
|
source_code_uri: https://github.com/fontist/fontisan
|
|
676
661
|
changelog_uri: https://github.com/fontist/fontisan/blob/main/CHANGELOG.md
|
|
677
662
|
rubygems_mfa_required: 'true'
|
|
663
|
+
post_install_message:
|
|
678
664
|
rdoc_options: []
|
|
679
665
|
require_paths:
|
|
680
666
|
- lib
|
|
@@ -689,7 +675,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
689
675
|
- !ruby/object:Gem::Version
|
|
690
676
|
version: '0'
|
|
691
677
|
requirements: []
|
|
692
|
-
rubygems_version: 3.
|
|
678
|
+
rubygems_version: 3.5.22
|
|
679
|
+
signing_key:
|
|
693
680
|
specification_version: 4
|
|
694
681
|
summary: Font analysis tools and utilities for OpenType fonts
|
|
695
682
|
test_files: []
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Fontisan
|
|
4
|
-
module Audit
|
|
5
|
-
# Coalesces a flat codepoint list into contiguous {Models::Audit::CodepointRange}s.
|
|
6
|
-
#
|
|
7
|
-
# Single static call site, deterministic output. Used by the Coverage
|
|
8
|
-
# extractor to produce the compact range view that is the default
|
|
9
|
-
# AuditReport shape.
|
|
10
|
-
module CodepointRangeCoalescer
|
|
11
|
-
module_function
|
|
12
|
-
|
|
13
|
-
# @param codepoints [Enumerable<Integer>] any enumeration of integers
|
|
14
|
-
# @return [Array<Models::Audit::CodepointRange>] contiguous, sorted
|
|
15
|
-
def call(codepoints)
|
|
16
|
-
return [] if codepoints.nil? || codepoints.empty?
|
|
17
|
-
|
|
18
|
-
sorted = codepoints.sort.uniq
|
|
19
|
-
ranges = []
|
|
20
|
-
range_start = sorted[0]
|
|
21
|
-
prev = sorted[0]
|
|
22
|
-
|
|
23
|
-
sorted[1..].each do |cp|
|
|
24
|
-
next if cp == prev # defensive: .uniq already handles this
|
|
25
|
-
|
|
26
|
-
if cp == prev + 1
|
|
27
|
-
prev = cp
|
|
28
|
-
else
|
|
29
|
-
ranges << Models::Audit::CodepointRange.new(first_cp: range_start,
|
|
30
|
-
last_cp: prev)
|
|
31
|
-
range_start = cp
|
|
32
|
-
prev = cp
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
ranges << Models::Audit::CodepointRange.new(first_cp: range_start,
|
|
36
|
-
last_cp: prev)
|
|
37
|
-
ranges
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Fontisan
|
|
4
|
-
module Audit
|
|
5
|
-
# Value object carrying everything an extractor needs to do its job.
|
|
6
|
-
#
|
|
7
|
-
# Extractors never reach back into AuditCommand state — they read
|
|
8
|
-
# exclusively from the Context. Shared derived data (codepoints,
|
|
9
|
-
# UCD indices, source format) is memoized here so multiple
|
|
10
|
-
# extractors don't recompute it.
|
|
11
|
-
class Context
|
|
12
|
-
attr_reader :font, :font_path, :font_index, :num_fonts_in_source,
|
|
13
|
-
:options
|
|
14
|
-
|
|
15
|
-
def initialize(font:, font_path:, font_index:, num_fonts_in_source:,
|
|
16
|
-
options:)
|
|
17
|
-
@font = font
|
|
18
|
-
@font_path = font_path
|
|
19
|
-
@font_index = font_index
|
|
20
|
-
@num_fonts_in_source = num_fonts_in_source
|
|
21
|
-
@options = options
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def codepoints
|
|
25
|
-
@codepoints ||= extract_codepoints
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def ucd
|
|
29
|
-
@ucd ||= resolve_ucd
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def cldr
|
|
33
|
-
return nil unless @options[:with_language_coverage]
|
|
34
|
-
|
|
35
|
-
@cldr ||= resolve_cldr
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def source_format
|
|
39
|
-
@source_format ||= FontLoader.detect_format(@font_path)&.to_s
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def all_codepoints?
|
|
43
|
-
@options[:all_codepoints] == true
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def extract_codepoints
|
|
49
|
-
return [] unless @font.has_table?(Constants::CMAP_TAG)
|
|
50
|
-
|
|
51
|
-
@font.table(Constants::CMAP_TAG).unicode_mappings.keys
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def resolve_ucd
|
|
55
|
-
version = Ucd::VersionResolver.resolve(@options[:ucd_version])
|
|
56
|
-
|
|
57
|
-
with_local_indices(version) do |blocks_path, scripts_path|
|
|
58
|
-
{
|
|
59
|
-
version: version,
|
|
60
|
-
blocks_index: Ucd::Index.load(blocks_path),
|
|
61
|
-
scripts_index: Ucd::Index.load(scripts_path),
|
|
62
|
-
warning: nil,
|
|
63
|
-
}
|
|
64
|
-
end
|
|
65
|
-
rescue Ucd::UnknownVersionError => e
|
|
66
|
-
{ version: nil, blocks_index: nil, scripts_index: nil,
|
|
67
|
-
warning: "UCD version rejected: #{e.message}" }
|
|
68
|
-
rescue StandardError => e
|
|
69
|
-
version_ref = @ucd&.fetch(:version, nil)
|
|
70
|
-
{
|
|
71
|
-
version: version_ref,
|
|
72
|
-
blocks_index: nil,
|
|
73
|
-
scripts_index: nil,
|
|
74
|
-
warning: "UCD unavailable for version #{version_ref}: #{e.message}",
|
|
75
|
-
}
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def with_local_indices(version)
|
|
79
|
-
unless Ucd::CacheManager.cached?(version)
|
|
80
|
-
Ucd::Downloader.download(version)
|
|
81
|
-
end
|
|
82
|
-
unless Ucd::CacheManager.blocks_index_path(version).exist?
|
|
83
|
-
Ucd::IndexBuilder.build(version)
|
|
84
|
-
end
|
|
85
|
-
yield Ucd::CacheManager.blocks_index_path(version),
|
|
86
|
-
Ucd::CacheManager.scripts_index_path(version)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def resolve_cldr
|
|
90
|
-
version = Cldr::VersionResolver.resolve(@options[:cldr_version])
|
|
91
|
-
|
|
92
|
-
with_local_languages_index(version) do |index_path|
|
|
93
|
-
{
|
|
94
|
-
version: version,
|
|
95
|
-
index: Cldr::Index.load(index_path),
|
|
96
|
-
warning: nil,
|
|
97
|
-
}
|
|
98
|
-
end
|
|
99
|
-
rescue Cldr::UnknownVersionError => e
|
|
100
|
-
{ version: nil, index: nil,
|
|
101
|
-
warning: "CLDR version rejected: #{e.message}" }
|
|
102
|
-
rescue StandardError => e
|
|
103
|
-
version_ref = @cldr&.fetch(:version, nil)
|
|
104
|
-
{
|
|
105
|
-
version: version_ref,
|
|
106
|
-
index: nil,
|
|
107
|
-
warning: "CLDR unavailable for version #{version_ref}: #{e.message}",
|
|
108
|
-
}
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def with_local_languages_index(version)
|
|
112
|
-
unless Cldr::CacheManager.cached?(version)
|
|
113
|
-
Cldr::Downloader.download(version)
|
|
114
|
-
end
|
|
115
|
-
unless Cldr::CacheManager.languages_index_path(version).exist?
|
|
116
|
-
Cldr::IndexBuilder.build(version)
|
|
117
|
-
end
|
|
118
|
-
yield Cldr::CacheManager.languages_index_path(version)
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Fontisan
|
|
4
|
-
module Audit
|
|
5
|
-
# Computes an {Models::Audit::AuditDiff} between two AuditReports.
|
|
6
|
-
#
|
|
7
|
-
# Pure: no I/O, no font parsing. Both reports must already be built
|
|
8
|
-
# (Commands::AuditCompareCommand handles loading reports from disk
|
|
9
|
-
# or auditing fresh fonts before invoking the differ).
|
|
10
|
-
#
|
|
11
|
-
# Comparison shape:
|
|
12
|
-
# - Scalar fields: one FieldChange per differing field.
|
|
13
|
-
# - Codepoint coverage: CodepointSetDiff built from the cmap range
|
|
14
|
-
# lists (expanded to integer sets for set arithmetic, then
|
|
15
|
-
# re-coalesced to ranges for output).
|
|
16
|
-
# - Structural inventories (features, scripts, blocks, languages):
|
|
17
|
-
# simple array set-diffs.
|
|
18
|
-
class Differ
|
|
19
|
-
# Scalar AuditReport fields compared field-by-field. Excludes
|
|
20
|
-
# generated_at / source_sha256 / source_file (per-report identity),
|
|
21
|
-
# codepoints / codepoint_ranges (handled via CodepointSetDiff),
|
|
22
|
-
# and nested models (surfaced via structural add/remove lists).
|
|
23
|
-
COMPARED_FIELDS = %i[
|
|
24
|
-
family_name subfamily_name full_name postscript_name version
|
|
25
|
-
font_revision weight_class width_class italic bold panose
|
|
26
|
-
total_codepoints total_glyphs ucd_version cldr_version
|
|
27
|
-
].freeze
|
|
28
|
-
|
|
29
|
-
def initialize(left_report, right_report)
|
|
30
|
-
@left = left_report
|
|
31
|
-
@right = right_report
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# @return [Models::Audit::AuditDiff]
|
|
35
|
-
def diff
|
|
36
|
-
Models::Audit::AuditDiff.new(
|
|
37
|
-
left_source: @left.source_file,
|
|
38
|
-
right_source: @right.source_file,
|
|
39
|
-
field_changes: field_changes,
|
|
40
|
-
codepoints: codepoint_diff,
|
|
41
|
-
added_features: set_diff(features(@right), features(@left)),
|
|
42
|
-
removed_features: set_diff(features(@left), features(@right)),
|
|
43
|
-
added_scripts: set_diff(scripts(@right), scripts(@left)),
|
|
44
|
-
removed_scripts: set_diff(scripts(@left), scripts(@right)),
|
|
45
|
-
added_blocks: set_diff(blocks(@right), blocks(@left)),
|
|
46
|
-
removed_blocks: set_diff(blocks(@left), blocks(@right)),
|
|
47
|
-
added_languages: set_diff(languages(@right), languages(@left)),
|
|
48
|
-
removed_languages: set_diff(languages(@left), languages(@right)),
|
|
49
|
-
)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
def field_changes
|
|
55
|
-
COMPARED_FIELDS.filter_map do |field|
|
|
56
|
-
left_val = @left.public_send(field)
|
|
57
|
-
right_val = @right.public_send(field)
|
|
58
|
-
next if left_val == right_val
|
|
59
|
-
|
|
60
|
-
Models::Audit::FieldChange.new(
|
|
61
|
-
field: field.to_s,
|
|
62
|
-
left: serialize_value(left_val),
|
|
63
|
-
right: serialize_value(right_val),
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def codepoint_diff
|
|
69
|
-
left_set = codepoints_from_ranges(@left)
|
|
70
|
-
right_set = codepoints_from_ranges(@right)
|
|
71
|
-
added = right_set - left_set
|
|
72
|
-
removed = left_set - right_set
|
|
73
|
-
unchanged = left_set & right_set
|
|
74
|
-
|
|
75
|
-
Models::Audit::CodepointSetDiff.new(
|
|
76
|
-
added: CodepointRangeCoalescer.call(added.to_a),
|
|
77
|
-
removed: CodepointRangeCoalescer.call(removed.to_a),
|
|
78
|
-
added_count: added.size,
|
|
79
|
-
removed_count: removed.size,
|
|
80
|
-
unchanged_count: unchanged.size,
|
|
81
|
-
)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Expand a report's compact codepoint range list into a Set<Integer>.
|
|
85
|
-
# Works for both default reports (range list populated) and
|
|
86
|
-
# --all-codepoints reports (range list is also populated).
|
|
87
|
-
def codepoints_from_ranges(report)
|
|
88
|
-
ranges = report.codepoint_ranges || []
|
|
89
|
-
ranges.each_with_object(Set.new) do |range, set|
|
|
90
|
-
(range.first_cp..range.last_cp).each { |cp| set << cp }
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def features(report)
|
|
95
|
-
report.opentype_layout&.features || []
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def scripts(report)
|
|
99
|
-
report.opentype_layout&.scripts || []
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def blocks(report)
|
|
103
|
-
(report.blocks || []).map(&:name)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def languages(report)
|
|
107
|
-
(report.language_coverage || []).map(&:language)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def set_diff(minuend, subtrahend)
|
|
111
|
-
(Array(minuend) - Array(subtrahend)).sort
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def serialize_value(value)
|
|
115
|
-
case value
|
|
116
|
-
when nil then ""
|
|
117
|
-
when String, Integer, Float then value.to_s
|
|
118
|
-
when true, false then value.to_s
|
|
119
|
-
else value.to_yaml
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Fontisan
|
|
4
|
-
module Audit
|
|
5
|
-
module Extractors
|
|
6
|
-
# Aggregation fields: UCD block/script coverage.
|
|
7
|
-
#
|
|
8
|
-
# Returned fields:
|
|
9
|
-
# ucd_version, blocks, unicode_scripts
|
|
10
|
-
#
|
|
11
|
-
# OpenType script/feature inventory lives in {Extractors::OpenTypeLayout}
|
|
12
|
-
# (MECE: this extractor is UCD-driven, that one is SFNT-table-driven).
|
|
13
|
-
class Aggregations < Base
|
|
14
|
-
def extract(context)
|
|
15
|
-
ucd = context.ucd
|
|
16
|
-
ucd_aggregations(context.codepoints, ucd)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def ucd_aggregations(codepoints, ucd)
|
|
22
|
-
return empty_aggregation(ucd) if ucd[:blocks_index].nil?
|
|
23
|
-
|
|
24
|
-
blocks_hashes = Ucd::Aggregator.aggregate_blocks(codepoints,
|
|
25
|
-
ucd[:blocks_index])
|
|
26
|
-
{
|
|
27
|
-
ucd_version: ucd[:version],
|
|
28
|
-
blocks: blocks_hashes.map { |h| build_audit_block(h) },
|
|
29
|
-
unicode_scripts: Ucd::Aggregator.aggregate_scripts(codepoints,
|
|
30
|
-
ucd[:scripts_index]),
|
|
31
|
-
}
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def empty_aggregation(ucd)
|
|
35
|
-
{ ucd_version: ucd[:version], blocks: [], unicode_scripts: [] }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def build_audit_block(block_hash)
|
|
39
|
-
Models::Audit::AuditBlock.new(
|
|
40
|
-
name: block_hash[:name],
|
|
41
|
-
first_cp: block_hash[:first_cp],
|
|
42
|
-
last_cp: block_hash[:last_cp],
|
|
43
|
-
range: format("U+%<first>04X-U+%<last>04X",
|
|
44
|
-
first: block_hash[:first_cp], last: block_hash[:last_cp]),
|
|
45
|
-
total: block_hash[:total],
|
|
46
|
-
covered: block_hash[:covered],
|
|
47
|
-
fill_ratio: block_hash[:fill_ratio],
|
|
48
|
-
complete: block_hash[:complete],
|
|
49
|
-
)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Fontisan
|
|
4
|
-
module Audit
|
|
5
|
-
module Extractors
|
|
6
|
-
# Abstract extractor interface. Subclasses implement `#extract`.
|
|
7
|
-
#
|
|
8
|
-
# An extractor reads from a Context and returns a hash of fields
|
|
9
|
-
# suitable for `Models::Audit::AuditReport.new(**fields)`.
|
|
10
|
-
# Returning an empty hash is valid (no-op).
|
|
11
|
-
class Base
|
|
12
|
-
def extract(context)
|
|
13
|
-
raise NotImplementedError,
|
|
14
|
-
"#{self.class} must implement #extract"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
protected
|
|
18
|
-
|
|
19
|
-
# Convenience accessor used by most extractors.
|
|
20
|
-
def font(context)
|
|
21
|
-
context.font
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|