91 lines
2.3 KiB
Ruby
91 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative '../../reader'
|
|
|
|
module TTFunk
|
|
class Table
|
|
class Kern
|
|
# Format 0 kerning subtable.
|
|
class Format0
|
|
include Reader
|
|
|
|
# Subtable attributes.
|
|
# @return [Hash{Symbol => any}]
|
|
attr_reader :attributes
|
|
|
|
# Kerning pairs.
|
|
# @return [Hash{Array(Integer, Integer) => Integer}]
|
|
attr_reader :pairs
|
|
|
|
# @param attributes [Hash{Symbol => any}]
|
|
def initialize(attributes = {})
|
|
@attributes = attributes
|
|
|
|
num_pairs, *pairs = attributes.delete(:data).unpack('nx6n*')
|
|
|
|
@pairs = {}
|
|
num_pairs.times do |i|
|
|
# sanity check, in case there's a bad length somewhere
|
|
break if (i * 3) + 2 > pairs.length
|
|
|
|
left = pairs[i * 3]
|
|
right = pairs[(i * 3) + 1]
|
|
value = to_signed(pairs[(i * 3) + 2])
|
|
@pairs[[left, right]] = value
|
|
end
|
|
end
|
|
|
|
# Is this vertical kerning?
|
|
# @return [Boolean]
|
|
def vertical?
|
|
@attributes[:vertical]
|
|
end
|
|
|
|
# Is this horizontal kerning?
|
|
# @return [Boolean]
|
|
def horizontal?
|
|
!vertical?
|
|
end
|
|
|
|
# Is this cross-stream kerning?
|
|
# @return [Boolean]
|
|
def cross_stream?
|
|
@attributes[:cross]
|
|
end
|
|
|
|
# Recode this subtable using the specified mapping.
|
|
#
|
|
# @param mapping [Hash{Integer => Integer}] keys are new glyph IDs,
|
|
# values are old glyph IDs
|
|
# @return [String]
|
|
def recode(mapping)
|
|
subset = []
|
|
pairs.each do |(left, right), value|
|
|
if mapping[left] && mapping[right]
|
|
subset << [mapping[left], mapping[right], value]
|
|
end
|
|
end
|
|
|
|
return if subset.empty?
|
|
|
|
num_pairs = subset.length
|
|
search_range = 2 * (2**Integer(Math.log(num_pairs) / Math.log(2)))
|
|
entry_selector = Integer(Math.log(search_range / 2) / Math.log(2))
|
|
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
|