1 2 3 4 5 6 7 8 9 10 11 12 13 14 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
|
require 'ttfunk/reader'
module TTFunk
class Table
class Kern
class Format0
include Reader
attr_reader :attributes
attr_reader :pairs
def initialize(attributes={})
@attributes = attributes
num_pairs, search_range, entry_selector, range_shift, *pairs =
attributes.delete(:data).unpack("n*")
@pairs = {}
num_pairs.times do |i|
break if i*3+2 > pairs.length # sanity check, in case there's a bad length somewhere
left = pairs[i*3]
right = pairs[i*3+1]
value = to_signed(pairs[i*3+2])
@pairs[[left, right]] = value
end
end
def vertical?
@attributes[:vertical]
end
def horizontal?
!vertical?
end
def cross_stream?
@attributes[:cross]
end
def recode(mapping)
subset = []
pairs.each do |(left, right), value|
if mapping[left] && mapping[right]
subset << [mapping[left], mapping[right], value]
end
end
return nil if subset.empty?
num_pairs = subset.length
search_range = 2 * 2 ** (Math.log(num_pairs) / Math.log(2)).to_i
entry_selector = (Math.log(search_range / 2) / Math.log(2)).to_i
range_shift = (2 * num_pairs) - search_range
[attributes[:version], num_pairs * 6 + 14, attributes[:coverage],
num_pairs, search_range, entry_selector, range_shift, subset].
flatten.pack("n*")
end
end
end
end
end
|