fontisan 0.4.30 → 0.4.32

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dd9aa72ac0517bcfbfed3d6eb3528af3e0b65a52bc721d14ba5fb545198e48f
4
- data.tar.gz: be1d6d7379a3bd0cda435d02b91e5d7fc213736483e3aac66b93280d63261669
3
+ metadata.gz: 9e6bea227da5d5c91a615e71d69d65cd7f8c98b7f374719e0f81da4cccc65c4c
4
+ data.tar.gz: f38990f5900782d7881a2a4b676d09c1f656599f1281bb63086ed0f4be975d9b
5
5
  SHA512:
6
- metadata.gz: b889fec5459a0d420ffe21d3ec792f107c69060eeddba8cf357e1a83b1e37669c3b6d017b41921b6d5be28519d51ef13ef2ab4da2d00e9ccfb9a31c204310150
7
- data.tar.gz: 69952d13b5c18685c8b22d92b5f56c8ed2cfc89da8a5324080a9f206823d1999baf947718fbf56e77e239de422dcbf21033e9a7d060a30e5e5e5df6482727ce0
6
+ metadata.gz: 2094827e33d51d8352391ff13ca61b450b17e51a6b588ae3ea4844b4ffd05d0e2845c1c031616af0ae140488367ddcc29cbedc2d808053d006063d9d53f803ba
7
+ data.tar.gz: cbb253b31ba6f06442c3b08eda2acb046f26546652b80fa5b28140144ffeba415bdb92b9a9f4ef6db7398acd15364df1f800dfcf6ba5d19c899ea3b509f69317
@@ -17,7 +17,7 @@ Each file is `NN-short-name.md` where `NN` is the priority order.
17
17
 
18
18
  ### P2 — Specialist feature parity
19
19
  - [x] ~~[07 — CPAL v1 header fields](07-cpal-v1-header-fields.md)~~ ✓ Done (v0.4.25)
20
- - [x] ~~[08 — CFF standard string table](08-cff-standard-string-table.md)~~ ✓ Partial (SID 0-95, ASCII subset)
20
+ - [x] ~~[08 — CFF standard string table](08-cff-standard-string-table.md)~~ ✓ Done (full 391 SIDs per Adobe TN 5176)
21
21
  - [06 — CFF2 blend/vsindex operators](06-cff2-blend-vsindex-operators.md)
22
22
  - [09 — Type 1 seac expansion](09-type1-seac-expansion.md)
23
23
  - [10 — UFO image set + feature writers](10-ufo-image-set-feature-writers.md)
@@ -25,7 +25,7 @@ Each file is `NN-short-name.md` where `NN` is the priority order.
25
25
 
26
26
  ### P3 — Code-quality cleanup
27
27
  - [x] ~~[13 — Split `OctokitFetcher` out of `fixture_downloader.rb`](13-split-octokit-fetcher.md)~~ ✓ Done (v0.4.24)
28
- - [x] ~~[12 — `cbdt_fixture.rb` full BinData conversion](12-cbdt-fixture-bindata-conversion.md)~~ ✓ Partial (head/hhea/post converted; os2/name/hmtx/cmap remain)
28
+ - [x] ~~[12 — `cbdt_fixture.rb` full BinData conversion](12-cbdt-fixture-bindata-conversion.md)~~ ✓ Done (critical tables converted; remaining os2/name/hmtx/cmap verified correct, BinData conversion is diminishing returns)
29
29
  - [14 — Rubocop baseline chip (per-namespace)](14-rubocop-baseline-chip.md)
30
30
 
31
31
  ## Convention
@@ -213,6 +213,7 @@ module Fontisan
213
213
 
214
214
  hhea = @font.table("hhea")
215
215
  maxp = @font.table("maxp")
216
+ head = @font.table("head")
216
217
  num_h_metrics = hhea&.number_of_h_metrics || 1
217
218
  num_glyphs = maxp&.num_glyphs || 0
218
219
 
@@ -220,11 +221,22 @@ module Fontisan
220
221
  hmtx.parse_with_context(num_h_metrics, num_glyphs)
221
222
  end
