fontisan 0.4.42 → 0.4.44

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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.bug-fixes/09-type1-cff-seac-expansion.md +22 -0
  3. data/TODO.bug-fixes/10-ttf-type1-composite-glyphs.md +23 -0
  4. data/TODO.bug-fixes/11-remaining-respond-to.md +25 -0
  5. data/TODO.bug-fixes/12-type1-generators-duck-typing.md +80 -0
  6. data/TODO.bug-fixes/13-hint-extractor-duck-typing.md +30 -0
  7. data/TODO.bug-fixes/14-font-interface-type-checks.md +82 -0
  8. data/TODO.bug-fixes/15-glyph-type-checks-and-simple-glyph-points-bug.md +49 -0
  9. data/TODO.bug-fixes/16-variation-table-checks.md +31 -0
  10. data/TODO.bug-fixes/17-ufo-and-stitcher-cleanup.md +32 -0
  11. data/TODO.bug-fixes/18-generic-value-and-io-checks.md +56 -0
  12. data/TODO.bug-fixes/19-serialization-migration.md +52 -0
  13. data/TODO.bug-fixes/20-variation-validator-type-checks.md +29 -0
  14. data/TODO.bug-fixes/21-xml-builder-send.md +24 -0
  15. data/TODO.bug-fixes/22-type1-converter-font-info.md +25 -0
  16. data/TODO.bug-fixes/23-boundary-type-checks.md +31 -0
  17. data/TODO.bug-fixes/24-validator-dynamic-field-key.md +25 -0
  18. data/TODO.bug-fixes/25-serialization-migration.md +49 -0
  19. data/TODO.bug-fixes/26-variation-preserver-spec-migration.md +25 -0
  20. data/TODO.bug-fixes/27-table-class-registry.md +50 -0
  21. data/TODO.bug-fixes/28-spec-doubles-cleanup.md +40 -0
  22. data/TODO.bug-fixes/29-strategy-registries.md +30 -0
  23. data/TODO.bug-fixes/README.md +29 -2
  24. data/lib/fontisan/binary/base_record.rb +13 -12
  25. data/lib/fontisan/collection/builder.rb +3 -5
  26. data/lib/fontisan/collection/dfont_builder.rb +4 -11
  27. data/lib/fontisan/collection/writer.rb +1 -1
  28. data/lib/fontisan/commands/pack_command.rb +4 -4
  29. data/lib/fontisan/commands/unpack_command.rb +1 -1
  30. data/lib/fontisan/commands/validate_command.rb +1 -1
  31. data/lib/fontisan/converters/format_converter.rb +2 -2
  32. data/lib/fontisan/converters/glyf_table_builder.rb +1 -1
  33. data/lib/fontisan/converters/outline_converter.rb +2 -6
  34. data/lib/fontisan/converters/table_copier.rb +4 -12
  35. data/lib/fontisan/converters/type1_converter.rb +12 -37
  36. data/lib/fontisan/converters/woff2_encoder.rb +8 -10
  37. data/lib/fontisan/converters/woff_writer.rb +3 -3
  38. data/lib/fontisan/export/exporter.rb +8 -9
  39. data/lib/fontisan/export/table_serializer.rb +71 -186
  40. data/lib/fontisan/export/transformers/font_to_ttx.rb +18 -18
  41. data/lib/fontisan/export/transformers/head_transformer.rb +1 -1
  42. data/lib/fontisan/export/transformers/hhea_transformer.rb +1 -1
  43. data/lib/fontisan/export/transformers/maxp_transformer.rb +1 -1
  44. data/lib/fontisan/export/transformers/name_transformer.rb +1 -1
  45. data/lib/fontisan/export/transformers/os2_transformer.rb +1 -1
  46. data/lib/fontisan/export/transformers/post_transformer.rb +1 -1
  47. data/lib/fontisan/export/ttx_generator.rb +36 -37
  48. data/lib/fontisan/font_writer.rb +1 -1
  49. data/lib/fontisan/glyph_accessor.rb +9 -15
  50. data/lib/fontisan/hints/postscript_hint_extractor.rb +24 -64
  51. data/lib/fontisan/hints/truetype_hint_extractor.rb +1 -1
  52. data/lib/fontisan/models/ttx/tables/binary_table.rb +1 -1
  53. data/lib/fontisan/optimizers/charstring_rewriter.rb +1 -1
  54. data/lib/fontisan/outline_extractor.rb +1 -5
  55. data/lib/fontisan/sfnt_font.rb +3 -3
  56. data/lib/fontisan/sfnt_source.rb +28 -0
  57. data/lib/fontisan/stitcher/source.rb +8 -10
  58. data/lib/fontisan/subset/builder.rb +2 -2
  59. data/lib/fontisan/subset/table_strategy/cff2.rb +2 -3
  60. data/lib/fontisan/svg/font_face_generator.rb +0 -4
  61. data/lib/fontisan/svg/font_generator.rb +0 -4
  62. data/lib/fontisan/svg_to_glyf/assembler.rb +59 -20
  63. data/lib/fontisan/svg_to_glyf/document.rb +28 -9
  64. data/lib/fontisan/svg_to_glyf/geometry/normalizer.rb +34 -17
  65. data/lib/fontisan/tables/cff/charstring.rb +3 -0
  66. data/lib/fontisan/tables/cff/dict.rb +6 -3
  67. data/lib/fontisan/tables/cff/index.rb +1 -1
  68. data/lib/fontisan/tables/cff/private_dict_writer.rb +2 -2
  69. data/lib/fontisan/tables/cff/table_builder.rb +1 -1
  70. data/lib/fontisan/tables/cff.rb +3 -0
  71. data/lib/fontisan/tables/cff2/table_builder.rb +2 -4
  72. data/lib/fontisan/tables/cff2.rb +3 -0
  73. data/lib/fontisan/tables/cmap.rb +3 -0
  74. data/lib/fontisan/tables/cvar.rb +3 -0
  75. data/lib/fontisan/tables/fvar.rb +3 -0
  76. data/lib/fontisan/tables/glyf/simple_glyph.rb +9 -0
  77. data/lib/fontisan/tables/glyf.rb +12 -8
  78. data/lib/fontisan/tables/glyf_table.rb +4 -4
  79. data/lib/fontisan/tables/gvar.rb +3 -0
  80. data/lib/fontisan/tables/head.rb +3 -0
  81. data/lib/fontisan/tables/hhea.rb +3 -0
  82. data/lib/fontisan/tables/hmtx.rb +3 -7
  83. data/lib/fontisan/tables/hvar.rb +4 -0
  84. data/lib/fontisan/tables/loca.rb +3 -0
  85. data/lib/fontisan/tables/maxp.rb +3 -0
  86. data/lib/fontisan/tables/mvar.rb +3 -0
  87. data/lib/fontisan/tables/name.rb +3 -0
  88. data/lib/fontisan/tables/os2.rb +3 -0
  89. data/lib/fontisan/tables/post.rb +3 -0
  90. data/lib/fontisan/tables/registry.rb +71 -0
  91. data/lib/fontisan/tables/vvar.rb +3 -0
  92. data/lib/fontisan/tables.rb +2 -0
  93. data/lib/fontisan/type1/afm_generator.rb +12 -65
  94. data/lib/fontisan/type1/charstring_converter.rb +21 -23
  95. data/lib/fontisan/type1/conversion_options.rb +3 -2
  96. data/lib/fontisan/type1/decryptor.rb +1 -1
  97. data/lib/fontisan/type1/generator.rb +14 -9
  98. data/lib/fontisan/type1/inf_generator.rb +10 -35
  99. data/lib/fontisan/type1/pfa_generator.rb +36 -26
  100. data/lib/fontisan/type1/pfb_generator.rb +24 -12
  101. data/lib/fontisan/type1/pfm_generator.rb +14 -31
  102. data/lib/fontisan/type1/ttf_to_type1_converter.rb +88 -26
  103. data/lib/fontisan/ufo/bounds.rb +91 -0
  104. data/lib/fontisan/ufo/compile/fvar.rb +2 -2
  105. data/lib/fontisan/ufo/contour.rb +5 -0
  106. data/lib/fontisan/ufo/convert/from_bin_data.rb +15 -29
  107. data/lib/fontisan/ufo/info.rb +4 -0
  108. data/lib/fontisan/ufo/point.rb +0 -7
  109. data/lib/fontisan/ufo.rb +1 -0
  110. data/lib/fontisan/utilities/brotli_wrapper.rb +3 -5
  111. data/lib/fontisan/utilities/padding.rb +9 -8
  112. data/lib/fontisan/validation/collection_validator.rb +2 -2
  113. data/lib/fontisan/validators/validator.rb +4 -4
  114. data/lib/fontisan/variable/delta_applicator.rb +4 -11
  115. data/lib/fontisan/variable/metric_delta_processor.rb +3 -3
  116. data/lib/fontisan/variable/static_font_builder.rb +19 -23
  117. data/lib/fontisan/variation/instance_font_wrapper.rb +41 -0
  118. data/lib/fontisan/variation/instance_writer.rb +19 -17
  119. data/lib/fontisan/variation/metrics_adjuster.rb +17 -20
  120. data/lib/fontisan/variation/validator.rb +26 -38
  121. data/lib/fontisan/variation/variable_svg_generator.rb +0 -48
  122. data/lib/fontisan/variation/variation_preserver.rb +2 -3
  123. data/lib/fontisan/variation.rb +1 -0
  124. data/lib/fontisan/version.rb +1 -1
  125. data/lib/fontisan/woff2/sfnt_checksum.rb +1 -1
  126. data/lib/fontisan/woff2/table_transformer.rb +22 -29
  127. data/lib/fontisan/woff2_font.rb +11 -10
  128. data/lib/fontisan/woff_font.rb +2 -1
  129. data/lib/fontisan.rb +1 -0
  130. metadata +27 -2
