Class: Fontisan::Tables::Cff2::FdSelect

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/tables/cff2/fd_select.rb

Overview

Builds the FDSelect subtable for CFF2, mapping glyph IDs to Font DICT indices.

Three formats:

0 — flat array: one byte per glyph
3 — range-based (compact for clustered FDs, ≤65,534 glyphs)
4 — range-based with uint32 (for >65,534 glyphs)

For single-FD fonts (all glyphs share one Font DICT), FDSelect is omitted entirely — the CFF2 Top DICT's FontDICTSelectOffset is left unset.

Class Method Summary collapse

Class Method Details

.build(assignments) ⇒ String

Returns FDSelect bytes in the most compact format.

Parameters:

  • assignments (Array<Integer>)

    FD index per glyph (length = numGlyphs)

Returns:

  • (String)

    FDSelect bytes in the most compact format



22
23
24
25
26
# File 'lib/fontisan/tables/cff2/fd_select.rb', line 22

def self.build(assignments)
  return 0.to_s if assignments.empty?

  format0_bytes(assignments)
end

.format0_bytes(assignments) ⇒ Object

Format 0: simple byte array. Best for random FD assignments. uint8 format (= 0) uint8 fontDICTIDs



31
32
33
# File 'lib/fontisan/tables/cff2/fd_select.rb', line 31

def self.format0_bytes(assignments)
  ([0] + assignments).pack("C*")
end

.format3_bytes(assignments) ⇒ Object

Format 3: range-based. Best for clustered FD assignments. uint8 format (= 3) uint16 numRanges Range3: { uint16 first, uint8 fontDICTID } uint16 sentinel (= numGlyphs)



40
41
42
43
44
45
46
47
48
# File 'lib/fontisan/tables/cff2/fd_select.rb', line 40

def self.format3_bytes(assignments)
  ranges = build_ranges(assignments)

  io = +""
  io << [3, ranges.size].pack("Cn")
  ranges.each { |first, fd| io << [first, fd].pack("nC") }
  io << [assignments.size].pack("n")
  io
end