Module: TTFunk::Table::Cmap::Format04
- Defined in:
- lib/ttfunk/table/cmap/format04.rb
Overview
Format 4: Segment mapping to delta values.
This module conditionally extends Subtable.
Instance Attribute Summary collapse
-
#code_map ⇒ Hash{Integer => Integer}
readonly
Code map.
-
#language ⇒ Integer
readonly
Language.
Class Method Summary collapse
-
.encode(charmap) ⇒ Hash
Encode the encoding record to format 4.
Instance Method Summary collapse
-
#[](code) ⇒ Integer
Get glyph ID for character code.
-
#supported? ⇒ true
Is this encoding record format supported?.
Instance Attribute Details
#code_map ⇒ Hash{Integer => Integer} (readonly)
Code map.
16 17 18 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 16 def code_map @code_map end |
#language ⇒ Integer (readonly)
Language.
12 13 14 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 12 def language @language end |
Class Method Details
.encode(charmap) ⇒ Hash
Encode the encoding record to format 4.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 30 def self.encode(charmap) end_codes = [] start_codes = [] next_id = 0 last = difference = nil glyph_map = { 0 => 0 } new_map = charmap.keys.sort.each_with_object({}) do |code, map| old = charmap[code] glyph_map[old] ||= next_id += 1 map[code] = { old: old, new: glyph_map[old] } delta = glyph_map[old] - code if last.nil? || delta != difference end_codes << last if last start_codes << code difference = delta end last = code map end end_codes << last if last end_codes << 0xFFFF start_codes << 0xFFFF segcount = start_codes.length # build the conversion tables deltas = [] range_offsets = [] glyph_indices = [] offset = 0 start_codes.zip(end_codes).each_with_index do |(a, b), segment| if a == 0xFFFF # We want the final 0xFFFF code to map to glyph 0. # The glyph index is calculated as glyph = charcode + delta, # which means that delta must be -0xFFFF to map character code # 0xFFFF to glyph 0. deltas << -0xFFFF range_offsets << 0 break end start_glyph_id = new_map[a][:new] if a - start_glyph_id >= 0x8000 deltas << 0 range_offsets << (2 * (glyph_indices.length + segcount - segment)) a.upto(b) { |code| glyph_indices << new_map[code][:new] } else deltas << (-a + start_glyph_id) range_offsets << 0 end offset += 2 end # format, length, language subtable = [ 4, 16 + (8 * segcount) + (2 * glyph_indices.length), 0, ].pack('nnn') search_range = 2 * (2**Integer(Math.log(segcount) / Math.log(2))) entry_selector = Integer(Math.log(search_range / 2) / Math.log(2)) range_shift = (2 * segcount) - search_range subtable << [ segcount * 2, search_range, entry_selector, range_shift, ].pack('nnnn') subtable << end_codes.pack('n*') << "\0\0" << start_codes.pack('n*') subtable << deltas.pack('n*') << range_offsets.pack('n*') subtable << glyph_indices.pack('n*') { charmap: new_map, subtable: subtable, max_glyph_id: next_id + 1 } end |
Instance Method Details
#[](code) ⇒ Integer
Get glyph ID for character code.
113 114 115 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 113 def [](code) @code_map[code] || 0 end |
#supported? ⇒ true
Is this encoding record format supported?
120 121 122 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 120 def supported? true end |