Class: Fontisan::Tables::Cff2::DictEncoder
- Inherits:
-
Object
- Object
- Fontisan::Tables::Cff2::DictEncoder
- Defined in:
- lib/fontisan/tables/cff2/dict_encoder.rb
Overview
Encodes CFF2 DICT data: sequences of (operands, operator) pairs.
CFF2 DICTs use the same operand encoding as CFF1:
32..246 → integer (value = b0 - 139, range -107..107)
247..250 → integer (positive, 2 bytes, range 108..1131)
251..254 → integer (negative, 2 bytes, range -1131..-108)
28 → integer (3 bytes, range -32768..32767)
29 → integer (5 bytes, full int32)
30 → real (BCD nibble encoding)
Operators are 1 byte (0..21) or 2 bytes (12, xx) for escapes.
Class Method Summary collapse
-
.encode_entry(operands, operator) ⇒ String
Encode a DICT entry: operands followed by operator.
-
.encode_integer(value) ⇒ String
Encode a single integer operand.
- .encode_operator(operator) ⇒ String
-
.encode_real(value) ⇒ String
Encode a real number operand using BCD nibble encoding.
Class Method Details
.encode_entry(operands, operator) ⇒ String
Encode a DICT entry: operands followed by operator.
57 58 59 60 61 62 63 64 |
# File 'lib/fontisan/tables/cff2/dict_encoder.rb', line 57 def self.encode_entry(operands, operator) io = +"" operands.each do |operand| io << (operand.is_a?(Float) ? encode_real(operand) : encode_integer(operand.to_i)) end io << encode_operator(operator) io end |
.encode_integer(value) ⇒ String
Encode a single integer operand.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/fontisan/tables/cff2/dict_encoder.rb', line 21 def self.encode_integer(value) case value when -107..107 [value + 139].pack("C") when 108..1131 v = value - 108 [(v >> 8) + 247, v & 0xFF].pack("CC") when -1131..-108 v = -value - 108 [(-(v >> 8)) + 251, -(v & 0xFF) & 0xFF].pack("CC") when -32768..32767 [28, value].pack("Cn") else [29, value].pack("CN") # 29 + 4-byte signed int (big-endian) end end |
.encode_operator(operator) ⇒ String
68 69 70 |
# File 'lib/fontisan/tables/cff2/dict_encoder.rb', line 68 def self.encode_operator(operator) operator.is_a?(Array) ? operator.pack("C*") : [operator].pack("C") end |
.encode_real(value) ⇒ String
Encode a real number operand using BCD nibble encoding.
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/fontisan/tables/cff2/dict_encoder.rb', line 41 def self.encode_real(value) nibbles = real_to_nibbles(value) nibbles << 0x0F # end-of-number marker nibbles << 0x0F if nibbles.size.odd? # pad to even io = +"" nibbles.each_slice(2) do |high, low| io << [(high << 4) | (low & 0x0F)].pack("C") end [30].pack("C") + io # prefix with operator byte 30 end |