Module: TTFunk::Table::Cmap::Format04
- Defined in:
- lib/ttfunk/table/cmap/format04.rb
Instance Attribute Summary collapse
-
#code_map ⇒ Object
readonly
Returns the value of attribute code_map.
-
#language ⇒ Object
readonly
Returns the value of attribute language.
Class Method Summary collapse
-
.encode(charmap) ⇒ Object
Expects a hash mapping character codes to glyph ids (where the glyph ids are from the original font).
Instance Method Summary collapse
Instance Attribute Details
#code_map ⇒ Object (readonly)
Returns the value of attribute code_map.
7 8 9 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 7 def code_map @code_map end |
#language ⇒ Object (readonly)
Returns the value of attribute language.
6 7 8 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 6 def language @language end |
Class Method Details
.encode(charmap) ⇒ Object
Expects a hash mapping character codes to glyph ids (where the glyph ids are from the original font). Returns a hash including a new map (:charmap) that maps the characters in charmap to a another hash containing both the old (:old) and new (:new) glyph ids. The returned hash also includes a :subtable key, which contains the encoded subtable for the given charmap.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 15 def self.encode(charmap) end_codes = [] start_codes = [] next_id = 0 last = difference = nil glyph_map = { 0 => 0 } new_map = charmap.keys.sort.inject({}) do |map, code| 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 deltas << 0 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 ** (Math.log(segcount) / Math.log(2)).to_i entry_selector = (Math.log(search_range / 2) / Math.log(2)).to_i 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*") << glyph_indices.pack("n*") { :charmap => new_map, :subtable => subtable, :max_glyph_id => next_id+1 } end |
Instance Method Details
#[](code) ⇒ Object
82 83 84 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 82 def [](code) @code_map[code] || 0 end |
#supported? ⇒ Boolean
86 87 88 |
# File 'lib/ttfunk/table/cmap/format04.rb', line 86 def supported? true end |