@@ -103,11 +103,9 @@ module Fontisan
103
103
  # Check CFF2 if present
104
104
  if @font.has_table?("CFF2")
105
105
  cff2 = @font.table("CFF2")
106
- if cff2.respond_to?(:num_axes)
107
- cff2_axes = cff2.num_axes || 0
108
- if cff2_axes != axis_count && cff2_axes.positive?
109
- @errors << "CFF2 axis count (#{cff2_axes}) doesn't match fvar (#{axis_count})"
110
- end
106
+ cff2_axes = cff2&.num_axes || 0
107
+ if cff2_axes != axis_count && cff2_axes.positive?
108
+ @errors << "CFF2 axis count (#{cff2_axes}) doesn't match fvar (#{axis_count})"
111
109
  end
112
110
  end
113
111
 
@@ -133,20 +131,17 @@ module Fontisan
133
131
  return unless @font.has_table?(table_tag)
134
132
 
135
133
  table = @font.table(table_tag)
136
- return unless table.respond_to?(:item_variation_store)
137
-
138
- store = table.item_variation_store
134
+ store = table&.item_variation_store
139
135
  return unless store
140
136
 
141
- # Check region list axis count
142
- if store.respond_to?(:region_list) && store.region_list
143
- region_list = store.region_list
144
- if region_list.respond_to?(:axis_count)
145
- region_axes = region_list.axis_count
146
- if region_axes != expected_axes
147
- @errors << "#{table_tag} region axis count (#{region_axes}) doesn't match fvar (#{expected_axes})"
148
- end
149
- end
137
+ region_list = store.variation_region_list
138
+ return unless region_list
139
+
140
+ region_axes = region_list.axis_count
141
+ return unless region_axes
142
+
143
+ if region_axes != expected_axes
144
+ @errors << "#{table_tag} region axis count (#{region_axes}) doesn't match fvar (#{expected_axes})"
150
145
  end
