Class: HexaPDF::Font::TrueType::Subsetter
- Inherits:
-
Object
- Object
- HexaPDF::Font::TrueType::Subsetter
- Defined in:
- lib/hexapdf/font/true_type/subsetter.rb
Overview
Subsets a TrueType font in the context of PDF.
TrueType fonts can be embedded into PDF either as a simple font or as a composite font. This subsetter implements the functionality needed when embedding a TrueType subset for a composite font.
This means in particular that the resulting font file cannot be used outside of the PDF.
Instance Method Summary collapse
-
#build_font ⇒ Object
Builds the subset font file and returns it as a binary string.
-
#initialize(font) ⇒ Subsetter
constructor
Creates a new Subsetter for the given TrueType Font object.
-
#use_glyph(glyph_id) ⇒ Object
Includes the glyph with the given ID in the subset and returns the new subset glyph ID.
Constructor Details
#initialize(font) ⇒ Subsetter
Creates a new Subsetter for the given TrueType Font object.
48 49 50 51 52 |
# File 'lib/hexapdf/font/true_type/subsetter.rb', line 48 def initialize(font) @font = font @glyph_map = {0 => 0} @last_id = 0 end |
Instance Method Details
#build_font ⇒ Object
Builds the subset font file and returns it as a binary string.
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/hexapdf/font/true_type/subsetter.rb', line 65 def build_font glyf, locations = build_glyf_table loca = build_loca_table(locations) hmtx = build_hmtx_table head = build_head_table(modified: Time.now, loca_type: 1) hhea = build_hhea_table(@glyph_map.size) maxp = build_maxp_table(@glyph_map.size) tables = { 'head' => head, 'hhea' => hhea, 'maxp' => maxp, 'glyf' => glyf, 'loca' => loca, 'hmtx' => hmtx, } tables['cvt '] = @font[:"cvt "].raw_data if @font[:"cvt "] tables['fpgm'] = @font[:fpgm].raw_data if @font[:fpgm] tables['prep'] = @font[:prep].raw_data if @font[:prep] search_range = 2**(tables.length.bit_length - 1) * 16 entry_selector = tables.length.bit_length - 1 range_shift = tables.length * 16 - search_range font_data = "\x0\x1\x0\x0".b + \ [tables.length, search_range, entry_selector, range_shift].pack('n4') offset = font_data.length + tables.length * 16 checksum = Table.calculate_checksum(font_data) tables.each do |tag, data| table_checksum = Table.calculate_checksum(data) # tag, offset, data.length are all 32bit uint, table_checksum for header and body checksum += tag.unpack('N').first + 2 * table_checksum + offset + data.length font_data << [tag, table_checksum, offset, data.length].pack('a4N3') offset += data.length end head[8, 4] = [0xB1B0AFBA - checksum].pack('N') tables.each_value {|data| font_data << data} font_data end |
#use_glyph(glyph_id) ⇒ Object
Includes the glyph with the given ID in the subset and returns the new subset glyph ID.
Can be called multiple times with the same glyph ID, always returning the correct new subset glyph ID.
58 59 60 61 62 |
# File 'lib/hexapdf/font/true_type/subsetter.rb', line 58 def use_glyph(glyph_id) return @glyph_map[glyph_id] if @glyph_map.key?(glyph_id) @last_id += 1 @glyph_map[glyph_id] = @last_id end |