Class: Fontisan::Tables::Cff::DictBuilder
- Inherits:
-
Object
- Object
- Fontisan::Tables::Cff::DictBuilder
- Defined in:
- lib/fontisan/tables/cff/dict_builder.rb
Overview
CFF DICT (Dictionary) structure builder
[‘DictBuilder`](lib/fontisan/tables/cff/dict_builder.rb) constructs binary DICT structures from hash representations. DICTs in CFF use a compact operand-operator format similar to PostScript.
The builder encodes operands in various compact formats and writes operators according to the CFF specification.
Operand Encoding:
-
Small integers (-107 to +107): Single byte (32-246)
-
Medium integers (108 to 1131): Two bytes (247-250 + byte)
-
Medium integers (-1131 to -108): Two bytes (251-254 + byte)
-
Larger integers: Three bytes (28 + 2 bytes) or five bytes (29 + 4 bytes)
-
Real numbers: Nibble-encoded (30 + nibbles + 0xF terminator)
Operators:
-
Single-byte: 0-21
-
Two-byte: 12 followed by second byte
Reference: CFF specification section 4 “DICT Data” adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
Constant Summary collapse
- OPERATORS =
Operator mapping (name => byte(s))
{ version: 0, notice: 1, full_name: 2, family_name: 3, weight: 4, charset: 15, encoding: 16, charstrings: 17, private: 18, copyright: [12, 0], is_fixed_pitch: [12, 1], italic_angle: [12, 2], underline_position: [12, 3], underline_thickness: [12, 4], paint_type: [12, 5], charstring_type: [12, 6], font_matrix: [12, 7], stroke_width: [12, 8], synthetic_base: [12, 20], postscript: [12, 21], base_font_name: [12, 22], base_font_blend: [12, 23], # Private DICT operators subrs: 19, default_width_x: 20, nominal_width_x: 21, }.freeze
Class Method Summary collapse
-
.build(dict_hash) ⇒ String
Build DICT structure from hash.
Class Method Details
.build(dict_hash) ⇒ String
Build DICT structure from hash
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/fontisan/tables/cff/dict_builder.rb', line 70 def self.build(dict_hash) validate_dict!(dict_hash) return "".b if dict_hash.empty? output = StringIO.new("".b) # Encode each operator with its operands dict_hash.each do |operator_name, value| # Get operator bytes operator_bytes = operator_for_name(operator_name) raise ArgumentError, "Unknown operator: #{operator_name}" unless operator_bytes # Write operands (value can be single value or array) if value.is_a?(Array) value.each { |v| write_operand(output, v) } else write_operand(output, value) end # Write operator write_operator(output, operator_bytes) end output.string end |