class TTFunk::Table::Glyf::Compound

Constants

ARG_1_AND_2_ARE_WORDS
Component
MORE_COMPONENTS
WE_HAVE_AN_X_AND_Y_SCALE
WE_HAVE_A_SCALE
WE_HAVE_A_TWO_BY_TWO
WE_HAVE_INSTRUCTIONS

Attributes

glyph_ids[R]
id[R]
number_of_contours[R]
raw[R]
x_max[R]
x_min[R]
y_max[R]
y_min[R]

Public Class Methods

new(id, raw) click to toggle source
# File lib/ttfunk/table/glyf/compound.rb, line 25
def initialize(id, raw)
  @id = id
  @raw = raw
  io = StringIO.new(raw)

  @number_of_contours, @x_min, @y_min, @x_max, @y_max =
    io.read(10).unpack('n*').map do |i|
      BinUtils.twos_comp_to_int(i, bit_width: 16)
    end

  # Because TTFunk only cares about glyphs insofar as they (1) provide
  # a bounding box for each glyph, and (2) can be rewritten into a
  # font subset, we don't really care about the rest of the glyph data
  # except as a whole. Thus, we don't actually decompose the glyph
  # into it's parts--all we really care about are the locations within
  # the raw string where the component glyph ids are stored, so that
  # when we rewrite this glyph into a subset we can rewrite the
  # component glyph-ids so they are correct for the subset.

  @glyph_ids = []
  @glyph_id_offsets = []
  offset = 10 # 2 bytes for each of num-contours, min x/y, max x/y

  loop do
    flags, glyph_id = @raw[offset, 4].unpack('n*')
    @glyph_ids << glyph_id
    @glyph_id_offsets << offset + 2

    break unless flags & MORE_COMPONENTS != 0

    offset += 4

    offset +=
      if (flags & ARG_1_AND_2_ARE_WORDS).zero?
        2
      else
        4
      end

    if flags & WE_HAVE_A_TWO_BY_TWO != 0
      offset += 8
    elsif flags & WE_HAVE_AN_X_AND_Y_SCALE != 0
      offset += 4
    elsif flags & WE_HAVE_A_SCALE != 0
      offset += 2
    end
  end
end

Public Instance Methods

compound?() click to toggle source
# File lib/ttfunk/table/glyf/compound.rb, line 74
def compound?
  true
end
recode(mapping) click to toggle source
# File lib/ttfunk/table/glyf/compound.rb, line 78
def recode(mapping)
  result = raw.dup
  new_ids = glyph_ids.map { |id| mapping[id] }

  new_ids.zip(@glyph_id_offsets).each do |new_id, offset|
    result[offset, 2] = [new_id].pack('n')
  end

  result
end