Class: TTFunk::Table::Glyf::Compound
- Inherits:
-
Object
- Object
- TTFunk::Table::Glyf::Compound
- Includes:
- Reader
- Defined in:
- lib/ttfunk/table/glyf/compound.rb
Overview
Composite TrueType glyph.
Defined Under Namespace
Classes: Component
Constant Summary collapse
- ARG_1_AND_2_ARE_WORDS =
Flags bit 0: arg1 and arg2 are words.
0x0001
- WE_HAVE_A_SCALE =
Flags bit 3: there is a simple scale for the component.
0x0008
- MORE_COMPONENTS =
Flags bit 5: at least one more glyph after this one.
0x0020
- WE_HAVE_AN_X_AND_Y_SCALE =
Flags bit 6: the x direction will use a different scale from the y direction.
0x0040
- WE_HAVE_A_TWO_BY_TWO =
Flags bit 7: there is a 2 by 2 transformation that will be used to scale the component.
0x0080
- WE_HAVE_INSTRUCTIONS =
Flags bit 8: following the last component are instructions for the composite character.
0x0100
Instance Attribute Summary collapse
-
#glyph_ids ⇒ Object
readonly
IDs of compound glyphs.
-
#id ⇒ Integer
readonly
Glyph ID.
-
#number_of_contours ⇒ Integer
readonly
Number of contours in this glyph.
-
#raw ⇒ String
readonly
Binary serialization of this glyph.
-
#x_max ⇒ Integer
readonly
Maximum x for coordinate.
-
#x_min ⇒ Integer
readonly
Minimum x for coordinate.
-
#y_max ⇒ Integer
readonly
Maximum y for coordinate.
-
#y_min ⇒ Integer
readonly
Minimum y for coordinate.
Instance Method Summary collapse
-
#compound? ⇒ true
Is this a composite glyph?.
-
#initialize(id, raw) ⇒ Compound
constructor
A new instance of Compound.
-
#recode(mapping) ⇒ String
Recode glyph.
Constructor Details
#initialize(id, raw) ⇒ Compound
Returns a new instance of Compound.
Source Code
85 | def initialize(id, raw) |
86 | @id = id |
87 | @raw = raw |
88 | io = StringIO.new(raw) |
89 | |
90 | @number_of_contours, @x_min, @y_min, @x_max, @y_max = |
91 | io.read(10).unpack('n*').map { |i| |
92 | BinUtils.twos_comp_to_int(i, bit_width: 16) |
93 | }
|
94 | |
95 | # Because TTFunk only cares about glyphs insofar as they (1) provide
|
96 | # a bounding box for each glyph, and (2) can be rewritten into a
|
97 | # font subset, we don't really care about the rest of the glyph data
|
98 | # except as a whole. Thus, we don't actually decompose the glyph
|
99 | # into it's parts--all we really care about are the locations within
|
100 | # the raw string where the component glyph ids are stored, so that
|
101 | # when we rewrite this glyph into a subset we can rewrite the
|
102 | # component glyph-ids so they are correct for the subset.
|
103 | |
104 | @glyph_ids = [] |
105 | @glyph_id_offsets = [] |
106 | offset = 10 # 2 bytes for each of num-contours, min x/y, max x/y |
107 | |
108 | loop do |
109 | flags, glyph_id = @raw[offset, 4].unpack('n*') |
110 | @glyph_ids << glyph_id |
111 | @glyph_id_offsets << (offset + 2) |
112 | |
113 | break if (flags & MORE_COMPONENTS).zero? |
114 | |
115 | offset += 4 |
116 | |
117 | offset += |
118 | if (flags & ARG_1_AND_2_ARE_WORDS).zero? |
119 | 2
|
120 | else
|
121 | 4
|
122 | end
|
123 | |
124 | if flags & WE_HAVE_A_TWO_BY_TWO != 0 |
125 | offset += 8 |
126 | elsif flags & WE_HAVE_AN_X_AND_Y_SCALE != 0 |
127 | offset += 4 |
128 | elsif flags & WE_HAVE_A_SCALE != 0 |
129 | offset += 2 |
130 | end
|
131 | end
|
132 | end
|
Instance Attribute Details
#glyph_ids ⇒ Object (readonly)
IDs of compound glyphs.
Source Code
62 | def glyph_ids |
63 | @glyph_ids
|
64 | end
|
#id ⇒ Integer (readonly)
Glyph ID.
Source Code
35 | def id |
36 | @id
|
37 | end
|
#number_of_contours ⇒ Integer (readonly)
Number of contours in this glyph.
Source Code
43 | def number_of_contours |
44 | @number_of_contours
|
45 | end
|
#raw ⇒ String (readonly)
Binary serialization of this glyph.
Source Code
39 | def raw |
40 | @raw
|
41 | end
|
#x_max ⇒ Integer (readonly)
Maximum x for coordinate.
Source Code
55 | def x_max |
56 | @x_max
|
57 | end
|
#x_min ⇒ Integer (readonly)
Minimum x for coordinate.
Source Code
47 | def x_min |
48 | @x_min
|
49 | end
|
#y_max ⇒ Integer (readonly)
Maximum y for coordinate.
Source Code
59 | def y_max |
60 | @y_max
|
61 | end
|
#y_min ⇒ Integer (readonly)
Minimum y for coordinate.
Source Code
51 | def y_min |
52 | @y_min
|
53 | end
|
Instance Method Details
#compound? ⇒ true
Is this a composite glyph?
Source Code
136 | def compound? |
137 | true
|
138 | end
|
#recode(mapping) ⇒ String
Recode glyph.
Source Code
145 | def recode(mapping) |
146 | result = raw.dup |
147 | new_ids = glyph_ids.map { |id| mapping[id] } |
148 | |
149 | new_ids.zip(@glyph_id_offsets).each do |new_id, offset| |
150 | result[offset, 2] = [new_id].pack('n') |
151 | end
|
152 | |
153 | result
|
154 | end
|