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
data/lib/fontisan/cli.rb
CHANGED
|
@@ -25,93 +25,9 @@ module Fontisan
|
|
|
25
25
|
desc: "Suppress non-error output",
|
|
26
26
|
aliases: "-q"
|
|
27
27
|
|
|
28
|
-
desc "ucd", "Manage local UCD cache (subcommands)", hide: true
|
|
29
|
-
subcommand "ucd", UcdCli
|
|
30
|
-
|
|
31
28
|
desc "cldr", "Manage local CLDR cache (subcommands)", hide: true
|
|
32
29
|
subcommand "cldr", CldrCli
|
|
33
30
|
|
|
34
|
-
desc "audit PATH", "Produce a per-face font audit report, or diff/summarize"
|
|
35
|
-
long_desc <<~DESC
|
|
36
|
-
Produce a complete per-face font audit report covering identity, style,
|
|
37
|
-
metrics, coverage (Unicode blocks/scripts), licensing, hinting, color
|
|
38
|
-
capabilities, variable font detail, and OpenType layout features.
|
|
39
|
-
|
|
40
|
-
For TTC/OTC/dfont collections, one report per face is produced. Use
|
|
41
|
-
--output to write reports to disk; --font-index to audit a single face.
|
|
42
|
-
|
|
43
|
-
Variants:
|
|
44
|
-
fontisan audit FONT.ttf
|
|
45
|
-
fontisan audit COLLECTION.ttc
|
|
46
|
-
fontisan audit DIR/ --recursive --summary
|
|
47
|
-
fontisan audit --compare A.ttf B.ttf
|
|
48
|
-
fontisan audit --compare A.yaml B.yaml
|
|
49
|
-
|
|
50
|
-
Output formats: text (default), yaml, json.
|
|
51
|
-
|
|
52
|
-
Use --brief for a fast inventory pass that skips metrics, hinting,
|
|
53
|
-
color, variable-font detail, OpenType layout, and UCD/CLDR
|
|
54
|
-
aggregation — only identity, style, licensing, and codepoint coverage.
|
|
55
|
-
DESC
|
|
56
|
-
option :font_index, type: :numeric,
|
|
57
|
-
desc: "Audit only this face in a collection (default: all)"
|
|
58
|
-
option :all_codepoints, type: :boolean, default: false,
|
|
59
|
-
desc: "Include the full per-codepoint list " \
|
|
60
|
-
"(defaults to compact range view)"
|
|
61
|
-
option :ucd_version, type: :string,
|
|
62
|
-
desc: "UCD version to aggregate against " \
|
|
63
|
-
"(default: configured default; 'latest' to probe)"
|
|
64
|
-
option :with_language_coverage, type: :boolean, default: false,
|
|
65
|
-
desc: "Compute coverage % per CLDR language " \
|
|
66
|
-
"(requires CLDR cache; auto-downloads)"
|
|
67
|
-
option :cldr_version, type: :string,
|
|
68
|
-
desc: "CLDR version (default: configured default; " \
|
|
69
|
-
"'latest' to probe)"
|
|
70
|
-
option :brief, type: :boolean, default: false,
|
|
71
|
-
desc: "Skip metrics/hinting/color/layout/UCD/CLDR for a " \
|
|
72
|
-
"fast inventory pass"
|
|
73
|
-
option :compare, type: :boolean, default: false,
|
|
74
|
-
desc: "Diff two fonts or two saved reports " \
|
|
75
|
-
"(requires exactly two PATHs)"
|
|
76
|
-
option :recursive, type: :boolean, default: false,
|
|
77
|
-
desc: "Audit every font under a directory tree " \
|
|
78
|
-
"(library mode)"
|
|
79
|
-
option :summary, type: :boolean, default: false,
|
|
80
|
-
desc: "Produce a LibrarySummary over a directory of fonts"
|
|
81
|
-
option :output, type: :string,
|
|
82
|
-
desc: "Output directory (collections/library) or file " \
|
|
83
|
-
"(single font / compare)",
|
|
84
|
-
aliases: "-o"
|
|
85
|
-
# Produce a complete font audit report, or diff two fonts/reports,
|
|
86
|
-
# or summarize a whole library.
|
|
87
|
-
#
|
|
88
|
-
# @param paths [Array<String>] one path (audit/library), or two paths (--compare)
|
|
89
|
-
def audit(*paths)
|
|
90
|
-
raise Thor::Error, "audit requires one PATH (or two with --compare)" if paths.empty?
|
|
91
|
-
|
|
92
|
-
if options[:compare]
|
|
93
|
-
unless paths.length == 2
|
|
94
|
-
raise Thor::Error,
|
|
95
|
-
"audit --compare requires exactly two paths"
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
return run_compare(paths[0], paths[1])
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
raise Thor::Error, "audit requires exactly one PATH" unless paths.length == 1
|
|
102
|
-
|
|
103
|
-
path = paths[0]
|
|
104
|
-
if Dir.exist?(path) && !library_mode?(path)
|
|
105
|
-
raise Thor::Error,
|
|
106
|
-
"audit on a directory requires --recursive or --summary"
|
|
107
|
-
end
|
|
108
|
-
return run_library_audit(path) if library_mode?(path)
|
|
109
|
-
|
|
110
|
-
run_single_audit(path)
|
|
111
|
-
rescue Errno::ENOENT, Error, Thor::Error => e
|
|
112
|
-
handle_error(e)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
31
|
desc "info PATH", "Display font information"
|
|
116
32
|
option :brief, type: :boolean, default: false,
|
|
117
33
|
desc: "Brief mode - only essential info (5x faster, uses metadata loading)",
|
|
@@ -788,92 +704,6 @@ module Fontisan
|
|
|
788
704
|
puts output unless options[:quiet]
|
|
789
705
|
end
|
|
790
706
|
|
|
791
|
-
# Write audit reports to disk. If `target` is a directory (or there are
|
|
792
|
-
# multiple reports), one file per face is written under it. If `target`
|
|
793
|
-
# is a file path and there's exactly one report, that exact path is used.
|
|
794
|
-
#
|
|
795
|
-
# @param reports [Array<Models::Audit::AuditReport>]
|
|
796
|
-
# @param target [String] directory (collection) or file path (single)
|
|
797
|
-
# @param format [String] "yaml" or "json"
|
|
798
|
-
# @return [void]
|
|
799
|
-
def write_audit_outputs(reports, target, format)
|
|
800
|
-
sym_format = format.to_sym
|
|
801
|
-
|
|
802
|
-
if reports.one? && !Dir.exist?(target) && File.extname(target) != ""
|
|
803
|
-
File.write(target, serialize_report(reports.first, sym_format))
|
|
804
|
-
puts "Wrote #{target}" unless options[:quiet]
|
|
805
|
-
return
|
|
806
|
-
end
|
|
807
|
-
|
|
808
|
-
paths = Commands::AuditCommand.write_reports(reports, to: target,
|
|
809
|
-
format: sym_format)
|
|
810
|
-
paths.each { |p| puts "Wrote #{p}" unless options[:quiet] }
|
|
811
|
-
end
|
|
812
|
-
|
|
813
|
-
def run_single_audit(path)
|
|
814
|
-
cmd_options = options.dup
|
|
815
|
-
cmd_options.delete(:output)
|
|
816
|
-
# Audit's --brief selects a cheap extractor subset but still needs FULL
|
|
817
|
-
# font loading (Coverage reads cmap). Translate to :audit_brief so
|
|
818
|
-
# BaseCommand's :brief → METADATA shortcut does not fire.
|
|
819
|
-
cmd_options[:audit_brief] = cmd_options.delete(:brief) if cmd_options.key?(:brief)
|
|
820
|
-
command = Commands::AuditCommand.new(path, cmd_options)
|
|
821
|
-
reports = Array(command.run)
|
|
822
|
-
|
|
823
|
-
if options[:output]
|
|
824
|
-
write_audit_outputs(reports, options[:output], options[:format])
|
|
825
|
-
else
|
|
826
|
-
reports.each { |r| output_result(r) }
|
|
827
|
-
end
|
|
828
|
-
end
|
|
829
|
-
|
|
830
|
-
def run_compare(left_path, right_path)
|
|
831
|
-
cmd = Commands::AuditCompareCommand.new(left_path, right_path, options)
|
|
832
|
-
diff = cmd.run
|
|
833
|
-
return if options[:quiet]
|
|
834
|
-
|
|
835
|
-
if options[:output]
|
|
836
|
-
File.write(options[:output], serialize_report(diff, options[:format].to_sym))
|
|
837
|
-
puts "Wrote #{options[:output]}"
|
|
838
|
-
return
|
|
839
|
-
end
|
|
840
|
-
|
|
841
|
-
output_result(diff)
|
|
842
|
-
end
|
|
843
|
-
|
|
844
|
-
def run_library_audit(path)
|
|
845
|
-
cmd = Commands::AuditLibraryCommand.new(
|
|
846
|
-
path,
|
|
847
|
-
recursive: options[:recursive],
|
|
848
|
-
options: options.dup,
|
|
849
|
-
)
|
|
850
|
-
summary = cmd.run
|
|
851
|
-
announce_skipped(cmd.skipped)
|
|
852
|
-
return if options[:quiet]
|
|
853
|
-
|
|
854
|
-
if options[:output]
|
|
855
|
-
File.write(options[:output],
|
|
856
|
-
serialize_report(summary, options[:format].to_sym))
|
|
857
|
-
puts "Wrote #{options[:output]}"
|
|
858
|
-
return
|
|
859
|
-
end
|
|
860
|
-
|
|
861
|
-
output_result(summary)
|
|
862
|
-
end
|
|
863
|
-
|
|
864
|
-
# Library mode triggers when the path is a directory and either
|
|
865
|
-
# --recursive or --summary is requested. A single-file audit ignores
|
|
866
|
-
# both flags (a TTC is audited face-by-face via run_single_audit).
|
|
867
|
-
def library_mode?(path)
|
|
868
|
-
Dir.exist?(path) && (options[:recursive] || options[:summary])
|
|
869
|
-
end
|
|
870
|
-
|
|
871
|
-
def announce_skipped(skipped)
|
|
872
|
-
return if skipped.empty?
|
|
873
|
-
|
|
874
|
-
skipped.each { |p| warn "skipped #{p}" }
|
|
875
|
-
end
|
|
876
|
-
|
|
877
707
|
def serialize_report(report, format)
|
|
878
708
|
format == :json ? report.to_json : report.to_yaml
|
|
879
709
|
end
|
data/lib/fontisan/commands.rb
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
module Fontisan
|
|
6
6
|
module Commands
|
|
7
|
-
autoload :AuditCompareCommand, "fontisan/commands/audit_compare_command"
|
|
8
|
-
autoload :AuditCommand, "fontisan/commands/audit_command"
|
|
9
|
-
autoload :AuditLibraryCommand, "fontisan/commands/audit_library_command"
|
|
10
7
|
autoload :BaseCommand, "fontisan/commands/base_command"
|
|
11
8
|
autoload :ConvertCommand, "fontisan/commands/convert_command"
|
|
12
9
|
autoload :DumpTableCommand, "fontisan/commands/dump_table_command"
|
|
@@ -44,12 +44,6 @@ module Fontisan
|
|
|
44
44
|
format_collection_info(model)
|
|
45
45
|
when Models::CollectionBriefInfo
|
|
46
46
|
format_collection_brief_info(model)
|
|
47
|
-
when Models::Audit::AuditReport
|
|
48
|
-
Formatters::AuditTextRenderer.new(model).render
|
|
49
|
-
when Models::Audit::AuditDiff
|
|
50
|
-
Formatters::AuditDiffTextRenderer.new(model).render
|
|
51
|
-
when Models::Audit::LibrarySummary
|
|
52
|
-
Formatters::LibrarySummaryTextRenderer.new(model).render
|
|
53
47
|
else
|
|
54
48
|
model.to_s
|
|
55
49
|
end
|
data/lib/fontisan/formatters.rb
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
module Fontisan
|
|
6
6
|
module Formatters
|
|
7
|
-
autoload :AuditDiffTextRenderer, "fontisan/formatters/audit_diff_text_renderer"
|
|
8
|
-
autoload :AuditTextRenderer, "fontisan/formatters/audit_text_renderer"
|
|
9
|
-
autoload :LibrarySummaryTextRenderer, "fontisan/formatters/library_summary_text_renderer"
|
|
10
7
|
autoload :TextFormatter, "fontisan/formatters/text_formatter"
|
|
11
8
|
end
|
|
12
9
|
end
|
data/lib/fontisan/hints.rb
CHANGED
|
@@ -7,10 +7,13 @@ module Fontisan
|
|
|
7
7
|
autoload :HintConverter, "fontisan/hints/hint_converter"
|
|
8
8
|
autoload :HintValidator, "fontisan/hints/hint_validator"
|
|
9
9
|
autoload :PostScriptHintApplier, "fontisan/hints/postscript_hint_applier"
|
|
10
|
-
autoload :PostScriptHintExtractor,
|
|
10
|
+
autoload :PostScriptHintExtractor,
|
|
11
|
+
"fontisan/hints/postscript_hint_extractor"
|
|
11
12
|
autoload :TrueTypeHintApplier, "fontisan/hints/truetype_hint_applier"
|
|
12
13
|
autoload :TrueTypeHintExtractor, "fontisan/hints/truetype_hint_extractor"
|
|
13
|
-
autoload :TrueTypeInstructionAnalyzer,
|
|
14
|
-
|
|
14
|
+
autoload :TrueTypeInstructionAnalyzer,
|
|
15
|
+
"fontisan/hints/truetype_instruction_analyzer"
|
|
16
|
+
autoload :TrueTypeInstructionGenerator,
|
|
17
|
+
"fontisan/hints/truetype_instruction_generator"
|
|
15
18
|
end
|
|
16
19
|
end
|
data/lib/fontisan/models.rb
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
module Fontisan
|
|
6
6
|
module Models
|
|
7
|
-
autoload :AllScriptsFeaturesInfo,
|
|
8
|
-
|
|
7
|
+
autoload :AllScriptsFeaturesInfo,
|
|
8
|
+
"fontisan/models/all_scripts_features_info"
|
|
9
9
|
autoload :AxisInfo, "fontisan/models/variable_font_info"
|
|
10
10
|
autoload :BitmapGlyph, "fontisan/models/bitmap_glyph"
|
|
11
11
|
autoload :BitmapStrike, "fontisan/models/bitmap_strike"
|
|
@@ -13,7 +13,8 @@ module Fontisan
|
|
|
13
13
|
autoload :CollectionFontSummary, "fontisan/models/collection_font_summary"
|
|
14
14
|
autoload :CollectionInfo, "fontisan/models/collection_info"
|
|
15
15
|
autoload :CollectionListInfo, "fontisan/models/collection_list_info"
|
|
16
|
-
autoload :CollectionValidationReport,
|
|
16
|
+
autoload :CollectionValidationReport,
|
|
17
|
+
"fontisan/models/collection_validation_report"
|
|
17
18
|
autoload :Cldr, "fontisan/models/cldr"
|
|
18
19
|
autoload :ColorGlyph, "fontisan/models/color_glyph"
|
|
19
20
|
autoload :ColorLayer, "fontisan/models/color_layer"
|
|
@@ -38,7 +39,6 @@ module Fontisan
|
|
|
38
39
|
autoload :TableInfo, "fontisan/models/table_info"
|
|
39
40
|
autoload :TableSharingInfo, "fontisan/models/table_sharing_info"
|
|
40
41
|
autoload :Ttx, "fontisan/models/ttx/ttfont"
|
|
41
|
-
autoload :Ucd, "fontisan/models/ucd"
|
|
42
42
|
autoload :UnicodeMapping, "fontisan/models/unicode_mappings"
|
|
43
43
|
autoload :UnicodeMappings, "fontisan/models/unicode_mappings"
|
|
44
44
|
autoload :ValidationReport, "fontisan/models/validation_report"
|
|
@@ -6,9 +6,11 @@ module Fontisan
|
|
|
6
6
|
module Pipeline
|
|
7
7
|
module Strategies
|
|
8
8
|
autoload :BaseStrategy, "fontisan/pipeline/strategies/base_strategy"
|
|
9
|
-
autoload :InstanceStrategy,
|
|
9
|
+
autoload :InstanceStrategy,
|
|
10
|
+
"fontisan/pipeline/strategies/instance_strategy"
|
|
10
11
|
autoload :NamedStrategy, "fontisan/pipeline/strategies/named_strategy"
|
|
11
|
-
autoload :PreserveStrategy,
|
|
12
|
+
autoload :PreserveStrategy,
|
|
13
|
+
"fontisan/pipeline/strategies/preserve_strategy"
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
end
|
data/lib/fontisan/pipeline.rb
CHANGED
|
@@ -7,7 +7,8 @@ module Fontisan
|
|
|
7
7
|
autoload :FormatDetector, "fontisan/pipeline/format_detector"
|
|
8
8
|
autoload :OutputWriter, "fontisan/pipeline/output_writer"
|
|
9
9
|
autoload :Strategies, "fontisan/pipeline/strategies/base_strategy"
|
|
10
|
-
autoload :TransformationPipeline,
|
|
10
|
+
autoload :TransformationPipeline,
|
|
11
|
+
"fontisan/pipeline/transformation_pipeline"
|
|
11
12
|
autoload :VariationResolver, "fontisan/pipeline/variation_resolver"
|
|
12
13
|
end
|
|
13
14
|
end
|
data/lib/fontisan/tables/cff.rb
CHANGED
|
@@ -54,7 +54,8 @@ module Fontisan
|
|
|
54
54
|
autoload :DictBuilder, "fontisan/tables/cff/dict_builder"
|
|
55
55
|
autoload :Encoding, "fontisan/tables/cff/encoding"
|
|
56
56
|
autoload :Header, "fontisan/tables/cff/header"
|
|
57
|
-
autoload :HintOperationInjector,
|
|
57
|
+
autoload :HintOperationInjector,
|
|
58
|
+
"fontisan/tables/cff/hint_operation_injector"
|
|
58
59
|
autoload :Index, "fontisan/tables/cff/index"
|
|
59
60
|
autoload :IndexBuilder, "fontisan/tables/cff/index_builder"
|
|
60
61
|
autoload :OffsetRecalculator, "fontisan/tables/cff/offset_recalculator"
|
data/lib/fontisan/tables.rb
CHANGED
|
@@ -12,7 +12,8 @@ module Fontisan
|
|
|
12
12
|
autoload :CmapTable, "fontisan/tables/cmap_table"
|
|
13
13
|
autoload :Colr, "fontisan/tables/colr"
|
|
14
14
|
autoload :CompoundGlyph, "fontisan/tables/glyf/compound_glyph"
|
|
15
|
-
autoload :CompoundGlyphResolver,
|
|
15
|
+
autoload :CompoundGlyphResolver,
|
|
16
|
+
"fontisan/tables/glyf/compound_glyph_resolver"
|
|
16
17
|
autoload :Cpal, "fontisan/tables/cpal"
|
|
17
18
|
autoload :CurveConverter, "fontisan/tables/glyf/curve_converter"
|
|
18
19
|
autoload :Cvar, "fontisan/tables/cvar"
|
data/lib/fontisan/version.rb
CHANGED
data/lib/fontisan.rb
CHANGED
|
@@ -72,7 +72,6 @@ module Fontisan
|
|
|
72
72
|
autoload :VariationDataCorruptedError, "fontisan/error"
|
|
73
73
|
|
|
74
74
|
# Namespace hubs (each hub declares its own child autoloads)
|
|
75
|
-
autoload :Audit, "fontisan/audit"
|
|
76
75
|
autoload :Binary, "fontisan/binary"
|
|
77
76
|
autoload :Cldr, "fontisan/cldr"
|
|
78
77
|
autoload :Collection, "fontisan/collection"
|
|
@@ -89,7 +88,6 @@ module Fontisan
|
|
|
89
88
|
autoload :Svg, "fontisan/svg"
|
|
90
89
|
autoload :Tables, "fontisan/tables"
|
|
91
90
|
autoload :Type1, "fontisan/type1"
|
|
92
|
-
autoload :Ucd, "fontisan/ucd"
|
|
93
91
|
autoload :Utilities, "fontisan/utilities"
|
|
94
92
|
autoload :Utils, "fontisan/utils"
|
|
95
93
|
autoload :Validation, "fontisan/validation"
|
|
@@ -116,7 +114,6 @@ module Fontisan
|
|
|
116
114
|
autoload :TrueTypeFont, "fontisan/true_type_font"
|
|
117
115
|
autoload :TrueTypeFontExtensions, "fontisan/true_type_font_extensions"
|
|
118
116
|
autoload :Type1Font, "fontisan/type1_font"
|
|
119
|
-
autoload :UcdCli, "fontisan/cli/ucd_cli"
|
|
120
117
|
autoload :CldrCli, "fontisan/cli/cldr_cli"
|
|
121
118
|
autoload :Woff2Font, "fontisan/woff2_font"
|
|
122
119
|
autoload :WoffFont, "fontisan/woff_font"
|
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.2.
|
|
4
|
+
version: 0.2.23
|
|
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
|
|
@@ -597,18 +544,6 @@ files:
|
|
|
597
544
|
- lib/fontisan/type1/ttf_to_type1_converter.rb
|
|
598
545
|
- lib/fontisan/type1/upm_scaler.rb
|
|
599
546
|
- lib/fontisan/type1_font.rb
|
|
600
|
-
- lib/fontisan/ucd.rb
|
|
601
|
-
- lib/fontisan/ucd/aggregator.rb
|
|
602
|
-
- lib/fontisan/ucd/cache_manager.rb
|
|
603
|
-
- lib/fontisan/ucd/config.rb
|
|
604
|
-
- lib/fontisan/ucd/download_error.rb
|
|
605
|
-
- lib/fontisan/ucd/downloader.rb
|
|
606
|
-
- lib/fontisan/ucd/error.rb
|
|
607
|
-
- lib/fontisan/ucd/index.rb
|
|
608
|
-
- lib/fontisan/ucd/index_builder.rb
|
|
609
|
-
- lib/fontisan/ucd/range_entry.rb
|
|
610
|
-
- lib/fontisan/ucd/unknown_version_error.rb
|
|
611
|
-
- lib/fontisan/ucd/version_resolver.rb
|
|
612
547
|
- lib/fontisan/utilities.rb
|
|
613
548
|
- lib/fontisan/utilities/brotli_wrapper.rb
|
|
614
549
|
- lib/fontisan/utilities/checksum_calculator.rb
|
|
@@ -675,6 +610,7 @@ metadata:
|
|
|
675
610
|
source_code_uri: https://github.com/fontist/fontisan
|
|
676
611
|
changelog_uri: https://github.com/fontist/fontisan/blob/main/CHANGELOG.md
|
|
677
612
|
rubygems_mfa_required: 'true'
|
|
613
|
+
post_install_message:
|
|
678
614
|
rdoc_options: []
|
|
679
615
|
require_paths:
|
|
680
616
|
- lib
|
|
@@ -689,7 +625,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
689
625
|
- !ruby/object:Gem::Version
|
|
690
626
|
version: '0'
|
|
691
627
|
requirements: []
|
|
692
|
-
rubygems_version: 3.
|
|
628
|
+
rubygems_version: 3.5.22
|
|
629
|
+
signing_key:
|
|
693
630
|
specification_version: 4
|
|
694
631
|
summary: Font analysis tools and utilities for OpenType fonts
|
|
695
632
|
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
|