require 'ttfunk/table' module TTFunk class Table class Kern < Table attr_reader :version attr_reader :tables def self.encode(kerning, mapping) return nil unless kerning.exists? && kerning.tables.any? tables = kerning.tables.map { |table| table.recode(mapping) }.compact return nil if tables.empty? [0, tables.length, tables.join].pack("nnA*") end private def parse! @version, num_tables = read(4, "n*") @tables = [] if @version == 1 # Mac OS X fonts @version = (@version << 16) + num_tables num_tables = read(4, "N").first parse_version_1_tables(num_tables) else parse_version_0_tables(num_tables) end end def parse_version_0_tables(num_tables) # It looks like some MS fonts report their kerning subtable lengths # wrong. In one case, the length was reported to be some 19366, and yet # the table also claimed to hold 14148 pairs (each pair consisting of 6 bytes). # You do the math! # # We're going to assume that the microsoft fonts hold only a single kerning # subtable, which occupies the entire length of the kerning table. Worst # case, we lose any other subtables that the font contains, but it's better # than reading a truncated kerning table. # # And what's more, it appears to work. So. version, length, coverage = read(6, "n*") format = coverage >> 8 add_table format, :version => version, :length => length, :coverage => coverage, :data => raw[10..-1], :vertical => (coverage & 0x1 == 0), :minimum => (coverage & 0x2 != 0), :cross => (coverage & 0x4 != 0), :override => (coverage & 0x8 != 0) end def parse_version_1_tables(num_tables) num_tables.times do length, coverage, tuple_index = read(8, "Nnn") format = coverage & 0x0FF add_table format, :length => length, :coverage => coverage, :tuple_index => tuple_index, :data => io.read(length-8), :vertical => (coverage & 0x8000 != 0), :cross => (coverage & 0x4000 != 0), :variation => (coverage & 0x2000 != 0) end end def add_table(format, attributes={}) if format == 0 @tables << Kern::Format0.new(attributes) else # silently ignore unsupported kerning tables end end end end end require 'ttfunk/table/kern/format0'