# frozen_string_literal: true require_relative '../table' module TTFunk class Table class Hmtx < Table attr_reader :metrics attr_reader :left_side_bearings attr_reader :widths def self.encode(hmtx, mapping) metrics = mapping.keys.sort.map do |new_id| metric = hmtx.for(mapping[new_id]) [metric.advance_width, metric.left_side_bearing] end { number_of_metrics: metrics.length, table: metrics.flatten.pack('n*') } end HorizontalMetric = Struct.new(:advance_width, :left_side_bearing) def for(glyph_id) @metrics[glyph_id] || metrics_cache[glyph_id] ||= HorizontalMetric.new( @metrics.last.advance_width, @left_side_bearings[glyph_id - @metrics.length] ) end private def metrics_cache @metrics_cache ||= {} end def parse! @metrics = [] file.horizontal_header.number_of_metrics.times do advance = read(2, 'n').first lsb = read_signed(1).first @metrics.push HorizontalMetric.new(advance, lsb) end lsb_count = file.maximum_profile.num_glyphs - file.horizontal_header.number_of_metrics @left_side_bearings = read_signed(lsb_count) @widths = @metrics.map(&:advance_width) @widths += [@widths.last] * @left_side_bearings.length end end end end