Class: Fontisan::Tables::Cff2::CharstringParser
- Inherits:
-
Object
- Object
- Fontisan::Tables::Cff2::CharstringParser
- Defined in:
- lib/fontisan/tables/cff2/charstring_parser.rb
Overview
Type 2 CharString parser for CFF2 (variable fonts)
CFF2 CharStrings extend Type 2 CharStrings with the blend operator for variation support. The blend operator applies variation deltas to base values based on design space coordinates.
Blend Operator (operator 16):
-
Takes N*K+1 operands where:
-
N = number of design variation axes
-
K = number of values to blend
-
-
Format: [v1, Δv1_axis1, Δv1_axis2, …, v2, Δv2_axis1, …, K, N, blend]
-
Produces K blended values on the stack
Example for 2 axes (wght, wdth) blending 3 values:
Input: [100, 10, 5, 200, 20, 10, 50, 5, 2, 3, 2, blend]
- v1=100 with deltas [10, 5]
- v2=200 with deltas [20, 10]
- v3=50 with deltas [5, 2]
- K=3 (number of values), N=2 (number of axes)
Reference: Adobe Technical Note #5177 (CFF2 specification)
Constant Summary collapse
- BLEND_OPERATOR =
CFF2-specific operators
16
Instance Attribute Summary collapse
-
#blend_data ⇒ Array<Hash>
readonly
Blend operator data.
-
#data ⇒ String
readonly
Binary CharString data.
-
#num_axes ⇒ Integer
readonly
Number of variation axes.
-
#path ⇒ Array<Hash>
readonly
Parsed path commands.
-
#width ⇒ Integer?
readonly
Glyph width.
-
#x ⇒ Float
readonly
Current X coordinate.
-
#y ⇒ Float
readonly
Current Y coordinate.
Instance Method Summary collapse
-
#blend_values(coordinates) ⇒ Array<Float>
Get blended values for a specific set of coordinates.
-
#initialize(data, num_axes = 0, global_subrs = nil, local_subrs = nil, vsindex = 0) ⇒ CharstringParser
constructor
Initialize parser.
-
#parse ⇒ self
Parse the CharString.
-
#to_commands ⇒ Array<Array>
Convert path to drawing commands.
Constructor Details
#initialize(data, num_axes = 0, global_subrs = nil, local_subrs = nil, vsindex = 0) ⇒ CharstringParser
Initialize parser
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 71 def initialize(data, num_axes = 0, global_subrs = nil, local_subrs = nil, vsindex = 0) @data = data @num_axes = num_axes @global_subrs = global_subrs @local_subrs = local_subrs @vsindex = vsindex @path = [] @blend_data = [] @x = 0.0 @y = 0.0 @width = nil @stems = 0 end |
Instance Attribute Details
#blend_data ⇒ Array<Hash> (readonly)
Returns Blend operator data.
50 51 52 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 50 def blend_data @blend_data end |
#data ⇒ String (readonly)
Returns Binary CharString data.
41 42 43 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 41 def data @data end |
#num_axes ⇒ Integer (readonly)
Returns Number of variation axes.
44 45 46 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 44 def num_axes @num_axes end |
#path ⇒ Array<Hash> (readonly)
Returns Parsed path commands.
47 48 49 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 47 def path @path end |
#width ⇒ Integer? (readonly)
Returns Glyph width.
59 60 61 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 59 def width @width end |
#x ⇒ Float (readonly)
Returns Current X coordinate.
53 54 55 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 53 def x @x end |
#y ⇒ Float (readonly)
Returns Current Y coordinate.
56 57 58 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 56 def y @y end |
Instance Method Details
#blend_values(coordinates) ⇒ Array<Float>
Get blended values for a specific set of coordinates
106 107 108 109 110 111 112 113 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 106 def blend_values(coordinates) return [] if @blend_data.empty? # Apply blend operations with coordinates @blend_data.map do |blend_op| apply_blend(blend_op, coordinates) end.flatten end |
#parse ⇒ self
Parse the CharString
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 89 def parse return self if @parsed @stack = [] @io = StringIO.new(@data) @io.set_encoding(Encoding::BINARY) parse_charstring_program @parsed = true self end |
#to_commands ⇒ Array<Array>
Convert path to drawing commands
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/fontisan/tables/cff2/charstring_parser.rb', line 118 def to_commands @path.map do |cmd| case cmd[:type] when :move_to [:move_to, cmd[:x], cmd[:y]] when :line_to [:line_to, cmd[:x], cmd[:y]] when :curve_to [:curve_to, cmd[:x1], cmd[:y1], cmd[:x2], cmd[:y2], cmd[:x], cmd[:y]] end end end |