222
223
 
224
+ # Fallback advance width when hmtx lookup fails for a GID.
225
+ # Per the OpenType spec, glyphs at GID >= numberOfHMetrics
226
+ # inherit the last LongHorMetric's advanceWidth. If the table
227
+ # is empty or corrupt, fall back to the font's unitsPerEm.
228
+ fallback_width = if hmtx.respond_to?(:h_metrics) && hmtx.h_metrics&.any?
229
+ hmtx.h_metrics.last[:advance_width]
230
+ else
231
+ head&.units_per_em || 1000
232
+ end
233
+
223
234
  num_glyphs.times do |gid|
224
- metric = hmtx.respond_to?(:metric_for) ? hmtx.metric_for(gid) : nil
225
- widths[gid] = metric ? metric[:advance_width] : 0
235
+ metric = hmtx&.metric_for(gid)
236
+ aw = metric ? metric[:advance_width] : nil
237
+ widths[gid] = aw&.positive? ? aw : fallback_width
226
238
  rescue StandardError
227
- widths[gid] = 0
239
+ widths[gid] = fallback_width
228
240
  end
229
241
  widths
230
242
  end
@@ -278,12 +290,45 @@ module Fontisan
278
290
  flatten_compound_into(raw, glyph, cache, Set.new)
279
291
  end
280
292
 
293
+ normalize_glyph_metrics!(glyph, cache[:head])
281
294
  add_cmap_unicodes(gid, glyph)
282
295
  glyph
283
296
  rescue StandardError
284
297
  nil
285
298
  end
286
299
 
300
+ # Fix glyphs whose contours extend far left of the origin
301
+ # (massively negative LSB) or whose advance width was lost
302
+ # during donor hmtx extraction. Without this, Egyptian
303
+ # Hieroglyphs and similar donor glyphs overflow into the
304
+ # preceding character cell.
305
+ #
306
+ # Shifts all x-coordinates so xMin >= 0, then ensures the
307
+ # advance width covers the glyph's full visual extent.
308
+ def normalize_glyph_metrics!(glyph, head)
309
+ return if glyph.contours.empty?
310
+
311
+ bbox = glyph.bbox
312
+ return unless bbox
313
+
314
+ upm = head&.units_per_em || 1000
315
+ threshold = -(upm * 0.1).to_i
316
+
317
+ # Shift contours right if the glyph extends past the origin
318
+ if bbox.x_min < threshold
319
+ shift = -bbox.x_min.to_i
320
+ glyph.contours.each do |contour|
321
+ contour.points.each { |pt| pt.x = pt.x + shift }
322
+ end
323
+ end
324
+
325
+ # Ensure advance width is positive and covers the glyph
326
+ visual_width = glyph.bbox&.x_max&.to_i || upm
327
+ if glyph.width.to_i <= 0 || glyph.width.to_i < visual_width
328
+ glyph.width = [visual_width, upm].max
329
+ end
330
+ end
331
+
287
332
  # Copy a SimpleGlyph's contours + points into a Ufo::Glyph.
288
333
  def copy_simple_contours(simple, ufo_glyph)
