Class: Fontisan::Woff2::GlyfLocaTransform

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/woff2/glyf_loca_transform.rb

Overview

Encodes glyf + loca into the WOFF2 transformed glyf table format per WOFF2 spec section 5.1.

The loca table is reconstructed by the decoder (its data is omitted from the brotli-compressed stream). Its directory entry keeps origLength and sets transformLength = 0 per spec section 5.3.

Output layout (spec section 5.1):

uint16 version              # always 0
uint16 optionFlags          # bit 0 = overlapSimpleBitmap present
uint16 numGlyphs
uint16 indexFormat          # loca format (0=short, 1=long)
uint32 × 7 stream sizes
nContourStream:   int16[numGlyphs]
nPointsStream:    255UInt16 per contour (point count, not endpoint)
flagStream:       uint8[numPoints] (triplet flags)
glyphStream:      triplet payloads + 255UInt16 instructionLength per glyph
compositeStream:  raw component bytes per composite glyph
bboxStream:       bboxBitmap + explicit bbox int16[4] entries
instructionStream: raw instruction bytes
overlapSimpleBitmap (optional)

Defined Under Namespace

Classes: Streams

Constant Summary collapse

FLAG_ON_CURVE =

TrueType simple-glyph flag bits per OpenType spec.

0x01
FLAG_OVERLAP_SIMPLE =
0x40
ARG_1_AND_2_ARE_WORDS =

TrueType composite-glyph flag bits.

0x0001
WE_HAVE_A_SCALE =
0x0008
MORE_COMPONENTS =
0x0020
WE_HAVE_AN_X_AND_Y_SCALE =
0x0040
WE_HAVE_A_TWO_BY_TWO =
0x0080
WE_HAVE_INSTRUCTIONS =
0x0100
SIMPLE_HEADER_SIZE =

Simple glyph records start with int16 numberOfContours + 4 int16 bbox.

10

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(glyf_data:, loca_data:, num_glyphs:, index_format:) ⇒ GlyfLocaTransform

Returns a new instance of GlyfLocaTransform.

Parameters:

  • glyf_data (String)

    raw glyf table bytes

  • loca_data (String)

    raw loca table bytes

  • num_glyphs (Integer)

    from maxp

  • index_format (Integer)

    0 (short) or 1 (long), from head. Used to parse the source loca; the WOFF2 transformed glyf always emits indexFormat=0 (Chrome OTS silently rejects any other value, even though WOFF2 spec section 5.1 allows the source's indexToLocFormat).



54
55
56
57
58
59
# File 'lib/fontisan/woff2/glyf_loca_transform.rb', line 54

def initialize(glyf_data:, loca_data:, num_glyphs:, index_format:)
  @glyf_data = glyf_data
  @loca_data = loca_data
  @num_glyphs = num_glyphs
  @source_index_format = index_format
end

Instance Attribute Details

#num_glyphsObject (readonly)

Returns the value of attribute num_glyphs.



44
45
46
# File 'lib/fontisan/woff2/glyf_loca_transform.rb', line 44

def num_glyphs
  @num_glyphs
end

#source_index_formatObject (readonly)

Returns the value of attribute source_index_format.



44
45
46
# File 'lib/fontisan/woff2/glyf_loca_transform.rb', line 44

def source_index_format
  @source_index_format
end

Instance Method Details

#transformString

Encode the glyf/loca transform, returning the transformed glyf bytes.

Returns:

  • (String)

    transformed glyf bytes per spec section 5.1



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/fontisan/woff2/glyf_loca_transform.rb', line 64

def transform
  s = Streams.new(@num_glyphs)
  offsets = parse_loca_offsets

  num_glyphs.times do |glyph_id|
    start_off = offsets[glyph_id]
    end_off = offsets[glyph_id + 1]
    glyph_bytes = @glyf_data[start_off...end_off]

    if glyph_bytes.nil? || glyph_bytes.empty? || glyph_bytes.bytesize.zero?
      s.n_contour << [0].pack("s>")
      next
    end

    num_contours = read_int16(glyph_bytes, 0)
    bbox = read_bbox(glyph_bytes, 2)

    case num_contours
    when 0
      s.n_contour << [0].pack("s>")
    when -1
      encode_composite(s:, glyph_bytes:, bbox:, glyph_id:)
    else
      encode_simple(s:, glyph_bytes:, num_contours:, bbox:, glyph_id:)
    end
  end

  assemble(s)
end