Class: Fontisan::Tables::CompoundGlyph
- Inherits:
-
Object
- Object
- Fontisan::Tables::CompoundGlyph
- Defined in:
- lib/fontisan/tables/glyf/compound_glyph.rb
Overview
Represents a compound TrueType glyph composed of other glyphs
A compound glyph is built by referencing other glyphs (components) and applying transformations to them. Each component references another glyph by ID and specifies positioning and optional scaling, rotation, or affine transformation.
The glyph structure consists of:
-
Header: numberOfContours (-1), xMin, yMin, xMax, yMax (10 bytes)
-
Components: array of component descriptions (variable length)
-
Instructions: optional TrueType hinting instructions
Each component has:
-
flags (uint16): component flags
-
glyphIndex (uint16): referenced glyph ID
-
arguments: positioning (arg1, arg2) - interpretation depends on flags
-
transformation: optional scale/rotation/affine matrix
Component flags (16-bit) indicate:
-
Bit 0 (0x0001): ARG_1_AND_2_ARE_WORDS - arguments are 16-bit
-
Bit 1 (0x0002): ARGS_ARE_XY_VALUES - arguments are x,y offsets
-
Bit 2 (0x0004): ROUND_XY_TO_GRID - round x,y to grid
-
Bit 3 (0x0008): WE_HAVE_A_SCALE - uniform scale follows
-
Bit 5 (0x0020): MORE_COMPONENTS - more components follow
-
Bit 6 (0x0040): WE_HAVE_AN_X_AND_Y_SCALE - separate x,y scale
-
Bit 7 (0x0080): WE_HAVE_A_TWO_BY_TWO - 2x2 affine matrix
-
Bit 8 (0x0100): WE_HAVE_INSTRUCTIONS - instructions follow components
-
Bit 9 (0x0200): USE_MY_METRICS - use this component’s metrics
-
Bit 10 (0x0400): OVERLAP_COMPOUND - component outlines overlap
-
Bit 11 (0x0800): SCALED_COMPONENT_OFFSET - scale offset values
-
Bit 12 (0x1000): UNSCALED_COMPONENT_OFFSET - don’t scale offsets
Reference: OpenType specification, glyf table - Compound Glyph Description docs.microsoft.com/en-us/typography/opentype/spec/glyf#compound-glyph-description
Defined Under Namespace
Classes: Component
Constant Summary collapse
- ARG_1_AND_2_ARE_WORDS =
Component flag constants
0x0001- ARGS_ARE_XY_VALUES =
0x0002- ROUND_XY_TO_GRID =
0x0004- WE_HAVE_A_SCALE =
0x0008- MORE_COMPONENTS =
0x0020- WE_HAVE_AN_X_AND_Y_SCALE =
0x0040- WE_HAVE_A_TWO_BY_TWO =
0x0080- WE_HAVE_INSTRUCTIONS =
0x0100- USE_MY_METRICS =
0x0200- OVERLAP_COMPOUND =
0x0400- SCALED_COMPONENT_OFFSET =
0x0800- UNSCALED_COMPONENT_OFFSET =
0x1000
Instance Attribute Summary collapse
-
#components ⇒ Object
readonly
Compound glyph data.
-
#glyph_id ⇒ Object
readonly
Glyph header fields.
-
#instruction_length ⇒ Object
readonly
Returns the value of attribute instruction_length.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#x_max ⇒ Object
readonly
Returns the value of attribute x_max.
-
#x_min ⇒ Object
readonly
Returns the value of attribute x_min.
-
#y_max ⇒ Object
readonly
Returns the value of attribute y_max.
-
#y_min ⇒ Object
readonly
Returns the value of attribute y_min.
Class Method Summary collapse
-
.parse(data, glyph_id) ⇒ CompoundGlyph
Parse compound glyph data.
Instance Method Summary collapse
-
#bounding_box ⇒ Array<Integer>
Get bounding box as array.
-
#component_glyph_ids ⇒ Array<Integer>
Get all component glyph IDs (for dependency tracking).
-
#compound? ⇒ Boolean
Check if this is a compound glyph.
-
#empty? ⇒ Boolean
Check if glyph has no components.
-
#initialize(glyph_id) ⇒ CompoundGlyph
constructor
Initialize a new compound glyph.
-
#metrics_component ⇒ Component?
Get the component that provides metrics (if any).
-
#num_components ⇒ Integer
Get number of components.
-
#parse_data(data) ⇒ Object
Parse glyph data.
-
#simple? ⇒ Boolean
Check if this is a simple glyph.
-
#uses_component?(glyph_id) ⇒ Boolean
Check if glyph uses a specific component.
-
#uses_component_metrics? ⇒ Boolean
Check if any component uses metrics from referenced glyph.
Constructor Details
#initialize(glyph_id) ⇒ CompoundGlyph
Initialize a new compound glyph
136 137 138 139 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 136 def initialize(glyph_id) @glyph_id = glyph_id @components = [] end |
Instance Attribute Details
#components ⇒ Object (readonly)
Compound glyph data
119 120 121 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 119 def components @components end |
#glyph_id ⇒ Object (readonly)
Glyph header fields
114 115 116 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 114 def glyph_id @glyph_id end |
#instruction_length ⇒ Object (readonly)
Returns the value of attribute instruction_length.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def instruction_length @instruction_length end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def instructions @instructions end |
#x_max ⇒ Object (readonly)
Returns the value of attribute x_max.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def x_max @x_max end |
#x_min ⇒ Object (readonly)
Returns the value of attribute x_min.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def x_min @x_min end |
#y_max ⇒ Object (readonly)
Returns the value of attribute y_max.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def y_max @y_max end |
#y_min ⇒ Object (readonly)
Returns the value of attribute y_min.
115 116 117 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 115 def y_min @y_min end |
Class Method Details
.parse(data, glyph_id) ⇒ CompoundGlyph
Parse compound glyph data
127 128 129 130 131 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 127 def self.parse(data, glyph_id) glyph = new(glyph_id) glyph.parse_data(data) glyph end |
Instance Method Details
#bounding_box ⇒ Array<Integer>
Get bounding box as array
180 181 182 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 180 def bounding_box [x_min, y_min, x_max, y_max] end |
#component_glyph_ids ⇒ Array<Integer>
Get all component glyph IDs (for dependency tracking)
This method returns the glyph IDs of all components that make up this compound glyph. This is essential for subsetting operations, where all dependent glyphs must be included.
198 199 200 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 198 def component_glyph_ids components.map(&:glyph_index) end |
#compound? ⇒ Boolean
Check if this is a compound glyph
166 167 168 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 166 def compound? true end |
#empty? ⇒ Boolean
Check if glyph has no components
173 174 175 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 173 def empty? components.empty? end |
#metrics_component ⇒ Component?
Get the component that provides metrics (if any)
227 228 229 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 227 def metrics_component components.find(&:use_my_metrics?) end |
#num_components ⇒ Integer
Get number of components
213 214 215 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 213 def num_components components.length end |
#parse_data(data) ⇒ Object
Parse glyph data
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 145 def parse_data(data) io = StringIO.new(data) io.set_encoding(Encoding::BINARY) parse_header(io) parse_components(io) parse_instructions(io) if has_instructions? validate_parsed_data! end |
#simple? ⇒ Boolean
Check if this is a simple glyph
159 160 161 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 159 def simple? false end |
#uses_component?(glyph_id) ⇒ Boolean
Check if glyph uses a specific component
206 207 208 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 206 def uses_component?(glyph_id) component_glyph_ids.include?(glyph_id) end |
#uses_component_metrics? ⇒ Boolean
Check if any component uses metrics from referenced glyph
220 221 222 |
# File 'lib/fontisan/tables/glyf/compound_glyph.rb', line 220 def uses_component_metrics? components.any?(&:use_my_metrics?) end |