module HexaPDF::Font::TrueType::Table::CmapSubtable::Format2

Cmap format 2

Constants

SubHeader

Public Class Methods

parse(io, length) → code_map click to toggle source

Parses the format 2 cmap subtable from the given IO at the current position and returns the contained code map.

It is assumed that the first six bytes of the subtable have already been consumed.

# File lib/hexapdf/font/true_type/table/cmap_subtable.rb, line 198
def self.parse(io, length)
  sub_header_keys = io.read(512).unpack('n*')
  nr_sub_headers = 0
  sub_header_keys.map! do |key|
    nr_sub_headers = key if key > nr_sub_headers
    key / 8
  end
  nr_sub_headers = 1 + nr_sub_headers / 8

  sub_headers = []
  nr_sub_headers.times do |i|
    h = SubHeader.new(*io.read(8).unpack('n2s>n'))
    # Map the currently stored id_range_offset to the corresponding glyph index by first
    # changing the offset to begin from the position of the first glyph index and then
    # halfing the value since each glyph is a UInt16.
    h.first_glyph_index = (h.first_glyph_index - 2 - 8 * (nr_sub_headers - i - 1)) / 2
    sub_headers << h
  end
  glyph_indexes = io.read(length - 6 - 512 - 8 * nr_sub_headers).unpack('n*')

  gid_map = {}
  sub_headers.each_with_index do |sub_header, i|
    sub_header.entry_count.times do |j|
      glyph_id = glyph_indexes[sub_header.first_glyph_index + j]
      glyph_id = (glyph_id + sub_header.id_delta) % 65536 if glyph_id != 0
      gid_map[glyph_id] = (sub_header_keys.index(i) << 8) + j + sub_header.first_code
    end
  end

  [mapper(sub_header_keys, sub_headers, glyph_indexes), gid_map]
end