Class: Fontisan::Subset::TableStrategy::GlyfLocaBuilder
- Inherits:
-
Object
- Object
- Fontisan::Subset::TableStrategy::GlyfLocaBuilder
- Defined in:
- lib/fontisan/subset/table_strategy/glyf_loca_builder.rb
Overview
Glyf + Loca are emitted together because loca is just an offset index into glyf. This builder walks the subset's glyph mapping, extracts each glyph's bytes (remapping composite component refs), and produces the new glyf bytes, the new loca offsets, and the union bounding box over the subset's glyphs.
Extracted as a collaborator so both the Glyf and Loca strategies can share a single build pass without coupling to each other or to TableSubsetter internals.
Instance Attribute Summary collapse
-
#bbox ⇒ Array(Integer, Integer, Integer, Integer)?
readonly
Union bbox as [x_min, y_min, x_max, y_max], or nil if all glyphs empty.
-
#glyf_data ⇒ String
readonly
New glyf bytes.
-
#loca_offsets ⇒ Array<Integer>
readonly
Loca offsets (one per glyph + 1).
Instance Method Summary collapse
-
#build ⇒ self
Build glyf + loca + bbox.
-
#initialize(font:, mapping:) ⇒ GlyfLocaBuilder
constructor
A new instance of GlyfLocaBuilder.
Constructor Details
#initialize(font:, mapping:) ⇒ GlyfLocaBuilder
Returns a new instance of GlyfLocaBuilder.
18 19 20 21 |
# File 'lib/fontisan/subset/table_strategy/glyf_loca_builder.rb', line 18 def initialize(font:, mapping:) @font = font @mapping = mapping end |
Instance Attribute Details
#bbox ⇒ Array(Integer, Integer, Integer, Integer)? (readonly)
Returns union bbox as [x_min, y_min, x_max, y_max], or nil if all glyphs empty.
31 32 33 |
# File 'lib/fontisan/subset/table_strategy/glyf_loca_builder.rb', line 31 def bbox @bbox end |
#glyf_data ⇒ String (readonly)
Returns new glyf bytes.
24 25 26 |
# File 'lib/fontisan/subset/table_strategy/glyf_loca_builder.rb', line 24 def glyf_data @glyf_data end |
#loca_offsets ⇒ Array<Integer> (readonly)
Returns loca offsets (one per glyph + 1).
27 28 29 |
# File 'lib/fontisan/subset/table_strategy/glyf_loca_builder.rb', line 27 def loca_offsets @loca_offsets end |
Instance Method Details
#build ⇒ self
Build glyf + loca + bbox. Idempotent — re-calling is a no-op.
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/fontisan/subset/table_strategy/glyf_loca_builder.rb', line 36 def build return self if @glyf_data glyf = @font.table("glyf") loca = @font.table("loca") head = @font.table("head") ensure_loca_parsed!(loca, head) @glyf_data = String.new(encoding: Encoding::BINARY) @loca_offsets = [] current_offset = 0 bbox_x_min = 1 << 30 bbox_y_min = 1 << 30 bbox_x_max = -(1 << 30) bbox_y_max = -(1 << 30) @mapping.old_ids.each do |old_id| @loca_offsets << current_offset offset = loca.offset_for(old_id) size = loca.size_of(old_id) next if size.nil? || size.zero? glyph_data = glyf.raw_data[offset, size] if glyph_data.bytesize >= 10 _n, gx_min, gy_min, gx_max, gy_max = glyph_data[0, 10].unpack("n5") gx_min = to_signed_16(gx_min) gy_min = to_signed_16(gy_min) gx_max = to_signed_16(gx_max) gy_max = to_signed_16(gy_max) bbox_x_min = gx_min if gx_min < bbox_x_min bbox_y_min = gy_min if gy_min < bbox_y_min bbox_x_max = gx_max if gx_max > bbox_x_max bbox_y_max = gy_max if gy_max > bbox_y_max end glyph_data = remap_compound!(glyph_data) if compound?(glyph_data) @glyf_data << glyph_data current_offset += glyph_data.bytesize end @loca_offsets << current_offset return if bbox_x_min > bbox_x_max @bbox = [bbox_x_min, bbox_y_min, bbox_x_max, bbox_y_max] self end |