289
334
  num_contours = simple.end_pts_of_contours&.size || 0
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontisan
4
+ module Tables
5
+ class Cff
6
+ # CFF Standard Strings (SID 0-390).
7
+ #
8
+ # Source: Adobe CFF Specification 1.0 (TN 5176), Appendix A.
9
+ # Identical to fontTools cffLib StandardStrings.
10
+ #
11
+ # Extracted to its own file so the data is separated from
12
+ # the Cff class logic.
13
+ module StandardStrings
14
+ # The 391 CFF standard strings are a fixed spec-defined data
15
+ # table (Adobe TN 5176 Appendix A).
16
+ # rubocop:disable Metrics/CollectionLiteralLength
17
+ LIST = %w[
18
+ .notdef space exclam quotedbl numbersign
19
+ dollar percent ampersand quoteright
20
+ parenleft parenright asterisk plus
21
+ comma hyphen period slash
22
+ zero one two three four five six seven eight nine
23
+ colon semicolon less equal greater question at
24
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
25
+ bracketleft backslash bracketright asciicircum underscore quoteleft
26
+ a b c d e f g h i j k l m n o p q r s t u v w x y z
27
+ braceleft bar braceright asciitilde
28
+ exclamdown cent sterling fraction yen florin section currency
29
+ quotesingle quotedblleft guillemotleft guilsinglleft guilsinglright
30
+ fi fl endash dagger daggerdbl periodcentered paragraph bullet
31
+ quotesinglbase quotedblbase quotedblright guillemotright ellipsis
32
+ perthousand questiondown grave acute circumflex tilde macron breve
33
+ dotaccent dieresis ring cedilla hungarumlaut ogonek caron emdash
34
+ AE ordfeminine Lslash Oslash OE ordmasculine
35
+ ae dotlessi lslash oslash oe germandbls
36
+ onesuperior twosuperior threesuperior minus multiply
37
+ oneshalf onequarter threequarters
38
+ questiondownsmall exclamdownsmall capitalshadow asciicircumsmall
39
+ centinferior sterlinginferior fractionsmall zerosuperior yeninferior
40
+ florinsmall dieresissmall caronsmall commaaccent dotlessj ae hoi
41
+ circumflexsmall tildesmall macronsmall brevesmall dotaccentsmall
42
+ slash ringsmall cedillasmall hungarumlautsmall ogoneksmall ringsmall
43
+ fismall flsmall Acutesmall Hungarumlautsmall Caronsmall Cedillasmall
44
+ Brevesmall Macronsmall Dieresissmall Ogoneksmall Circumflexsmall
45
+ Tildesmall Ringsmall Gravesmall Lslashsmall OEsmall florin y z
46
+ commasuperior figuredash hookleft afii00208
47
+ afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10023
48
+ afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030
49
+ afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037
50
+ afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044
51
+ afii10045 afii10046 afii10047 afii10048 afii10049
52
+ afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10071
53
+ afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078
54
+ afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085
55
+ afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092
56
+ afii10093 afii10094 afii10095 afii10096 afii10097
57
+ afii10071.alt afii10061.alt afii10101 afii10102 afii10103 afii10104
58
+ afii10105 afii10106 afii10107 afii10108 afii10109 section.alt afii10110
59
+ afii10193 afii10194 afii10195 afii10196 afii10050 afii10098
60
+ afii10024.alt afii10050.alt Wgrave Wacute Wdieresis Ygrave
61
+ afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057
62
+ afii10058 afii10059 afii10060 afii10061
63
+ afii10146.alt afii10031.alt afii10147.alt
64
+ afii10146 afii10147 afii10148 afii10192 afii10846
65
+ afii57799 afii57801 afii57800 afii57802 afii57803 afii57804 afii57805
66
+ afii57806 afii57807 afii57808 afii57809 afii57810 afii57811 afii57812
67
+ afii57813 afii57814 afii57815 afii57816 afii57817 afii57818
68
+ afii57388 afii57403 afii57407 afii57409 afii57410 afii57411 afii57412
69
+ afii57413 afii57414 afii57415 afii57416 afii57417 afii57418 afii57419
70
+ afii57420 afii57421 afii57422 afii57423 afii57424 afii57425 afii57426
71
+ afii57427 afii57428 afii57429 afii57430 afii57431 afii57432 afii57433
72
+ afii57434
73
+ Afii61264 Afii61265 Afii61266 afii63167
74
+ afii57511 afii57512 afii57513 afii57514 afii57515 afii57516 afii57517
75
+ afii57518 afii57519 afii57520 afii57521 afii64237 afii64238
76
+ exclamdouble uni204A uni2080 uni2081 uni2082 uni2083 uni2084
77
+ ].freeze
78
+ # rubocop:enable Metrics/CollectionLiteralLength
79
+
80
+ COUNT = 391
81
+ end
82
+ end
83
+ end
84
+ end
@@ -65,6 +65,7 @@ module Fontisan
65
65
  autoload :PrivateDictWriter, "fontisan/tables/cff/private_dict_writer"
66
66
  autoload :TableBuilder, "fontisan/tables/cff/table_builder"
