class TTFunk::Table::Cff::Index

CFF Index.

def [](index)

Returns:
  • (any) -

Parameters:
  • index (Integer) --
def [](index)
  return if index >= items_count
  entry_cache[index] ||=
    decode_item(
      index,
      data_reference_offset + offsets[index],
      offsets[index + 1] - offsets[index],
    )
end

def decode_item(index, _offset, _length)

By default do nothing
def decode_item(index, _offset, _length)
  items[index]
end

def each(&block)

Returns:
  • (Enumerator) -
  • (void) -

Overloads:
  • each()
  • each()

Other tags:
    Yieldparam: item -
def each(&block)
  return to_enum(__method__) unless block
  items_count.times do |i|
    yield(self[i])
  end
end

def encode(*args)

Returns:
  • (TTFunk::EncodedString) -

Parameters:
  • args () -- all arguments are passed to `encode_item` method.
def encode(*args)
  new_items = encode_items(*args)
  if new_items.empty?
    return [0].pack('n')
  end
  if new_items.length > 0xffff
    raise Error, 'Too many items in a CFF index'
  end
  offsets_array =
    new_items
      .each_with_object([1]) { |item, offsets|
        offsets << (offsets.last + item.length)
      }
  offset_size = (offsets_array.last.bit_length / 8.0).ceil
  offsets_array.map! { |offset| encode_offset(offset, offset_size) }
  EncodedString.new.concat(
    [new_items.length, offset_size].pack('nC'),
    *offsets_array,
    *new_items,
  )
end

def encode_items(*)

It gets all the arguments `encode` gets.

item encoding.
This is the place to do all the filtering, reordering, or individual

represent an encoded item.
placeholders, or EncodedString instances). Each element is supposed to
Returns an array of EncodedString elements (plain strings,
def encode_items(*)
  items
end

def encode_offset(offset, offset_size)

def encode_offset(offset, offset_size)
  case offset_size
  when 1
    [offset].pack('C')
  when 2
    [offset].pack('n')
  when 3
    [offset].pack('N')[1..]
  when 4
    [offset].pack('N')
  end
end

def entry_cache

def entry_cache
  @entry_cache ||= {}
end

def items_count

Returns:
  • (Integer) -
def items_count
  items.length
end

def parse!

def parse!
  @entry_cache = {}
  num_entries = read(2, 'n').first
  if num_entries.zero?
    @length = 2
    @items = []
    return
  end
  offset_size = read(1, 'C').first
  @offsets =
    Array.new(num_entries + 1) {
      unpack_offset(io.read(offset_size), offset_size)
    }
  @data_reference_offset = table_offset + 3 + (offsets.length * offset_size) - 1
  @length =
    2 + # num entries
    1 + # offset size
    (offsets.length * offset_size) + # offsets
    offsets.last - 1 # items
  @items =
    offsets.each_cons(2).map { |offset, next_offset|
      io.read(next_offset - offset)
    }
end

def unpack_offset(offset_data, offset_size)

def unpack_offset(offset_data, offset_size)
  padding = "\x00" * (4 - offset_size)
  (padding + offset_data).unpack1('N')
end