Module: Fontisan::Ufo::Compile::Gpos
- Defined in:
- lib/fontisan/ufo/compile/gpos.rb
Overview
Builds the OpenType GPOS (Glyph Positioning) table from UFO
kerning data. Emits a minimal but valid GPOS with:
- ScriptList: DFLT script, default language system
- FeatureList: `kern` feature (feature tag "kern")
- LookupList: one PairPos lookup (format 1, individual pairs)
Each kerning pair from the UFO source becomes a PairPosRecord with an x-advance adjustment on the first glyph.
Constant Summary collapse
- FEATURE_KERN =
"kern"- SCRIPT_DFLT =
"DFLT"- LANGSYS_DEFAULT =
0- VALUE_X_PLACEMENT =
ValueFormat flags (which fields are present in a ValueRecord)
0x0001- VALUE_Y_PLACEMENT =
0x0002- VALUE_X_ADVANCE =
0x0004- VALUE_Y_ADVANCE =
0x0008
Class Method Summary collapse
-
.build(font, glyphs:) ⇒ String?
GPOS table bytes, or nil if no kerning.
-
.collect_kerning_pairs(font, glyphs) ⇒ Array<[Integer, Integer, Integer]>
Collect kerning pairs from the UFO model.
-
.resolve_kerning_side(name, font) ⇒ Array<String>
Resolve a kerning key side to individual glyph names.
Class Method Details
.build(font, glyphs:) ⇒ String?
Returns GPOS table bytes, or nil if no kerning.
33 34 35 36 37 38 |
# File 'lib/fontisan/ufo/compile/gpos.rb', line 33 def self.build(font, glyphs:) pairs = collect_kerning_pairs(font, glyphs) return nil if pairs.empty? build_gpos_table(pairs) end |
.collect_kerning_pairs(font, glyphs) ⇒ Array<[Integer, Integer, Integer]>
Collect kerning pairs from the UFO model. Each pair is (gid1, gid2, x_advance_delta). Resolves class-based kerning keys (e.g. "@MMK_L_A @MMK_R_T") by expanding group members into individual glyph pairs via font.groups.
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 |
# File 'lib/fontisan/ufo/compile/gpos.rb', line 47 def self.collect_kerning_pairs(font, glyphs) name_to_gid = {} glyphs.each_with_index { |g, gid| name_to_gid[g.name] = gid } pairs = [] font.kerning.each_pair do |key, value| names = key.split next unless names.size == 2 left_names = resolve_kerning_side(names[0], font) right_names = resolve_kerning_side(names[1], font) left_names.each do |ln| right_names.each do |rn| gid1 = name_to_gid[ln] gid2 = name_to_gid[rn] next unless gid1 && gid2 pairs << [gid1, gid2, value.to_i] end end end pairs.sort_by { |a| [a[0], a[1]] } end |
.resolve_kerning_side(name, font) ⇒ Array<String>
Resolve a kerning key side to individual glyph names. If
name is a group reference (starts with "@"), returns all
group members. Otherwise returns [name] for an individual
glyph.
80 81 82 83 84 85 |
# File 'lib/fontisan/ufo/compile/gpos.rb', line 80 def self.resolve_kerning_side(name, font) return [name] unless name.start_with?("@") members = font.groups.glyphs(name) members.empty? ? [] : members end |