Class: Fontisan::Woff2::GlyfCanonicalizer
- Inherits:
-
Object
- Object
- Fontisan::Woff2::GlyfCanonicalizer
- Defined in:
- lib/fontisan/woff2/glyf_canonicalizer.rb
Overview
Canonicalizes a source glyf table by padding each glyph to a 4-byte boundary, matching fontTools' WOFF2 encoder behavior.
fontTools' WOFF2 writer calls _normaliseGlyfAndLoca(padding=4) before
transforming the glyf table (see Lib/fontTools/ttLib/woff2.py). Each
glyph is recompiled with recalcBBoxes=False, which makes
Glyph#compile return the source glyph bytes verbatim, then the
glyf-table-level compile pads each glyph to the configured alignment.
The result is a glyf whose bytes match the source byte-for-byte
except for added padding (≤ 3 bytes per glyph).
Chrome's OpenType Sanitizer (OTS) fails to reconstruct "unpadded" glyf tables — see the long comment in WOFF2Writer.close(): https://github.com/google/woff2/issues/15 https://github.com/khaledhosny/ots/issues/60
The canonical glyf is the bytes the WOFF2 transform encodes, the
bytes the decoder reconstructs, the bytes glyf.origLength reports,
and the bytes the SFNT checksum is computed over. All four must
agree.
Instance Method Summary collapse
-
#canonical ⇒ Hash{Symbol => String}
{ glyf:, loca: }where glyf is padded to 4-byte alignment per glyph and loca is emitted intarget_format. -
#initialize(glyf_data:, loca_data:, num_glyphs:, source_format:, target_format: nil) ⇒ GlyfCanonicalizer
constructor
A new instance of GlyfCanonicalizer.
Constructor Details
#initialize(glyf_data:, loca_data:, num_glyphs:, source_format:, target_format: nil) ⇒ GlyfCanonicalizer
Returns a new instance of GlyfCanonicalizer.
33 34 35 36 37 38 39 40 |
# File 'lib/fontisan/woff2/glyf_canonicalizer.rb', line 33 def initialize(glyf_data:, loca_data:, num_glyphs:, source_format:, target_format: nil) @glyf_data = glyf_data @loca_data = loca_data @num_glyphs = num_glyphs @source_format = source_format @target_format = target_format || source_format end |
Instance Method Details
#canonical ⇒ Hash{Symbol => String}
Returns { glyf:, loca: } where glyf is
padded to 4-byte alignment per glyph and loca is emitted in
target_format.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/fontisan/woff2/glyf_canonicalizer.rb', line 45 def canonical glyf = String.new(encoding: Encoding::BINARY) new_offsets = [0] @num_glyphs.times do |i| start_offset = source_offsets[i] end_offset = source_offsets[i + 1] if start_offset < end_offset glyf << @glyf_data.byteslice(start_offset, end_offset - start_offset) end remainder = glyf.bytesize % 4 glyf << ("\x00" * (4 - remainder)) if remainder.positive? new_offsets << glyf.bytesize end { glyf:, loca: build_loca(new_offsets) } end |