This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user