151
146
  end
152
147
 
@@ -195,24 +190,15 @@ module Fontisan
195
190
  hvar = @font.table("HVAR")
196
191
  return unless hvar
197
192
 
198
- # Check for item_variation_store
199
- unless hvar.respond_to?(:item_variation_store)
200
- @warnings << "HVAR table doesn't support item_variation_store"
201
- return
202
- end
203
-
204
193
  store = hvar.item_variation_store
205
194
  unless store
206
195
  @warnings << "HVAR has no item variation store"
207
196
  return
208
197
  end
209
198
 
210
- # Check that variation data exists
211
- if store.respond_to?(:item_variation_data)
212
- data = store.item_variation_data
213
- if data.nil? || data.empty?
214
- @warnings << "HVAR has no variation data"
215
- end
199
+ data = store.item_variation_data_entries
200
+ if data.nil? || data.empty?
201
+ @warnings << "HVAR has no variation data"
216
202
  end
217
203
  rescue StandardError => e
218
204
  @warnings << "Failed to check HVAR delta integrity: #{e.message}"
@@ -272,24 +258,26 @@ module Fontisan
272
258
  # @param axes [Array] Variation axes
273
259
  def check_metrics_region_coverage(table_tag, axes)
274
260
  table = @font.table(table_tag)