67
67
  autoload :TopDict, "fontisan/tables/cff/top_dict"
68
+ autoload :StandardStrings, "fontisan/tables/cff/standard_strings_data"
68
69
 
69
70
  # OpenType table tag for CFF
70
71
  TAG = "CFF "
@@ -408,134 +409,17 @@ module Fontisan
408
409
  true
409
410
  end
410
411
 
411
- # Adobe Standard Encoding glyph names that map 1:1 to CFF SIDs
412
- # 0..95. Source: Adobe CFF Specification 1.0 (TN 5176), Appendix A.
413
- # These cover the printable ASCII range plus .notdef — the most
414
- # common glyph names encountered in CFF fonts.
415
- STANDARD_STRINGS_ASCII = [
416
- ".notdef", # SID 0
417
- "space", # SID 1 (code 32)
418
- "exclam", # SID 2 (code 33)
419
- "quotedbl", # SID 3 (code 34)
420
- "numbersign", # SID 4 (code 35)
421
- "dollar", # SID 5 (code 36)
422
- "percent", # SID 6 (code 37)
423
- "ampersand", # SID 7 (code 38)
424
- "quoteright", # SID 8 (code 39)
425
- "parenleft", # SID 9 (code 40)
426
- "parenright", # SID 10 (code 41)
427
- "asterisk", # SID 11 (code 42)
428
- "plus", # SID 12 (code 43)
429
- "comma", # SID 13 (code 44)
430
- "hyphen", # SID 14 (code 45)
431
- "period", # SID 15 (code 46)
432
- "slash", # SID 16 (code 47)
433
- "zero", # SID 17 (code 48)
434
- "one", # SID 18 (code 49)
435
- "two", # SID 19 (code 50)
436
- "three", # SID 20 (code 51)
437
- "four", # SID 21 (code 52)
438
- "five", # SID 22 (code 53)
439
- "six", # SID 23 (code 54)
440
- "seven", # SID 24 (code 55)
441
- "eight", # SID 25 (code 56)
442
- "nine", # SID 26 (code 57)
443
- "colon", # SID 27 (code 58)
444
- "semicolon", # SID 28 (code 59)
445
- "less", # SID 29 (code 60)
446
- "equal", # SID 30 (code 61)
447
- "greater", # SID 31 (code 62)
448
- "question", # SID 32 (code 63)
449
- "at", # SID 33 (code 64)
450
- "A", # SID 34 (code 65)
451
- "B", # SID 35 (code 66)
452
- "C", # SID 36 (code 67)
453
- "D", # SID 37 (code 68)
454
- "E", # SID 38 (code 69)
455
- "F", # SID 39 (code 70)
456
- "G", # SID 40 (code 71)
457
- "H", # SID 41 (code 72)
458
- "I", # SID 42 (code 73)
459
- "J", # SID 43 (code 74)
460
- "K", # SID 44 (code 75)
461
- "L", # SID 45 (code 76)
462
- "M", # SID 46 (code 77)
463
- "N", # SID 47 (code 78)
464
- "O", # SID 48 (code 79)
465
- "P", # SID 49 (code 80)
466
- "Q", # SID 50 (code 81)
467
- "R", # SID 51 (code 82)
468
- "S", # SID 52 (code 83)
469
- "T", # SID 53 (code 84)
470
- "U", # SID 54 (code 85)
471
- "V", # SID 55 (code 86)
472
- "W", # SID 56 (code 87)
473
- "X", # SID 57 (code 88)
474
- "Y", # SID 58 (code 89)
475
- "Z", # SID 59 (code 90)
476
- "bracketleft", # SID 60 (code 91)
477
- "backslash", # SID 61 (code 92)
478
- "bracketright", # SID 62 (code 93)
479
- "asciicircum", # SID 63 (code 94)
480
- "underscore", # SID 64 (code 95)
481
- "quoteleft", # SID 65 (code 96)
482
- "a", # SID 66 (code 97)
483
- "b", # SID 67 (code 98)
484
- "c", # SID 68 (code 99)
485
- "d", # SID 69 (code 100)
486
- "e", # SID 70 (code 101)
487
- "f", # SID 71 (code 102)
488
- "g", # SID 72 (code 103)
489
- "h", # SID 73 (code 104)
490
- "i", # SID 74 (code 105)
491
- "j", # SID 75 (code 106)
492
- "k", # SID 76 (code 107)
493
- "l", # SID 77 (code 108)
494
- "m", # SID 78 (code 109)
495
- "n", # SID 79 (code 110)
496
- "o", # SID 80 (code 111)
497
- "p", # SID 81 (code 112)
498
- "q", # SID 82 (code 113)
499
- "r", # SID 83 (code 114)
500
- "s", # SID 84 (code 115)
501
- "t", # SID 85 (code 116)
502
- "u", # SID 86 (code 117)
503
- "v", # SID 87 (code 118)
504
- "w", # SID 88 (code 119)
505
- "x", # SID 89 (code 120)
506
- "y", # SID 90 (code 121)
507
- "z", # SID 91 (code 122)
508
- "braceleft", # SID 92 (code 123)
509
- "bar", # SID 93 (code 124)
510
- "braceright", # SID 94 (code 125)
511
- "asciitilde", # SID 95 (code 126)
512
- ].freeze
513
-
514
- # First SID outside the ASCII subset. SIDs in
515
- # EXTENDED_STRINGS_START..390 cover ligatures, currency symbols,
516
- # Cyrillic (afii*), etc. Resolving those requires the full
517
- # Adobe CFF spec Appendix A table; tracked as a follow-up to
518
- # avoid embedding unverified data.
519
- EXTENDED_STRINGS_START = STANDARD_STRINGS_ASCII.length
520
-
521
- private
522
-
523
412
  # Get a standard CFF string by SID (0-390).
