fontisan 0.1.0 → 0.2.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_todo.yml +529 -65
- data/Gemfile +1 -0
- data/LICENSE +5 -1
- data/README.adoc +1301 -275
- data/Rakefile +27 -2
- data/benchmark/variation_quick_bench.rb +47 -0
- data/docs/EXTRACT_TTC_MIGRATION.md +549 -0
- data/fontisan.gemspec +4 -1
- data/lib/fontisan/binary/base_record.rb +22 -1
- data/lib/fontisan/cli.rb +309 -0
- data/lib/fontisan/collection/builder.rb +260 -0
- data/lib/fontisan/collection/offset_calculator.rb +227 -0
- data/lib/fontisan/collection/table_analyzer.rb +204 -0
- data/lib/fontisan/collection/table_deduplicator.rb +241 -0
- data/lib/fontisan/collection/writer.rb +306 -0
- data/lib/fontisan/commands/base_command.rb +8 -1
- data/lib/fontisan/commands/convert_command.rb +291 -0
- data/lib/fontisan/commands/export_command.rb +161 -0
- data/lib/fontisan/commands/info_command.rb +40 -6
- data/lib/fontisan/commands/instance_command.rb +295 -0
- data/lib/fontisan/commands/ls_command.rb +113 -0
- data/lib/fontisan/commands/pack_command.rb +241 -0
- data/lib/fontisan/commands/subset_command.rb +245 -0
- data/lib/fontisan/commands/unpack_command.rb +338 -0
- data/lib/fontisan/commands/validate_command.rb +178 -0
- data/lib/fontisan/commands/variable_command.rb +30 -1
- data/lib/fontisan/config/collection_settings.yml +56 -0
- data/lib/fontisan/config/conversion_matrix.yml +212 -0
- data/lib/fontisan/config/export_settings.yml +66 -0
- data/lib/fontisan/config/subset_profiles.yml +100 -0
- data/lib/fontisan/config/svg_settings.yml +60 -0
- data/lib/fontisan/config/validation_rules.yml +149 -0
- data/lib/fontisan/config/variable_settings.yml +99 -0
- data/lib/fontisan/config/woff2_settings.yml +77 -0
- data/lib/fontisan/constants.rb +69 -0
- data/lib/fontisan/converters/conversion_strategy.rb +96 -0
- data/lib/fontisan/converters/format_converter.rb +259 -0
- data/lib/fontisan/converters/outline_converter.rb +936 -0
- data/lib/fontisan/converters/svg_generator.rb +244 -0
- data/lib/fontisan/converters/table_copier.rb +117 -0
- data/lib/fontisan/converters/woff2_encoder.rb +416 -0
- data/lib/fontisan/converters/woff_writer.rb +391 -0
- data/lib/fontisan/error.rb +203 -0
- data/lib/fontisan/export/exporter.rb +262 -0
- data/lib/fontisan/export/table_serializer.rb +255 -0
- data/lib/fontisan/export/transformers/font_to_ttx.rb +172 -0
- data/lib/fontisan/export/transformers/head_transformer.rb +96 -0
- data/lib/fontisan/export/transformers/hhea_transformer.rb +59 -0
- data/lib/fontisan/export/transformers/maxp_transformer.rb +63 -0
- data/lib/fontisan/export/transformers/name_transformer.rb +63 -0
- data/lib/fontisan/export/transformers/os2_transformer.rb +121 -0
- data/lib/fontisan/export/transformers/post_transformer.rb +51 -0
- data/lib/fontisan/export/ttx_generator.rb +527 -0
- data/lib/fontisan/export/ttx_parser.rb +300 -0
- data/lib/fontisan/font_loader.rb +121 -12
- data/lib/fontisan/font_writer.rb +301 -0
- data/lib/fontisan/formatters/text_formatter.rb +102 -0
- data/lib/fontisan/glyph_accessor.rb +503 -0
- data/lib/fontisan/hints/hint_converter.rb +177 -0
- data/lib/fontisan/hints/postscript_hint_applier.rb +185 -0
- data/lib/fontisan/hints/postscript_hint_extractor.rb +254 -0
- data/lib/fontisan/hints/truetype_hint_applier.rb +71 -0
- data/lib/fontisan/hints/truetype_hint_extractor.rb +162 -0
- data/lib/fontisan/loading_modes.rb +113 -0
- data/lib/fontisan/metrics_calculator.rb +277 -0
- data/lib/fontisan/models/collection_font_summary.rb +52 -0
- data/lib/fontisan/models/collection_info.rb +76 -0
- data/lib/fontisan/models/collection_list_info.rb +37 -0
- data/lib/fontisan/models/font_export.rb +158 -0
- data/lib/fontisan/models/font_summary.rb +48 -0
- data/lib/fontisan/models/glyph_outline.rb +343 -0
- data/lib/fontisan/models/hint.rb +233 -0
- data/lib/fontisan/models/outline.rb +664 -0
- data/lib/fontisan/models/table_sharing_info.rb +40 -0
- data/lib/fontisan/models/ttx/glyph_order.rb +31 -0
- data/lib/fontisan/models/ttx/tables/binary_table.rb +67 -0
- data/lib/fontisan/models/ttx/tables/head_table.rb +74 -0
- data/lib/fontisan/models/ttx/tables/hhea_table.rb +74 -0
- data/lib/fontisan/models/ttx/tables/maxp_table.rb +55 -0
- data/lib/fontisan/models/ttx/tables/name_table.rb +45 -0
- data/lib/fontisan/models/ttx/tables/os2_table.rb +157 -0
- data/lib/fontisan/models/ttx/tables/post_table.rb +50 -0
- data/lib/fontisan/models/ttx/ttfont.rb +49 -0
- data/lib/fontisan/models/validation_report.rb +203 -0
- data/lib/fontisan/open_type_collection.rb +156 -2
- data/lib/fontisan/open_type_font.rb +296 -10
- data/lib/fontisan/optimizers/charstring_rewriter.rb +161 -0
- data/lib/fontisan/optimizers/pattern_analyzer.rb +308 -0
- data/lib/fontisan/optimizers/stack_tracker.rb +246 -0
- data/lib/fontisan/optimizers/subroutine_builder.rb +134 -0
- data/lib/fontisan/optimizers/subroutine_generator.rb +207 -0
- data/lib/fontisan/optimizers/subroutine_optimizer.rb +107 -0
- data/lib/fontisan/outline_extractor.rb +423 -0
- data/lib/fontisan/subset/builder.rb +268 -0
- data/lib/fontisan/subset/glyph_mapping.rb +215 -0
- data/lib/fontisan/subset/options.rb +142 -0
- data/lib/fontisan/subset/profile.rb +152 -0
- data/lib/fontisan/subset/table_subsetter.rb +461 -0
- data/lib/fontisan/svg/font_face_generator.rb +278 -0
- data/lib/fontisan/svg/font_generator.rb +264 -0
- data/lib/fontisan/svg/glyph_generator.rb +168 -0
- data/lib/fontisan/svg/view_box_calculator.rb +137 -0
- data/lib/fontisan/tables/cff/cff_glyph.rb +176 -0
- data/lib/fontisan/tables/cff/charset.rb +282 -0
- data/lib/fontisan/tables/cff/charstring.rb +905 -0
- data/lib/fontisan/tables/cff/charstring_builder.rb +322 -0
- data/lib/fontisan/tables/cff/charstrings_index.rb +162 -0
- data/lib/fontisan/tables/cff/dict.rb +351 -0
- data/lib/fontisan/tables/cff/dict_builder.rb +242 -0
- data/lib/fontisan/tables/cff/encoding.rb +274 -0
- data/lib/fontisan/tables/cff/header.rb +102 -0
- data/lib/fontisan/tables/cff/index.rb +237 -0
- data/lib/fontisan/tables/cff/index_builder.rb +170 -0
- data/lib/fontisan/tables/cff/private_dict.rb +284 -0
- data/lib/fontisan/tables/cff/top_dict.rb +236 -0
- data/lib/fontisan/tables/cff.rb +487 -0
- data/lib/fontisan/tables/cff2/blend_operator.rb +240 -0
- data/lib/fontisan/tables/cff2/charstring_parser.rb +591 -0
- data/lib/fontisan/tables/cff2/operand_stack.rb +232 -0
- data/lib/fontisan/tables/cff2.rb +341 -0
- data/lib/fontisan/tables/cvar.rb +242 -0
- data/lib/fontisan/tables/fvar.rb +2 -2
- data/lib/fontisan/tables/glyf/compound_glyph.rb +483 -0
- data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +136 -0
- data/lib/fontisan/tables/glyf/curve_converter.rb +343 -0
- data/lib/fontisan/tables/glyf/glyph_builder.rb +450 -0
- data/lib/fontisan/tables/glyf/simple_glyph.rb +382 -0
- data/lib/fontisan/tables/glyf.rb +235 -0
- data/lib/fontisan/tables/gvar.rb +270 -0
- data/lib/fontisan/tables/hhea.rb +124 -0
- data/lib/fontisan/tables/hmtx.rb +287 -0
- data/lib/fontisan/tables/hvar.rb +191 -0
- data/lib/fontisan/tables/loca.rb +322 -0
- data/lib/fontisan/tables/maxp.rb +192 -0
- data/lib/fontisan/tables/mvar.rb +185 -0
- data/lib/fontisan/tables/name.rb +99 -30
- data/lib/fontisan/tables/variation_common.rb +346 -0
- data/lib/fontisan/tables/vvar.rb +234 -0
- data/lib/fontisan/true_type_collection.rb +156 -2
- data/lib/fontisan/true_type_font.rb +297 -11
- data/lib/fontisan/utilities/brotli_wrapper.rb +159 -0
- data/lib/fontisan/utilities/checksum_calculator.rb +18 -0
- data/lib/fontisan/utils/thread_pool.rb +134 -0
- data/lib/fontisan/validation/checksum_validator.rb +170 -0
- data/lib/fontisan/validation/consistency_validator.rb +197 -0
- data/lib/fontisan/validation/structure_validator.rb +198 -0
- data/lib/fontisan/validation/table_validator.rb +158 -0
- data/lib/fontisan/validation/validator.rb +152 -0
- data/lib/fontisan/variable/axis_normalizer.rb +215 -0
- data/lib/fontisan/variable/delta_applicator.rb +313 -0
- data/lib/fontisan/variable/glyph_delta_processor.rb +218 -0
- data/lib/fontisan/variable/instancer.rb +344 -0
- data/lib/fontisan/variable/metric_delta_processor.rb +282 -0
- data/lib/fontisan/variable/region_matcher.rb +208 -0
- data/lib/fontisan/variable/static_font_builder.rb +213 -0
- data/lib/fontisan/variable/table_updater.rb +219 -0
- data/lib/fontisan/variation/blend_applier.rb +199 -0
- data/lib/fontisan/variation/cache.rb +298 -0
- data/lib/fontisan/variation/cache_key_builder.rb +162 -0
- data/lib/fontisan/variation/converter.rb +268 -0
- data/lib/fontisan/variation/data_extractor.rb +86 -0
- data/lib/fontisan/variation/delta_applier.rb +266 -0
- data/lib/fontisan/variation/delta_parser.rb +228 -0
- data/lib/fontisan/variation/inspector.rb +275 -0
- data/lib/fontisan/variation/instance_generator.rb +273 -0
- data/lib/fontisan/variation/interpolator.rb +231 -0
- data/lib/fontisan/variation/metrics_adjuster.rb +318 -0
- data/lib/fontisan/variation/optimizer.rb +418 -0
- data/lib/fontisan/variation/parallel_generator.rb +150 -0
- data/lib/fontisan/variation/region_matcher.rb +221 -0
- data/lib/fontisan/variation/subsetter.rb +463 -0
- data/lib/fontisan/variation/table_accessor.rb +105 -0
- data/lib/fontisan/variation/validator.rb +345 -0
- data/lib/fontisan/variation/variation_context.rb +211 -0
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan/woff2/directory.rb +257 -0
- data/lib/fontisan/woff2/header.rb +101 -0
- data/lib/fontisan/woff2/table_transformer.rb +163 -0
- data/lib/fontisan/woff2_font.rb +712 -0
- data/lib/fontisan/woff_font.rb +483 -0
- data/lib/fontisan.rb +120 -0
- data/scripts/compare_stack_aware.rb +187 -0
- data/scripts/measure_optimization.rb +141 -0
- metadata +205 -4
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Comparison script for stack-aware vs normal subroutine optimization
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ruby scripts/compare_stack_aware.rb [font_path]
|
|
8
|
+
#
|
|
9
|
+
# If no font path provided, uses NotoSans-Regular.ttf from fixtures
|
|
10
|
+
|
|
11
|
+
require_relative "../lib/fontisan"
|
|
12
|
+
|
|
13
|
+
def format_bytes(bytes)
|
|
14
|
+
if bytes < 1024
|
|
15
|
+
"#{bytes} B"
|
|
16
|
+
elsif bytes < 1024 * 1024
|
|
17
|
+
"#{(bytes / 1024.0).round(2)} KB"
|
|
18
|
+
else
|
|
19
|
+
"#{(bytes / (1024.0 * 1024)).round(2)} MB"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def format_time(seconds)
|
|
24
|
+
if seconds < 1
|
|
25
|
+
"#{(seconds * 1000).round(1)} ms"
|
|
26
|
+
else
|
|
27
|
+
"#{seconds.round(2)} s"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def measure_optimization(font_path, mode)
|
|
32
|
+
puts "\n#{if mode == :none
|
|
33
|
+
'Unoptimized'
|
|
34
|
+
else
|
|
35
|
+
mode == :normal ? 'Normal Optimization' : 'Stack-Aware Optimization'
|
|
36
|
+
end}:"
|
|
37
|
+
puts "=" * 60
|
|
38
|
+
|
|
39
|
+
font = Fontisan::FontLoader.load(font_path)
|
|
40
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
41
|
+
|
|
42
|
+
options = {
|
|
43
|
+
target_format: :otf,
|
|
44
|
+
optimize_subroutines: mode != :none,
|
|
45
|
+
stack_aware: mode == :stack_aware,
|
|
46
|
+
verbose: false,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
start_time = Time.now
|
|
50
|
+
result = converter.convert(font, options)
|
|
51
|
+
processing_time = Time.now - start_time
|
|
52
|
+
|
|
53
|
+
cff_size = result["CFF "].bytesize
|
|
54
|
+
optimization = result.instance_variable_get(:@subroutine_optimization)
|
|
55
|
+
|
|
56
|
+
puts " CFF table size: #{format_bytes(cff_size)}"
|
|
57
|
+
puts " Processing time: #{format_time(processing_time)}"
|
|
58
|
+
|
|
59
|
+
if optimization
|
|
60
|
+
puts " Patterns found: #{optimization[:pattern_count]}"
|
|
61
|
+
puts " Patterns selected: #{optimization[:selected_count]}"
|
|
62
|
+
puts " Local subroutines: #{optimization[:local_subrs].length}"
|
|
63
|
+
puts " Estimated savings: #{format_bytes(optimization[:savings])}"
|
|
64
|
+
puts " Bias: #{optimization[:bias]}"
|
|
65
|
+
else
|
|
66
|
+
puts " No optimization performed"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
size: cff_size,
|
|
71
|
+
time: processing_time,
|
|
72
|
+
optimization: optimization,
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def main
|
|
77
|
+
font_path = ARGV[0] || "spec/fixtures/fonts/NotoSans-Regular.ttf"
|
|
78
|
+
|
|
79
|
+
unless File.exist?(font_path)
|
|
80
|
+
puts "Error: Font file not found: #{font_path}"
|
|
81
|
+
puts "Usage: ruby scripts/compare_stack_aware.rb [font_path]"
|
|
82
|
+
exit 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
puts "╔═══════════════════════════════════════════════════════════════╗"
|
|
86
|
+
puts "║ Stack-Aware vs Normal Optimization Comparison ║"
|
|
87
|
+
puts "╚═══════════════════════════════════════════════════════════════╝"
|
|
88
|
+
puts
|
|
89
|
+
puts "Font: #{font_path}"
|
|
90
|
+
|
|
91
|
+
# Measure all three modes
|
|
92
|
+
unoptimized = measure_optimization(font_path, :none)
|
|
93
|
+
normal = measure_optimization(font_path, :normal)
|
|
94
|
+
stack_aware = measure_optimization(font_path, :stack_aware)
|
|
95
|
+
|
|
96
|
+
# Summary comparison
|
|
97
|
+
puts "\n#{'=' * 60}"
|
|
98
|
+
puts "SUMMARY COMPARISON"
|
|
99
|
+
puts "=" * 60
|
|
100
|
+
|
|
101
|
+
puts "\nFile Sizes:"
|
|
102
|
+
puts " Unoptimized: #{format_bytes(unoptimized[:size])} (baseline)"
|
|
103
|
+
puts " Normal: #{format_bytes(normal[:size])} (#{((normal[:size] - unoptimized[:size]) * 100.0 / unoptimized[:size]).round(2)}% change)"
|
|
104
|
+
puts " Stack-Aware: #{format_bytes(stack_aware[:size])} (#{((stack_aware[:size] - unoptimized[:size]) * 100.0 / unoptimized[:size]).round(2)}% change)"
|
|
105
|
+
|
|
106
|
+
puts "\nProcessing Times:"
|
|
107
|
+
puts " Unoptimized: #{format_time(unoptimized[:time])}"
|
|
108
|
+
puts " Normal: #{format_time(normal[:time])}"
|
|
109
|
+
puts " Stack-Aware: #{format_time(stack_aware[:time])}"
|
|
110
|
+
|
|
111
|
+
if normal[:optimization] && stack_aware[:optimization]
|
|
112
|
+
puts "\nOptimization Metrics:"
|
|
113
|
+
puts " Patterns Found:"
|
|
114
|
+
puts " Normal: #{normal[:optimization][:pattern_count]}"
|
|
115
|
+
puts " Stack-Aware: #{stack_aware[:optimization][:pattern_count]}"
|
|
116
|
+
|
|
117
|
+
puts " Patterns Selected:"
|
|
118
|
+
puts " Normal: #{normal[:optimization][:selected_count]}"
|
|
119
|
+
puts " Stack-Aware: #{stack_aware[:optimization][:selected_count]}"
|
|
120
|
+
|
|
121
|
+
puts " Subroutines Generated:"
|
|
122
|
+
puts " Normal: #{normal[:optimization][:local_subrs].length}"
|
|
123
|
+
puts " Stack-Aware: #{stack_aware[:optimization][:local_subrs].length}"
|
|
124
|
+
|
|
125
|
+
puts "\nBytes Saved (estimated):"
|
|
126
|
+
puts " Normal: #{format_bytes(normal[:optimization][:savings])}"
|
|
127
|
+
puts " Stack-Aware: #{format_bytes(stack_aware[:optimization][:savings])}"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
puts "\n#{'=' * 60}"
|
|
131
|
+
puts "ANALYSIS"
|
|
132
|
+
puts "=" * 60
|
|
133
|
+
|
|
134
|
+
# Calculate relative improvements
|
|
135
|
+
normal_reduction = unoptimized[:size] - normal[:size]
|
|
136
|
+
stack_aware_reduction = unoptimized[:size] - stack_aware[:size]
|
|
137
|
+
|
|
138
|
+
puts "\nFile Size Reduction:"
|
|
139
|
+
if normal_reduction.positive?
|
|
140
|
+
puts " Normal: #{format_bytes(normal_reduction)} (#{(normal_reduction * 100.0 / unoptimized[:size]).round(2)}%)"
|
|
141
|
+
else
|
|
142
|
+
puts " Normal: No reduction achieved"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
if stack_aware_reduction.positive?
|
|
146
|
+
puts " Stack-Aware: #{format_bytes(stack_aware_reduction)} (#{(stack_aware_reduction * 100.0 / unoptimized[:size]).round(2)}%)"
|
|
147
|
+
else
|
|
148
|
+
puts " Stack-Aware: No reduction achieved"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if normal_reduction.positive? && stack_aware_reduction.positive?
|
|
152
|
+
efficiency_ratio = (stack_aware_reduction.to_f / normal_reduction * 100).round(2)
|
|
153
|
+
puts "\nStack-Aware Efficiency: #{efficiency_ratio}% of normal optimization"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
time_overhead = ((stack_aware[:time] / unoptimized[:time] - 1) * 100).round(2)
|
|
157
|
+
puts "\nProcessing Time Overhead:"
|
|
158
|
+
puts " Stack-Aware vs Unoptimized: +#{time_overhead}%"
|
|
159
|
+
|
|
160
|
+
puts "\n#{'=' * 60}"
|
|
161
|
+
puts "CONCLUSION"
|
|
162
|
+
puts "=" * 60
|
|
163
|
+
|
|
164
|
+
if stack_aware_reduction.positive?
|
|
165
|
+
puts "\n✓ Stack-aware optimization achieved #{(stack_aware_reduction * 100.0 / unoptimized[:size]).round(2)}% file size reduction"
|
|
166
|
+
puts "✓ Trade-off: More reliable (stack-neutral patterns only)"
|
|
167
|
+
if normal_reduction > stack_aware_reduction
|
|
168
|
+
diff = normal_reduction - stack_aware_reduction
|
|
169
|
+
puts "✓ Cost: #{format_bytes(diff)} less compression vs normal mode"
|
|
170
|
+
elsif stack_aware_reduction > normal_reduction
|
|
171
|
+
diff = stack_aware_reduction - normal_reduction
|
|
172
|
+
puts "✓ Bonus: #{format_bytes(diff)} more compression than normal mode!"
|
|
173
|
+
else
|
|
174
|
+
puts "✓ Same compression as normal mode"
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
puts "\n⚠ Stack-aware optimization did not achieve compression for this font"
|
|
178
|
+
puts " This may indicate:"
|
|
179
|
+
puts " - Few stack-neutral patterns available"
|
|
180
|
+
puts " - Font has simple glyph structures"
|
|
181
|
+
puts " - Pattern sizes too small after stack validation"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
puts
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
main if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "../lib/fontisan"
|
|
5
|
+
|
|
6
|
+
def measure_font(font_path, options = {})
|
|
7
|
+
puts "\n#{'=' * 80}"
|
|
8
|
+
puts "Analyzing: #{File.basename(font_path)}"
|
|
9
|
+
puts "=" * 80
|
|
10
|
+
|
|
11
|
+
font = Fontisan::FontLoader.load(font_path)
|
|
12
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
13
|
+
|
|
14
|
+
# Get glyph count
|
|
15
|
+
maxp = font.table("maxp")
|
|
16
|
+
num_glyphs = maxp.num_glyphs
|
|
17
|
+
puts "Glyphs: #{num_glyphs}"
|
|
18
|
+
|
|
19
|
+
# Measure without optimization
|
|
20
|
+
puts "\n[1/2] Converting without optimization..."
|
|
21
|
+
start_time = Time.now
|
|
22
|
+
tables_unopt = converter.convert(font,
|
|
23
|
+
target_format: :otf,
|
|
24
|
+
optimize_subroutines: false)
|
|
25
|
+
time_unopt = Time.now - start_time
|
|
26
|
+
size_unopt = tables_unopt["CFF "].bytesize
|
|
27
|
+
|
|
28
|
+
# Measure with optimization
|
|
29
|
+
puts "[2/2] Converting with optimization..."
|
|
30
|
+
start_time = Time.now
|
|
31
|
+
tables_opt = converter.convert(font,
|
|
32
|
+
target_format: :otf,
|
|
33
|
+
optimize_subroutines: true,
|
|
34
|
+
min_pattern_length: options[:min_pattern_length] || 10,
|
|
35
|
+
max_subroutines: options[:max_subroutines] || 1000,
|
|
36
|
+
verbose: false)
|
|
37
|
+
time_opt = Time.now - start_time
|
|
38
|
+
size_opt = tables_opt["CFF "].bytesize
|
|
39
|
+
|
|
40
|
+
# Get optimization details
|
|
41
|
+
opt_result = tables_opt.instance_variable_get(:@subroutine_optimization)
|
|
42
|
+
|
|
43
|
+
# Calculate metrics
|
|
44
|
+
savings = size_unopt - size_opt
|
|
45
|
+
reduction_percent = (savings * 100.0 / size_unopt).round(2)
|
|
46
|
+
size_per_glyph_unopt = (size_unopt.to_f / num_glyphs).round(1)
|
|
47
|
+
size_per_glyph_opt = (size_opt.to_f / num_glyphs).round(1)
|
|
48
|
+
|
|
49
|
+
# Display results
|
|
50
|
+
puts "\n#{'-' * 80}"
|
|
51
|
+
puts "RESULTS"
|
|
52
|
+
puts "-" * 80
|
|
53
|
+
puts "File Sizes:"
|
|
54
|
+
puts " Without optimization: #{format('%10d', size_unopt)} bytes (#{size_per_glyph_unopt} bytes/glyph)"
|
|
55
|
+
puts " With optimization: #{format('%10d', size_opt)} bytes (#{size_per_glyph_opt} bytes/glyph)"
|
|
56
|
+
puts " Bytes saved: #{format('%10d', savings)} bytes"
|
|
57
|
+
puts " Reduction: #{format('%9.2f', reduction_percent)}%"
|
|
58
|
+
|
|
59
|
+
puts "\nProcessing Time:"
|
|
60
|
+
puts " Without optimization: #{format('%.2f', time_unopt)} seconds"
|
|
61
|
+
puts " With optimization: #{format('%.2f', time_opt)} seconds"
|
|
62
|
+
puts " Overhead: #{format('%.2f', time_opt - time_unopt)} seconds"
|
|
63
|
+
|
|
64
|
+
if opt_result
|
|
65
|
+
puts "\nOptimization Details:"
|
|
66
|
+
puts " Patterns found: #{format('%10d', opt_result[:pattern_count])}"
|
|
67
|
+
puts " Patterns selected: #{format('%10d', opt_result[:selected_count])}"
|
|
68
|
+
puts " Subroutines: #{format('%10d', opt_result[:local_subrs].length)}"
|
|
69
|
+
puts " CFF bias: #{format('%10d', opt_result[:bias])}"
|
|
70
|
+
puts " Est. bytes saved: #{format('%10d', opt_result[:savings])}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
{
|
|
74
|
+
font: File.basename(font_path),
|
|
75
|
+
num_glyphs: num_glyphs,
|
|
76
|
+
size_unopt: size_unopt,
|
|
77
|
+
size_opt: size_opt,
|
|
78
|
+
savings: savings,
|
|
79
|
+
reduction_percent: reduction_percent,
|
|
80
|
+
time_unopt: time_unopt,
|
|
81
|
+
time_opt: time_opt,
|
|
82
|
+
patterns_found: opt_result[:pattern_count],
|
|
83
|
+
patterns_selected: opt_result[:selected_count],
|
|
84
|
+
subroutines: opt_result[:local_subrs].length,
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def print_summary(results)
|
|
89
|
+
return if results.empty?
|
|
90
|
+
|
|
91
|
+
puts "\n\n#{'=' * 80}"
|
|
92
|
+
puts "SUMMARY TABLE"
|
|
93
|
+
puts "=" * 80
|
|
94
|
+
puts format("%-30s %8s %12s %12s %10s %8s",
|
|
95
|
+
"Font", "Glyphs", "Before", "After", "Saved", "Reduction")
|
|
96
|
+
puts "-" * 80
|
|
97
|
+
|
|
98
|
+
results.each do |r|
|
|
99
|
+
puts format("%-30s %8d %12d %12d %10d %7.2f%%",
|
|
100
|
+
r[:font], r[:num_glyphs],
|
|
101
|
+
r[:size_unopt], r[:size_opt],
|
|
102
|
+
r[:savings], r[:reduction_percent])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Calculate averages
|
|
106
|
+
avg_reduction = (results.sum { |r| r[:reduction_percent] } / results.length).round(2)
|
|
107
|
+
total_saved = results.sum { |r| r[:savings] }
|
|
108
|
+
|
|
109
|
+
puts "-" * 80
|
|
110
|
+
puts "Average reduction: #{avg_reduction}%"
|
|
111
|
+
puts "Total bytes saved: #{total_saved} bytes"
|
|
112
|
+
puts "=" * 80
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Main execution
|
|
116
|
+
if __FILE__ == $PROGRAM_NAME
|
|
117
|
+
font_paths = ARGV
|
|
118
|
+
|
|
119
|
+
if font_paths.empty?
|
|
120
|
+
# Use fixtures if no arguments provided
|
|
121
|
+
fixtures_dir = File.join(File.dirname(__FILE__), "..", "spec", "fixtures", "fonts")
|
|
122
|
+
font_paths = Dir.glob(File.join(fixtures_dir, "*.ttf"))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if font_paths.empty?
|
|
126
|
+
puts "Usage: ruby #{__FILE__} <font1.ttf> [font2.ttf ...]"
|
|
127
|
+
puts " or: ruby #{__FILE__} (uses fixture fonts)"
|
|
128
|
+
exit 1
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
results = []
|
|
132
|
+
font_paths.each do |path|
|
|
133
|
+
result = measure_font(path)
|
|
134
|
+
results << result
|
|
135
|
+
rescue StandardError => e
|
|
136
|
+
puts "\nERROR: Failed to process #{File.basename(path)}"
|
|
137
|
+
puts " #{e.message}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
print_summary(results)
|
|
141
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fontisan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: base64
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: bindata
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -24,6 +38,20 @@ dependencies:
|
|
|
24
38
|
- - "~>"
|
|
25
39
|
- !ruby/object:Gem::Version
|
|
26
40
|
version: '2.5'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: brotli
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.5'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.5'
|
|
27
55
|
- !ruby/object:Gem::Dependency
|
|
28
56
|
name: lutaml-model
|
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -38,20 +66,34 @@ dependencies:
|
|
|
38
66
|
- - "~>"
|
|
39
67
|
- !ruby/object:Gem::Version
|
|
40
68
|
version: '0.7'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: nokogiri
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.16'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.16'
|
|
41
83
|
- !ruby/object:Gem::Dependency
|
|
42
84
|
name: thor
|
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
|
44
86
|
requirements:
|
|
45
87
|
- - "~>"
|
|
46
88
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '1.
|
|
89
|
+
version: '1.3'
|
|
48
90
|
type: :runtime
|
|
49
91
|
prerelease: false
|
|
50
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
93
|
requirements:
|
|
52
94
|
- - "~>"
|
|
53
95
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '1.
|
|
96
|
+
version: '1.3'
|
|
55
97
|
description: |
|
|
56
98
|
Fontisan provides font analysis tools and utilities. It is
|
|
57
99
|
designed as a pure Ruby implementation with full object-oriented architecture,
|
|
@@ -73,53 +115,212 @@ files:
|
|
|
73
115
|
- LICENSE
|
|
74
116
|
- README.adoc
|
|
75
117
|
- Rakefile
|
|
118
|
+
- benchmark/variation_quick_bench.rb
|
|
119
|
+
- docs/EXTRACT_TTC_MIGRATION.md
|
|
76
120
|
- exe/fontisan
|
|
77
121
|
- fontisan.gemspec
|
|
78
122
|
- lib/fontisan.rb
|
|
79
123
|
- lib/fontisan/binary/base_record.rb
|
|
80
124
|
- lib/fontisan/binary/structures.rb
|
|
81
125
|
- lib/fontisan/cli.rb
|
|
126
|
+
- lib/fontisan/collection/builder.rb
|
|
127
|
+
- lib/fontisan/collection/offset_calculator.rb
|
|
128
|
+
- lib/fontisan/collection/table_analyzer.rb
|
|
129
|
+
- lib/fontisan/collection/table_deduplicator.rb
|
|
130
|
+
- lib/fontisan/collection/writer.rb
|
|
82
131
|
- lib/fontisan/commands/base_command.rb
|
|
132
|
+
- lib/fontisan/commands/convert_command.rb
|
|
83
133
|
- lib/fontisan/commands/dump_table_command.rb
|
|
134
|
+
- lib/fontisan/commands/export_command.rb
|
|
84
135
|
- lib/fontisan/commands/features_command.rb
|
|
85
136
|
- lib/fontisan/commands/glyphs_command.rb
|
|
86
137
|
- lib/fontisan/commands/info_command.rb
|
|
138
|
+
- lib/fontisan/commands/instance_command.rb
|
|
139
|
+
- lib/fontisan/commands/ls_command.rb
|
|
87
140
|
- lib/fontisan/commands/optical_size_command.rb
|
|
141
|
+
- lib/fontisan/commands/pack_command.rb
|
|
88
142
|
- lib/fontisan/commands/scripts_command.rb
|
|
143
|
+
- lib/fontisan/commands/subset_command.rb
|
|
89
144
|
- lib/fontisan/commands/tables_command.rb
|
|
90
145
|
- lib/fontisan/commands/unicode_command.rb
|
|
146
|
+
- lib/fontisan/commands/unpack_command.rb
|
|
147
|
+
- lib/fontisan/commands/validate_command.rb
|
|
91
148
|
- lib/fontisan/commands/variable_command.rb
|
|
149
|
+
- lib/fontisan/config/collection_settings.yml
|
|
150
|
+
- lib/fontisan/config/conversion_matrix.yml
|
|
151
|
+
- lib/fontisan/config/export_settings.yml
|
|
92
152
|
- lib/fontisan/config/features.yml
|
|
93
153
|
- lib/fontisan/config/scripts.yml
|
|
154
|
+
- lib/fontisan/config/subset_profiles.yml
|
|
155
|
+
- lib/fontisan/config/svg_settings.yml
|
|
156
|
+
- lib/fontisan/config/validation_rules.yml
|
|
157
|
+
- lib/fontisan/config/variable_settings.yml
|
|
158
|
+
- lib/fontisan/config/woff2_settings.yml
|
|
94
159
|
- lib/fontisan/constants.rb
|
|
160
|
+
- lib/fontisan/converters/conversion_strategy.rb
|
|
161
|
+
- lib/fontisan/converters/format_converter.rb
|
|
162
|
+
- lib/fontisan/converters/outline_converter.rb
|
|
163
|
+
- lib/fontisan/converters/svg_generator.rb
|
|
164
|
+
- lib/fontisan/converters/table_copier.rb
|
|
165
|
+
- lib/fontisan/converters/woff2_encoder.rb
|
|
166
|
+
- lib/fontisan/converters/woff_writer.rb
|
|
95
167
|
- lib/fontisan/error.rb
|
|
168
|
+
- lib/fontisan/export/exporter.rb
|
|
169
|
+
- lib/fontisan/export/table_serializer.rb
|
|
170
|
+
- lib/fontisan/export/transformers/font_to_ttx.rb
|
|
171
|
+
- lib/fontisan/export/transformers/head_transformer.rb
|
|
172
|
+
- lib/fontisan/export/transformers/hhea_transformer.rb
|
|
173
|
+
- lib/fontisan/export/transformers/maxp_transformer.rb
|
|
174
|
+
- lib/fontisan/export/transformers/name_transformer.rb
|
|
175
|
+
- lib/fontisan/export/transformers/os2_transformer.rb
|
|
176
|
+
- lib/fontisan/export/transformers/post_transformer.rb
|
|
177
|
+
- lib/fontisan/export/ttx_generator.rb
|
|
178
|
+
- lib/fontisan/export/ttx_parser.rb
|
|
96
179
|
- lib/fontisan/font_loader.rb
|
|
180
|
+
- lib/fontisan/font_writer.rb
|
|
97
181
|
- lib/fontisan/formatters/text_formatter.rb
|
|
182
|
+
- lib/fontisan/glyph_accessor.rb
|
|
183
|
+
- lib/fontisan/hints/hint_converter.rb
|
|
184
|
+
- lib/fontisan/hints/postscript_hint_applier.rb
|
|
185
|
+
- lib/fontisan/hints/postscript_hint_extractor.rb
|
|
186
|
+
- lib/fontisan/hints/truetype_hint_applier.rb
|
|
187
|
+
- lib/fontisan/hints/truetype_hint_extractor.rb
|
|
188
|
+
- lib/fontisan/loading_modes.rb
|
|
189
|
+
- lib/fontisan/metrics_calculator.rb
|
|
98
190
|
- lib/fontisan/models/all_scripts_features_info.rb
|
|
191
|
+
- lib/fontisan/models/collection_font_summary.rb
|
|
192
|
+
- lib/fontisan/models/collection_info.rb
|
|
193
|
+
- lib/fontisan/models/collection_list_info.rb
|
|
99
194
|
- lib/fontisan/models/features_info.rb
|
|
195
|
+
- lib/fontisan/models/font_export.rb
|
|
100
196
|
- lib/fontisan/models/font_info.rb
|
|
197
|
+
- lib/fontisan/models/font_summary.rb
|
|
101
198
|
- lib/fontisan/models/glyph_info.rb
|
|
199
|
+
- lib/fontisan/models/glyph_outline.rb
|
|
200
|
+
- lib/fontisan/models/hint.rb
|
|
102
201
|
- lib/fontisan/models/optical_size_info.rb
|
|
202
|
+
- lib/fontisan/models/outline.rb
|
|
103
203
|
- lib/fontisan/models/scripts_info.rb
|
|
104
204
|
- lib/fontisan/models/table_info.rb
|
|
205
|
+
- lib/fontisan/models/table_sharing_info.rb
|
|
206
|
+
- lib/fontisan/models/ttx/glyph_order.rb
|
|
207
|
+
- lib/fontisan/models/ttx/tables/binary_table.rb
|
|
208
|
+
- lib/fontisan/models/ttx/tables/head_table.rb
|
|
209
|
+
- lib/fontisan/models/ttx/tables/hhea_table.rb
|
|
210
|
+
- lib/fontisan/models/ttx/tables/maxp_table.rb
|
|
211
|
+
- lib/fontisan/models/ttx/tables/name_table.rb
|
|
212
|
+
- lib/fontisan/models/ttx/tables/os2_table.rb
|
|
213
|
+
- lib/fontisan/models/ttx/tables/post_table.rb
|
|
214
|
+
- lib/fontisan/models/ttx/ttfont.rb
|
|
105
215
|
- lib/fontisan/models/unicode_mappings.rb
|
|
216
|
+
- lib/fontisan/models/validation_report.rb
|
|
106
217
|
- lib/fontisan/models/variable_font_info.rb
|
|
107
218
|
- lib/fontisan/open_type_collection.rb
|
|
108
219
|
- lib/fontisan/open_type_font.rb
|
|
220
|
+
- lib/fontisan/optimizers/charstring_rewriter.rb
|
|
221
|
+
- lib/fontisan/optimizers/pattern_analyzer.rb
|
|
222
|
+
- lib/fontisan/optimizers/stack_tracker.rb
|
|
223
|
+
- lib/fontisan/optimizers/subroutine_builder.rb
|
|
224
|
+
- lib/fontisan/optimizers/subroutine_generator.rb
|
|
225
|
+
- lib/fontisan/optimizers/subroutine_optimizer.rb
|
|
226
|
+
- lib/fontisan/outline_extractor.rb
|
|
109
227
|
- lib/fontisan/parsers/tag.rb
|
|
228
|
+
- lib/fontisan/subset/builder.rb
|
|
229
|
+
- lib/fontisan/subset/glyph_mapping.rb
|
|
230
|
+
- lib/fontisan/subset/options.rb
|
|
231
|
+
- lib/fontisan/subset/profile.rb
|
|
232
|
+
- lib/fontisan/subset/table_subsetter.rb
|
|
233
|
+
- lib/fontisan/svg/font_face_generator.rb
|
|
234
|
+
- lib/fontisan/svg/font_generator.rb
|
|
235
|
+
- lib/fontisan/svg/glyph_generator.rb
|
|
236
|
+
- lib/fontisan/svg/view_box_calculator.rb
|
|
237
|
+
- lib/fontisan/tables/cff.rb
|
|
238
|
+
- lib/fontisan/tables/cff/cff_glyph.rb
|
|
239
|
+
- lib/fontisan/tables/cff/charset.rb
|
|
240
|
+
- lib/fontisan/tables/cff/charstring.rb
|
|
241
|
+
- lib/fontisan/tables/cff/charstring_builder.rb
|
|
242
|
+
- lib/fontisan/tables/cff/charstrings_index.rb
|
|
243
|
+
- lib/fontisan/tables/cff/dict.rb
|
|
244
|
+
- lib/fontisan/tables/cff/dict_builder.rb
|
|
245
|
+
- lib/fontisan/tables/cff/encoding.rb
|
|
246
|
+
- lib/fontisan/tables/cff/header.rb
|
|
247
|
+
- lib/fontisan/tables/cff/index.rb
|
|
248
|
+
- lib/fontisan/tables/cff/index_builder.rb
|
|
249
|
+
- lib/fontisan/tables/cff/private_dict.rb
|
|
250
|
+
- lib/fontisan/tables/cff/top_dict.rb
|
|
251
|
+
- lib/fontisan/tables/cff2.rb
|
|
252
|
+
- lib/fontisan/tables/cff2/blend_operator.rb
|
|
253
|
+
- lib/fontisan/tables/cff2/charstring_parser.rb
|
|
254
|
+
- lib/fontisan/tables/cff2/operand_stack.rb
|
|
110
255
|
- lib/fontisan/tables/cmap.rb
|
|
256
|
+
- lib/fontisan/tables/cvar.rb
|
|
111
257
|
- lib/fontisan/tables/fvar.rb
|
|
258
|
+
- lib/fontisan/tables/glyf.rb
|
|
259
|
+
- lib/fontisan/tables/glyf/compound_glyph.rb
|
|
260
|
+
- lib/fontisan/tables/glyf/compound_glyph_resolver.rb
|
|
261
|
+
- lib/fontisan/tables/glyf/curve_converter.rb
|
|
262
|
+
- lib/fontisan/tables/glyf/glyph_builder.rb
|
|
263
|
+
- lib/fontisan/tables/glyf/simple_glyph.rb
|
|
112
264
|
- lib/fontisan/tables/gpos.rb
|
|
113
265
|
- lib/fontisan/tables/gsub.rb
|
|
266
|
+
- lib/fontisan/tables/gvar.rb
|
|
114
267
|
- lib/fontisan/tables/head.rb
|
|
268
|
+
- lib/fontisan/tables/hhea.rb
|
|
269
|
+
- lib/fontisan/tables/hmtx.rb
|
|
270
|
+
- lib/fontisan/tables/hvar.rb
|
|
115
271
|
- lib/fontisan/tables/layout_common.rb
|
|
272
|
+
- lib/fontisan/tables/loca.rb
|
|
273
|
+
- lib/fontisan/tables/maxp.rb
|
|
274
|
+
- lib/fontisan/tables/mvar.rb
|
|
116
275
|
- lib/fontisan/tables/name.rb
|
|
117
276
|
- lib/fontisan/tables/os2.rb
|
|
118
277
|
- lib/fontisan/tables/post.rb
|
|
278
|
+
- lib/fontisan/tables/variation_common.rb
|
|
279
|
+
- lib/fontisan/tables/vvar.rb
|
|
119
280
|
- lib/fontisan/true_type_collection.rb
|
|
120
281
|
- lib/fontisan/true_type_font.rb
|
|
282
|
+
- lib/fontisan/utilities/brotli_wrapper.rb
|
|
121
283
|
- lib/fontisan/utilities/checksum_calculator.rb
|
|
284
|
+
- lib/fontisan/utils/thread_pool.rb
|
|
285
|
+
- lib/fontisan/validation/checksum_validator.rb
|
|
286
|
+
- lib/fontisan/validation/consistency_validator.rb
|
|
287
|
+
- lib/fontisan/validation/structure_validator.rb
|
|
288
|
+
- lib/fontisan/validation/table_validator.rb
|
|
289
|
+
- lib/fontisan/validation/validator.rb
|
|
290
|
+
- lib/fontisan/variable/axis_normalizer.rb
|
|
291
|
+
- lib/fontisan/variable/delta_applicator.rb
|
|
292
|
+
- lib/fontisan/variable/glyph_delta_processor.rb
|
|
293
|
+
- lib/fontisan/variable/instancer.rb
|
|
294
|
+
- lib/fontisan/variable/metric_delta_processor.rb
|
|
295
|
+
- lib/fontisan/variable/region_matcher.rb
|
|
296
|
+
- lib/fontisan/variable/static_font_builder.rb
|
|
297
|
+
- lib/fontisan/variable/table_updater.rb
|
|
298
|
+
- lib/fontisan/variation/blend_applier.rb
|
|
299
|
+
- lib/fontisan/variation/cache.rb
|
|
300
|
+
- lib/fontisan/variation/cache_key_builder.rb
|
|
301
|
+
- lib/fontisan/variation/converter.rb
|
|
302
|
+
- lib/fontisan/variation/data_extractor.rb
|
|
303
|
+
- lib/fontisan/variation/delta_applier.rb
|
|
304
|
+
- lib/fontisan/variation/delta_parser.rb
|
|
305
|
+
- lib/fontisan/variation/inspector.rb
|
|
306
|
+
- lib/fontisan/variation/instance_generator.rb
|
|
307
|
+
- lib/fontisan/variation/interpolator.rb
|
|
308
|
+
- lib/fontisan/variation/metrics_adjuster.rb
|
|
309
|
+
- lib/fontisan/variation/optimizer.rb
|
|
310
|
+
- lib/fontisan/variation/parallel_generator.rb
|
|
311
|
+
- lib/fontisan/variation/region_matcher.rb
|
|
312
|
+
- lib/fontisan/variation/subsetter.rb
|
|
313
|
+
- lib/fontisan/variation/table_accessor.rb
|
|
314
|
+
- lib/fontisan/variation/validator.rb
|
|
315
|
+
- lib/fontisan/variation/variation_context.rb
|
|
122
316
|
- lib/fontisan/version.rb
|
|
317
|
+
- lib/fontisan/woff2/directory.rb
|
|
318
|
+
- lib/fontisan/woff2/header.rb
|
|
319
|
+
- lib/fontisan/woff2/table_transformer.rb
|
|
320
|
+
- lib/fontisan/woff2_font.rb
|
|
321
|
+
- lib/fontisan/woff_font.rb
|
|
322
|
+
- scripts/compare_stack_aware.rb
|
|
323
|
+
- scripts/measure_optimization.rb
|
|
123
324
|
homepage: https://github.com/fontist/fontisan
|
|
124
325
|
licenses:
|
|
125
326
|
- BSD-2-Clause
|