class TTFunk::Table::Cff::Index

CFF Index.

Attributes

data_reference_offset[R]
items[R]
offsets[R]

Public Instance Methods

[](index) click to toggle source

Get value by index.

@param index [Integer] @return [any]

# File lib/ttfunk/table/cff/index.rb, line 14
def [](index)
  return if index >= items_count

  entry_cache[index] ||=
    decode_item(
      index,
      data_reference_offset + offsets[index],
      offsets[index + 1] - offsets[index],
    )
end
each() { |self| ... } click to toggle source

Iterate over index items.

@overload each()

@yieldparam item [any]
@return [void]

@overload each()

@return [Enumerator]
# File lib/ttfunk/table/cff/index.rb, line 32
def each(&block)
  return to_enum(__method__) unless block

  items_count.times do |i|
    yield(self[i])
  end
end
encode(*args) click to toggle source

Encode index.

@param args all arguments are passed to ‘encode_item` method. @return [TTFunk::EncodedString]

# File lib/ttfunk/table/cff/index.rb, line 51
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
items_count() click to toggle source

Numer of items in this index.

@return [Integer]

# File lib/ttfunk/table/cff/index.rb, line 43
def items_count
  items.length
end

Private Instance Methods

decode_item(index, _offset, _length) click to toggle source

By default do nothing

# File lib/ttfunk/table/cff/index.rb, line 102
def decode_item(index, _offset, _length)
  items[index]
end
encode_items(*) click to toggle source

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

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

It gets all the arguments ‘encode` gets.

# File lib/ttfunk/table/cff/index.rb, line 97
def encode_items(*)
  items
end
encode_offset(offset, offset_size) click to toggle source
# File lib/ttfunk/table/cff/index.rb, line 106
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
entry_cache() click to toggle source
# File lib/ttfunk/table/cff/index.rb, line 85
def entry_cache
  @entry_cache ||= {}
end
parse!() click to toggle source
# File lib/ttfunk/table/cff/index.rb, line 119
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
unpack_offset(offset_data, offset_size) click to toggle source
# File lib/ttfunk/table/cff/index.rb, line 151
def unpack_offset(offset_data, offset_size)
  padding = "\x00" * (4 - offset_size)
  (padding + offset_data).unpack1('N')
end