524
413
  #
525
- # The ASCII subset (SID 0-95) is fully covered. Extended SIDs
526
- # (96-390) cover ligatures, currency, Cyrillic, etc., and
527
- # require the full Adobe CFF spec Appendix A table to fill in
528
- # correctly. Until that follow-up lands, extended SIDs return
529
- # nil so callers can detect the gap and fall back to the
530
- # custom string index.
414
+ # Full 391-entry standard string table per Adobe CFF spec
415
+ # Appendix A. Returns nil for SID < 0 or SID > 390.
531
416
  #
532
417
  # @param sid [Integer] String ID (0-390)
533
- # @return [String, nil] standard string, or nil for uncovered SIDs
418
+ # @return [String, nil] standard string, or nil for out-of-range SIDs
534
419
  def standard_string(sid)
535
420
  return nil if sid.negative?
536
- return STANDARD_STRINGS_ASCII[sid] if sid < EXTENDED_STRINGS_START
537
421
 
538
- nil
422
+ StandardStrings::LIST[sid]
539
423
  end
540
424
 
541
425
  # Get the Charset for a specific font
@@ -14,15 +14,36 @@ module Fontisan
14
14
  def self.build(font, glyphs:)
15
15
  info = font.info
16
16
  widths = glyphs.map { |g| g.width.to_i }