275
- return unless table.respond_to?(:item_variation_store)
261
+ return unless table
276
262
 
277
263
  store = table.item_variation_store
278
- return unless store.respond_to?(:region_list)
264
+ return unless store
279
265
 
280
- region_list = store.region_list
281
- return unless region_list.respond_to?(:regions)
266
+ region_list = store.variation_region_list
267
+ return unless region_list
282
268
 
283
- # Check each region
284
269
  regions = region_list.regions
285
- regions.each_with_index do |region, idx|
286
- next unless region.respond_to?(:region_axes)
270
+ return unless regions
271
+
272
+ # Each region is an Array<RegionAxisCoordinates>; check coords
273
+ # are within the valid [-1, 1] normalized range.
274
+ regions.each_with_index do |region_axis_coords, idx|
275
+ next unless region_axis_coords.is_a?(Array)
287
276
 
288
- region.region_axes.each_with_index do |reg_axis, axis_idx|
277
+ region_axis_coords.each_with_index do |reg_axis, axis_idx|
289
278
  next if axis_idx >= axes.length
290
279
  next unless reg_axis
291
280
 
292
- # Check coordinates are in valid range [-1, 1]
293
281
  coords = {
294
282
  start_coord: reg_axis.start_coord,
295
283
  peak_coord: reg_axis.peak_coord,
@@ -178,8 +178,6 @@ module Fontisan
178
178
  # @param tables [Hash<String, String>] Font tables
179
179
  # @return [Object] Font-like object
180
180
  def build_font_from_tables(tables)
181
- # Create a simple font wrapper that implements the minimal
182
- # interface needed by SvgGenerator
183
181
  InstanceFontWrapper.new(@font, tables)
184
182
  end
185
183
 
@@ -214,52 +212,6 @@ module Fontisan
214
212
  end
215
213
  coords
216
214
  end
217
-
218
- # Wrapper class for instance font tables
219
- #
220
- # Provides minimal interface needed by SvgGenerator while using
221
- # instance tables instead of original font tables.
222
- class InstanceFontWrapper
223
- # @return [Hash<String, String>] Font tables
224
- attr_reader :table_data
225
-
226
- # Initialize wrapper
227
- #
228
- # @param original_font [Object] Original variable font
229
- # @param instance_tables [Hash<String, String>] Instance tables
230
- def initialize(original_font, instance_tables)
231
- @original_font = original_font
232
- @table_data = instance_tables
233
- end
234
-
235
- # Get table by tag
236
- #
237
- # @param tag [String] Table tag
238
- # @return [Object, nil] Table or nil
239
- def table(tag)
240
- # Use instance table if available, otherwise fall back to original
241
- if @table_data.key?(tag)
242
- end
243
- @original_font.table(tag)
244
- end
245
-
246
- # Check if table exists
247
- #
248
- # @param tag [String] Table tag
249
- # @return [Boolean] True if table exists
250
- def has_table?(tag)
251
- @table_data.key?(tag) || @original_font.has_table?(tag)
252
- end
253
-
254
- # Forward other methods to original font
255
- def method_missing(method, ...)
256
- @original_font.send(method, ...)
257
- end
258
-
259
- def respond_to_missing?(method, include_private = false)
260
- @original_font.respond_to?(method, include_private) || super
261
- end
262
- end
263
215
  end
264
216
  end
265
217
  end
@@ -148,10 +148,9 @@ module Fontisan
148
148
  def validate_source!
149
149
  raise ArgumentError, "Source font cannot be nil" if @source_font.nil?
150
150
 
151
- unless @source_font.respond_to?(:has_table?) &&
152
- @source_font.respond_to?(:table_data)
151
+ unless @source_font.is_a?(SfntSource)
153
152
  raise ArgumentError,
154
- "Source font must respond to :has_table? and :table_data"
153
+ "Source font must be an SfntSource instance"
155
154
  end
156
155
 
157
156
  if @target_tables.nil?
@@ -13,6 +13,7 @@ module Fontisan
13
13
  autoload :DeltaParser, "fontisan/variation/delta_parser"
14
14
  autoload :Inspector, "fontisan/variation/inspector"
15
15
  autoload :InstanceGenerator, "fontisan/variation/instance_generator"
16
+ autoload :InstanceFontWrapper, "fontisan/variation/instance_font_wrapper"
16
17
  autoload :InstanceWriter, "fontisan/variation/instance_writer"
17
18
  autoload :Interpolator, "fontisan/variation/interpolator"
18
19
  autoload :MetricsAdjuster, "fontisan/variation/metrics_adjuster"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- VERSION = "0.4.42"
4
+ VERSION = "0.4.44"
5
5
  end
@@ -79,7 +79,7 @@ module Fontisan
79
79
  offsets = {}
80
80
  @tables.each do |t|
81
81
  offsets[t.tag] = cursor
82
- cursor += Utilities::Padding.aligned_size(t.bytes)
82
+ cursor += Utilities::Padding.aligned_size(t.bytes.bytesize)
83
83
  end
84
84
 
85
85
  bytes = String.new(encoding: Encoding::BINARY)
@@ -32,41 +32,34 @@ module Fontisan
32
32
  #
33
33
  # @param tag [String] Table tag
34
34
  # @return [String, nil] Transformed table data
35
+ # Per-tag transform method dispatch.
36
+ TRANSFORM_DISPATCH = {
37
+ "glyf" => :transform_glyf,
38
+ "loca" => :transform_loca,
39
+ "hmtx" => :transform_hmtx,
40
+ }.freeze
41
+
42
+ # Per-tag transform version constant.
43
+ TRANSFORM_VERSIONS = {
44
+ "glyf" => Directory::TRANSFORM_GLYF_LOCA,
45
+ "loca" => Directory::TRANSFORM_GLYF_LOCA,
46
+ "hmtx" => Directory::TRANSFORM_HMTX,
47
+ }.freeze
48
+
35
49
  def transform_table(tag)
36
- case tag
37
- when "glyf"
38
- transform_glyf
39
- when "loca"
40
- transform_loca
41
- when "hmtx"
42
- transform_hmtx
43
- else
44
- # No transformation, return original data
45
- get_table_data(tag)
46
- end
50
+ transform_method = TRANSFORM_DISPATCH[tag]
51
+ return method(transform_method).call if transform_method
52
+
53
+ # No transformation, return original data
54
+ get_table_data(tag)
47
55
  end
48
56
 
49
- # Check if a table can be transformed
50
- #
51
- # @param tag [String] Table tag
52
- # @return [Boolean] True if table supports transformation
53
57
  def transformable?(tag)
54
- %w[glyf loca hmtx].include?(tag)
58
+ TRANSFORM_DISPATCH.key?(tag)
55
59
  end
56
60
 
57
- # Determine transformation version for a table
58
- #
59
- # @param tag [String] Table tag
60
- # @return [Integer] Transformation version
61
61
  def transformation_version(tag)
62
- case tag
63
- when "glyf", "loca"
64
- Directory::TRANSFORM_GLYF_LOCA
65
- when "hmtx"
66
- Directory::TRANSFORM_HMTX
67
- else
68
- Directory::TRANSFORM_NONE
69
- end
62
+ TRANSFORM_VERSIONS.fetch(tag, Directory::TRANSFORM_NONE)
70
63
  end
71
64
 
72
65
  private
@@ -150,7 +143,7 @@ module Fontisan
150
143
  # @param tag [String] Table tag
151
144
  # @return [String, nil] Table data or nil if not found
152
145
  def get_table_data(tag)
153
- return nil unless font.respond_to?(:table_data)
146
+ return nil unless font.is_a?(SfntSource)
154
147
 
155
148
  font.table_data[tag]
156
149
  end
@@ -42,18 +42,17 @@ module Fontisan
42
42
  (@flags & 0x3F) != 0x3F && KNOWN_TAGS[tag_index]&.start_with?(/glyf|loca|hmtx/)
43
43
  end
44
44
 
45
+ TRANSFORM_VERSIONS = {
46
+ "glyf" => TRANSFORM_GLYF_LOCA,
47
+ "loca" => TRANSFORM_GLYF_LOCA,
48
+ "hmtx" => TRANSFORM_HMTX,
49
+ }.freeze
50
+
45
51
  # Get transform version for this table
46
52
  def transform_version
47
53
  return TRANSFORM_NONE unless transformed?
48
54
 
49
- case tag
50
- when "glyf", "loca"
51
- TRANSFORM_GLYF_LOCA
52
- when "hmtx"
53
- TRANSFORM_HMTX
54
- else
55
- TRANSFORM_NONE
56
- end
55
+ TRANSFORM_VERSIONS.fetch(tag, TRANSFORM_NONE)
57
56
  end
58
57
 
59
58
  private
@@ -73,6 +72,8 @@ module Fontisan
73
72
  # puts font.header.flavor
74
73
  # puts font.table_names
75
74
  class Woff2Font
75
+ include SfntSource
76
+
76
77
  # High-level pipeline format identifier. Owned by the font class so the
77
78
  # conversion pipeline can dispatch without case statements (OCP).
78
79
  #
@@ -185,7 +186,7 @@ module Fontisan
185
186
  # If no tag provided, return all tables
186
187
  if tag.nil?
187
188
  # First try underlying font's table data if available
188
- if @underlying_font.respond_to?(:table_data)
189
+ if @underlying_font.is_a?(SfntFont)
189
190
  return @underlying_font.table_data
190
191
  end
191
192
 
@@ -195,7 +196,7 @@ module Fontisan
195
196
 
196
197
  # Tag provided - return specific table
197
198
  # First try underlying font's table data if available
198
- if @underlying_font.respond_to?(:table_data)
199
+ if @underlying_font.is_a?(SfntFont)
199
200
  underlying_data = @underlying_font.table_data[tag]
200
201
  return underlying_data if underlying_data
201
202
  end
@@ -53,6 +53,8 @@ module Fontisan
53
53
  # woff.to_ttf("output.ttf") # if TrueType flavored
54
54
  # woff.to_otf("output.otf") # if CFF flavored
55
55
  class WoffFont < BinData::Record
56
+ include SfntSource
57
+
56
58
  # High-level pipeline format identifier. Owned by the font class so the
57
59
  # conversion pipeline can dispatch without case statements (OCP).
58
60
  #
@@ -359,7 +361,6 @@ module Fontisan
359
361
  def valid?
360
362
  return false unless header
361
363
  return false unless header.signature == WOFF_SIGNATURE
362
- return false unless table_entries.respond_to?(:length)
363
364
  return false if table_entries.length != header.num_tables
364
365
  return false unless has_table?(Constants::HEAD_TAG)
365
366
 
data/lib/fontisan.rb CHANGED
@@ -116,6 +116,7 @@ module Fontisan
116
116
  autoload :OpenTypeFontExtensions, "fontisan/open_type_font_extensions"
117
117
  autoload :OutlineExtractor, "fontisan/outline_extractor"
118
118
  autoload :SfntFont, "fontisan/sfnt_font"
119
+ autoload :SfntSource, "fontisan/sfnt_source"
119
120
  autoload :SfntTable, "fontisan/sfnt_table"
120
121
  autoload :SfntBuilder, "fontisan/sfnt_builder"
121
122
  autoload :Stitcher, "fontisan/stitcher"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontisan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.42
4
+ version: 0.4.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-12 00:00:00.000000000 Z
11
+ date: 2026-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -141,6 +141,27 @@ files:
141
141
  - TODO.bug-fixes/06-instance-woff2-output.md
142
142
  - TODO.bug-fixes/07-encapsulation-violations.md
143
143
  - TODO.bug-fixes/08-respond-to-violations.md
144
+ - TODO.bug-fixes/09-type1-cff-seac-expansion.md
145
+ - TODO.bug-fixes/10-ttf-type1-composite-glyphs.md
146
+ - TODO.bug-fixes/11-remaining-respond-to.md
147
+ - TODO.bug-fixes/12-type1-generators-duck-typing.md
148
+ - TODO.bug-fixes/13-hint-extractor-duck-typing.md
149
+ - TODO.bug-fixes/14-font-interface-type-checks.md
150
+ - TODO.bug-fixes/15-glyph-type-checks-and-simple-glyph-points-bug.md
151
+ - TODO.bug-fixes/16-variation-table-checks.md
152
+ - TODO.bug-fixes/17-ufo-and-stitcher-cleanup.md
153
+ - TODO.bug-fixes/18-generic-value-and-io-checks.md
154
+ - TODO.bug-fixes/19-serialization-migration.md
155
+ - TODO.bug-fixes/20-variation-validator-type-checks.md
156
+ - TODO.bug-fixes/21-xml-builder-send.md
157
+ - TODO.bug-fixes/22-type1-converter-font-info.md
158
+ - TODO.bug-fixes/23-boundary-type-checks.md
159
+ - TODO.bug-fixes/24-validator-dynamic-field-key.md
160
+ - TODO.bug-fixes/25-serialization-migration.md
161
+ - TODO.bug-fixes/26-variation-preserver-spec-migration.md
162
+ - TODO.bug-fixes/27-table-class-registry.md
163
+ - TODO.bug-fixes/28-spec-doubles-cleanup.md
164
+ - TODO.bug-fixes/29-strategy-registries.md
144
165
  - TODO.bug-fixes/README.md
145
166
  - TODO.improvements/01-cbdt-cblc-gid-stable-propagation.md
146
167
  - TODO.improvements/02-collection-outline-priority.md
@@ -487,6 +508,7 @@ files:
487
508
  - lib/fontisan/pipeline/variation_resolver.rb
488
509
  - lib/fontisan/sfnt_builder.rb
489
510
  - lib/fontisan/sfnt_font.rb
511
+ - lib/fontisan/sfnt_source.rb
490
512
  - lib/fontisan/sfnt_table.rb
491
513
  - lib/fontisan/stitcher.rb
492
514
  - lib/fontisan/stitcher/cbdt_propagator.rb
@@ -642,6 +664,7 @@ files:
642
664
  - lib/fontisan/tables/os2_table.rb
643
665
  - lib/fontisan/tables/post.rb
644
666
  - lib/fontisan/tables/post_table.rb
667
+ - lib/fontisan/tables/registry.rb
645
668
  - lib/fontisan/tables/sbix.rb
646
669
  - lib/fontisan/tables/svg.rb
647
670
  - lib/fontisan/tables/variation_common.rb
@@ -675,6 +698,7 @@ files:
675
698
  - lib/fontisan/type1_font.rb
676
699
  - lib/fontisan/ufo.rb
677
700
  - lib/fontisan/ufo/anchor.rb
701
+ - lib/fontisan/ufo/bounds.rb
678
702
  - lib/fontisan/ufo/cli.rb
679
703
  - lib/fontisan/ufo/compile.rb
680
704
  - lib/fontisan/ufo/compile/avar.rb
@@ -797,6 +821,7 @@ files:
797
821
  - lib/fontisan/variation/delta_applier.rb
798
822
  - lib/fontisan/variation/delta_parser.rb
799
823
  - lib/fontisan/variation/inspector.rb
824
+ - lib/fontisan/variation/instance_font_wrapper.rb
800
825
  - lib/fontisan/variation/instance_generator.rb
801
826
  - lib/fontisan/variation/instance_writer.rb
802
827
  - lib/fontisan/variation/interpolator.rb