Module: HexaPDF::Font::TrueType::Builder

Defined in:
lib/hexapdf/font/true_type/builder.rb

Overview

Builds a TrueType font file given a hash of TrueType tables.

Class Method Summary collapse

Class Method Details

.build(tables) ⇒ Object

Returns a TrueType font file representing the given TrueType tables (a hash mapping table names (strings) to table data).



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
# File 'lib/hexapdf/font/true_type/builder.rb', line 46

def self.build(tables)
  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)

  # Prepare head table for checksumming
  head_table = tables['head']
  head_table[8, 4] = "\0\0\0\0"

  # The directory table needs to be sorted in ascending order by tag
  tables = tables.sort

  tables.each do |tag, data|
    original_data_length = data.length
    table_checksum = Table.calculate_checksum(data)
    data << "\0" * (4 - original_data_length % 4) if original_data_length % 4 != 0
    # tag, offset, data.length are all 32bit uint, table_checksum for header and body
    checksum += tag.unpack1('N') + 2 * table_checksum + offset + data.length
    font_data << [tag, table_checksum, offset, original_data_length].pack('a4N3')
    offset += data.length
  end

  head_table[8, 4] = [0xB1B0AFBA - checksum].pack('N')
  tables.each {|_, data| font_data << data }

  font_data
end