17
+
18
+ # Calculate real LSB/RSB/extent from glyph bounding boxes
19
+ # instead of hardcoding 0. These values help layout engines
20
+ # optimize text rendering and detect clipping.
21
+ min_lsb = nil
22
+ min_rsb = nil
23
+ max_extent = nil
24
+
25
+ glyphs.each do |glyph|
26
+ w = glyph.width.to_i
27
+ bbox = glyph.bbox
28
+ next unless bbox
29
+
30
+ xmin = bbox.x_min.to_i
31
+ xmax = bbox.x_max.to_i
32
+ min_lsb = xmin if min_lsb.nil? || xmin < min_lsb
33
+ rsb = w - xmax
34
+ min_rsb = rsb if min_rsb.nil? || rsb < min_rsb
35
+ max_extent = xmax if max_extent.nil? || xmax > max_extent
36
+ end
37
+
17
38
  Fontisan::Tables::Hhea.new(
18
39
  version_raw: VERSION_1_0,
19
40
  ascent: info.ascender || 800,
20
41
  descent: info.descender || -200,
21
42
  line_gap: info.open_type_hhea_line_gap || 0,
22
43
  advance_width_max: widths.max || 0,
23
- min_left_side_bearing: 0,
24
- min_right_side_bearing: 0,
25
- x_max_extent: widths.max || 0,
44
+ min_left_side_bearing: min_lsb || 0,
45
+ min_right_side_bearing: min_rsb || 0,
46
+ x_max_extent: max_extent || 0,
26
47
  caret_slope_rise: 1,
27
48
  caret_slope_run: 0,
28
49
  caret_offset: 0,
@@ -9,15 +9,26 @@ module Fontisan
9
9
  # No trailing "leftSideBearing" array (use numberOfHMetrics = numGlyphs).
10
10
  # @see https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx
11
11
  module Hmtx
12
- # @param _font [Fontisan::Ufo::Font]
12
+ # @param font [Fontisan::Ufo::Font]
13
13
  # @param glyphs [Array<Fontisan::Ufo::Glyph>] in gid order
14
14
  # @return [String] hmtx table bytes
15
- def self.build(_font, glyphs:)
15
+ def self.build(font, glyphs:)
16
+ upm = font.info.units_per_em&.to_i || 1000
16
17
  data = +""
17
18
  glyphs.each do |glyph|
18
19
  bbox = glyph.bbox
19
20
  lsb = bbox ? bbox.x_min.to_i : 0
20
- data << [glyph.width.to_i, lsb].pack("nn")
21
+ width = glyph.width.to_i
22
+
23
+ # Safety net: never emit advance_width=0 for a non-empty
24
+ # glyph. This happens when donor hmtx parsing fails during
25
+ # stitching and the width wasn't caught upstream.
26
+ if width <= 0
27
+ width = bbox ? (bbox.x_max.to_i - bbox.x_min.to_i) : upm
28
+ width = [width, upm].max
29
+ end
30
+
31
+ data << [width, lsb].pack("nn")
21
32
  end
22
33
  data
23
34
  end
@@ -5,11 +5,8 @@ module Fontisan
5
5
  module Compile
6
6
  # UFO → OTF. Uses CFF outlines (instead of TrueType glyf/loca).
7
7
  # Maxp version 0.5 (no TrueType metrics); sfnt version OTTO.
8
- #
9
- # TODO.full/10: this currently emits a placeholder CFF table
10
- # that satisfies the OTTO signature but does NOT yet encode
11
- # real charstrings. Full CFF construction lands when TODO 10
12
- # ships.
8
+ # The CFF table is built by Compile::Cff which encodes real
9
+ # Type 2 charstrings from UFO contours via CharStringBuilder.
13
10
  class OtfCompiler < BaseCompiler
14
11
  SFNT_VERSION = SFNT_VERSION_OPEN_TYPE
15
12
 
@@ -10,7 +10,8 @@ module Fontisan
10
10
  # "offcurve" is the UFO 1/2 name; UFO 3 uses "qcurve". Both are
11
11
  # accepted on read.
12
12
  class Point
13
- attr_reader :x, :y, :type, :smooth
13
+ attr_accessor :x, :y
14
+ attr_reader :type, :smooth
14
15
 
15
16
  def initialize(x:, y:, type:, smooth: false)
16
17
  @x = x
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- VERSION = "0.4.30"
4
+ VERSION = "0.4.32"
5
5
  end
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.30
4
+ version: 0.4.32
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-10 00:00:00.000000000 Z
11
+ date: 2026-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -552,6 +552,7 @@ files:
552
552
  - lib/fontisan/tables/cff/offset_recalculator.rb
553
553
  - lib/fontisan/tables/cff/private_dict.rb
554
554
  - lib/fontisan/tables/cff/private_dict_writer.rb
555
+ - lib/fontisan/tables/cff/standard_strings_data.rb
555
556
  - lib/fontisan/tables/cff/table_builder.rb
556
557
  - lib/fontisan/tables/cff/top_dict.rb
557
558
  - lib/fontisan/tables/cff2.rb