module HexaPDF::Font::TrueType::Table::CmapSubtable::Format4
def self.mapper(end_codes, start_codes, id_deltas, id_range_offsets, glyph_indexes)
def self.mapper(end_codes, start_codes, id_deltas, id_range_offsets, glyph_indexes) compute_glyph_id = lambda do |index, code| offset = id_range_offsets[index] if offset == 0 glyph_id = (code + id_deltas[index]) % 65536 else glyph_id = glyph_indexes[offset - end_codes.length + (code - start_codes[index])] glyph_id ||= 0 # Handle invalid subtable entries glyph_id = (glyph_id + id_deltas[index]) % 65536 if glyph_id != 0 end glyph_id end code_map = Hash.new do |h, code| i = end_codes.bsearch_index {|c| c >= code } glyph_id = (i && start_codes[i] <= code ? compute_glyph_id.call(i, code) : 0) h[code] = glyph_id unless glyph_id == 0 end gid_map = {} end_codes.length.times do |i| start_codes[i].upto(end_codes[i]) do |code| gid_map[compute_glyph_id.call(i, code)] = code end end [code_map, gid_map] end
def self.parse(io, length)
returns the contained code map.
Parses the format 4 cmap subtable from the given IO at the current position and
Format4.parse(io, length) -> code_map
:call-seq:
def self.parse(io, length) seg_count_x2 = io.read(8).unpack1('n') end_codes = io.read(seg_count_x2).unpack('n*') io.pos += 2 start_codes = io.read(seg_count_x2).unpack('n*') id_deltas = io.read(seg_count_x2).unpack('n*') id_range_offsets = io.read(seg_count_x2).unpack('n*').map!.with_index do |offset, idx| # Change offsets to indexes, starting from the id_range_offsets array offset == 0 ? offset : offset / 2 + idx end glyph_indexes = io.read(length - 16 - seg_count_x2 * 4).unpack('n*') mapper(end_codes, start_codes, id_deltas, id_range_offsets, glyph_indexes) end