1
- <?php
2
- /**
3
- * @package php-font-lib
4
- * @link https://github.com/PhenX/php-font-lib
5
- * @author Fabien Ménager <[email protected] >
6
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
- * @version $Id: font_table_glyf.cls.php 46 2012-04-02 20:22:38Z fabien.menager $
8
- */
9
-
10
- /**
11
- * `glyf` font table.
12
- *
13
- * @package php-font-lib
14
- */
15
- class Font_Glyph_Outline_Composite extends Font_Glyph_Outline {
16
- public $ flags ;
17
- public $ glyphIndex ;
18
-
19
- function parseData (){
20
- parent ::parseData ();
21
-
22
- $ font = $ this ->getFont ();
23
-
24
- $ this ->flags = $ font ->readUInt16 ();
25
- $ this ->glyphIndex = $ font ->readUInt16 ();
26
- }
1
+ <?php
2
+ /**
3
+ * @package php-font-lib
4
+ * @link https://github.com/PhenX/php-font-lib
5
+ * @author Fabien Ménager <[email protected] >
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ * @version $Id: font_table_glyf.cls.php 46 2012-04-02 20:22:38Z fabien.menager $
8
+ */
9
+
10
+ require_once dirname (__FILE__ )."/font_glyph_outline_component.cls.php " ;
11
+
12
+ /**
13
+ * Composite glyph outline
14
+ *
15
+ * @package php-font-lib
16
+ */
17
+ class Font_Glyph_Outline_Composite extends Font_Glyph_Outline {
18
+ const ARG_1_AND_2_ARE_WORDS = 0x0001 ;
19
+ const ARGS_ARE_XY_VALUES = 0x0002 ;
20
+ const ROUND_XY_TO_GRID = 0x0004 ;
21
+ const WE_HAVE_A_SCALE = 0x0008 ;
22
+ const MORE_COMPONENTS = 0x0020 ;
23
+ const WE_HAVE_AN_X_AND_Y_SCALE = 0x0040 ;
24
+ const WE_HAVE_A_TWO_BY_TWO = 0x0080 ;
25
+ const WE_HAVE_INSTRUCTIONS = 0x0100 ;
26
+ const USE_MY_METRICS = 0x0200 ;
27
+ const OVERLAP_COMPOUND = 0x0400 ;
28
+
29
+ /**
30
+ * @var Font_Glyph_Outline_Component[]
31
+ */
32
+ public $ components = array ();
33
+
34
+ function getGlyphIDs (){
35
+ if (empty ($ this ->components )) {
36
+ $ this ->parseData ();
37
+ }
38
+
39
+ $ glyphIDs = array ();
40
+ foreach ($ this ->components as $ _component ) {
41
+ $ glyphIDs [] = $ _component ->glyphIndex ;
42
+ }
43
+
44
+ return $ glyphIDs ;
45
+ }
46
+
47
+ /*function parse() {
48
+ //$this->parseData();
49
+ }*/
50
+
51
+ function parseData (){
52
+ parent ::parseData ();
53
+
54
+ $ font = $ this ->getFont ();
55
+
56
+ do {
57
+ $ flags = $ font ->readUInt16 ();
58
+ $ glyphIndex = $ font ->readUInt16 ();
59
+
60
+ $ a = 1.0 ; $ b = 0.0 ;
61
+ $ c = 0.0 ; $ d = 1.0 ;
62
+ $ e = 0.0 ; $ f = 0.0 ;
63
+
64
+ $ point_compound = null ;
65
+ $ point_component = null ;
66
+
67
+ $ instructions = null ;
68
+
69
+ if ($ flags & self ::ARG_1_AND_2_ARE_WORDS ) {
70
+ if ($ flags & self ::ARGS_ARE_XY_VALUES ) {
71
+ $ e = $ font ->readInt16 ();
72
+ $ f = $ font ->readInt16 ();
73
+ }
74
+ else {
75
+ $ point_compound = $ font ->readUInt16 ();
76
+ $ point_component = $ font ->readUInt16 ();
77
+ }
78
+ }
79
+ else {
80
+ if ($ flags & self ::ARGS_ARE_XY_VALUES ) {
81
+ $ e = $ font ->readInt8 ();
82
+ $ f = $ font ->readInt8 ();
83
+ }
84
+ else {
85
+ $ point_compound = $ font ->readUInt8 ();
86
+ $ point_component = $ font ->readUInt8 ();
87
+ }
88
+ }
89
+
90
+ if ($ flags & self ::WE_HAVE_A_SCALE ) {
91
+ $ a = $ d = $ font ->readInt16 ();
92
+ }
93
+ elseif ($ flags & self ::WE_HAVE_AN_X_AND_Y_SCALE ) {
94
+ $ a = $ font ->readInt16 ();
95
+ $ d = $ font ->readInt16 ();
96
+ }
97
+ elseif ($ flags & self ::WE_HAVE_A_TWO_BY_TWO ) {
98
+ $ a = $ font ->readInt16 ();
99
+ $ b = $ font ->readInt16 ();
100
+ $ c = $ font ->readInt16 ();
101
+ $ d = $ font ->readInt16 ();
102
+ }
103
+
104
+ //if ($flags & self::WE_HAVE_INSTRUCTIONS) {
105
+ //
106
+ //}
107
+
108
+ $ component = new Font_Glyph_Outline_Component ();
109
+ $ component ->flags = $ flags ;
110
+ $ component ->glyphIndex = $ glyphIndex ;
111
+ $ component ->a = $ a ;
112
+ $ component ->b = $ b ;
113
+ $ component ->c = $ c ;
114
+ $ component ->d = $ d ;
115
+ $ component ->e = $ e ;
116
+ $ component ->f = $ f ;
117
+ $ component ->point_compound = $ point_compound ;
118
+ $ component ->point_component = $ point_component ;
119
+ $ component ->instructions = $ instructions ;
120
+
121
+ $ this ->components [] = $ component ;
122
+
123
+ } while ($ flags & self ::MORE_COMPONENTS );
124
+ }
125
+
126
+ function encode (){
127
+ $ font = $ this ->getFont ();
128
+
129
+ $ gids = array_values ($ font ->getSubset ());
130
+
131
+ $ size = $ font ->writeInt16 (-1 );
132
+ $ size += $ font ->writeFWord ($ this ->xMin );
133
+ $ size += $ font ->writeFWord ($ this ->yMin );
134
+ $ size += $ font ->writeFWord ($ this ->xMax );
135
+ $ size += $ font ->writeFWord ($ this ->yMax );
136
+
137
+ foreach ($ this ->components as $ _i => $ _component ) {
138
+ $ flags = 0 ;
139
+ if ($ _component ->point_component === null && $ _component ->point_compound === null ) {
140
+ $ flags |= self ::ARGS_ARE_XY_VALUES ;
141
+
142
+ if (abs ($ _component ->e ) > 0x7F || abs ($ _component ->f ) > 0x7F ) {
143
+ $ flags |= self ::ARG_1_AND_2_ARE_WORDS ;
144
+ }
145
+ }
146
+ elseif ($ _component ->point_component > 0xFF || $ _component ->point_compound > 0xFF ) {
147
+ $ flags |= self ::ARG_1_AND_2_ARE_WORDS ;
148
+ }
149
+
150
+ if ($ _component ->b == 0 && $ _component ->c == 0 ) {
151
+ if ($ _component ->a == $ _component ->d ) {
152
+ if ($ _component ->a != 1.0 ) {
153
+ $ flags |= self ::WE_HAVE_A_SCALE ;
154
+ }
155
+ }
156
+ else {
157
+ $ flags |= self ::WE_HAVE_AN_X_AND_Y_SCALE ;
158
+ }
159
+ }
160
+ else {
161
+ $ flags |= self ::WE_HAVE_A_TWO_BY_TWO ;
162
+ }
163
+
164
+ if ($ _i < count ($ this ->components )-1 ) {
165
+ $ flags |= self ::MORE_COMPONENTS ;
166
+ }
167
+
168
+ $ size += $ font ->writeUInt16 ($ flags );
169
+
170
+ $ new_gid = array_search ($ _component ->glyphIndex , $ gids );
171
+ $ size += $ font ->writeUInt16 ($ new_gid );
172
+
173
+ if ($ flags & self ::ARG_1_AND_2_ARE_WORDS ) {
174
+ if ($ flags & self ::ARGS_ARE_XY_VALUES ) {
175
+ $ size += $ font ->writeInt16 ($ _component ->e );
176
+ $ size += $ font ->writeInt16 ($ _component ->f );
177
+ }
178
+ else {
179
+ $ size += $ font ->writeUInt16 ($ _component ->point_compound );
180
+ $ size += $ font ->writeUInt16 ($ _component ->point_component );
181
+ }
182
+ }
183
+ else {
184
+ if ($ flags & self ::ARGS_ARE_XY_VALUES ) {
185
+ $ size += $ font ->writeInt8 ($ _component ->e );
186
+ $ size += $ font ->writeInt8 ($ _component ->f );
187
+ }
188
+ else {
189
+ $ size += $ font ->writeUInt8 ($ _component ->point_compound );
190
+ $ size += $ font ->writeUInt8 ($ _component ->point_component );
191
+ }
192
+ }
193
+
194
+ if ($ flags & self ::WE_HAVE_A_SCALE ) {
195
+ $ size += $ font ->writeInt16 ($ _component ->a );
196
+ }
197
+ elseif ($ flags & self ::WE_HAVE_AN_X_AND_Y_SCALE ) {
198
+ $ size += $ font ->writeInt16 ($ _component ->a );
199
+ $ size += $ font ->writeInt16 ($ _component ->d );
200
+ }
201
+ elseif ($ flags & self ::WE_HAVE_A_TWO_BY_TWO ) {
202
+ $ size += $ font ->writeInt16 ($ _component ->a );
203
+ $ size += $ font ->writeInt16 ($ _component ->b );
204
+ $ size += $ font ->writeInt16 ($ _component ->c );
205
+ $ size += $ font ->writeInt16 ($ _component ->d );
206
+ }
207
+ }
208
+
209
+ return $ size ;
210
+ }
211
+
212
+ public function getSVGContours (){
213
+ $ path = "" ;
214
+
215
+ /** @var Font_Table_glyf $glyph_data */
216
+ $ glyph_data = $ this ->getFont ()->getTableObject ("glyf " );
217
+
218
+ $ glyphs = $ glyph_data ->data ;
219
+
220
+ foreach ($ this ->components as $ component ) {
221
+ $ path .= $ glyphs [$ component ->glyphIndex ]->getSVGContours ();
222
+ }
223
+
224
+ return $ path ;
225
+ }
27
226
}
0 commit comments