Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / phenx / php-font-lib / src / FontLib / Glyph / OutlineComposite.php
1 <?php
2 /**
3  * @package php-font-lib
4  * @link    https://github.com/PhenX/php-font-lib
5  * @author  Fabien Ménager <fabien.menager@gmail.com>
6  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7  * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $
8  */
9
10 namespace FontLib\Glyph;
11
12 /**
13  * Composite glyph outline
14  *
15  * @package php-font-lib
16  */
17 class OutlineComposite extends 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 OutlineComponent[]
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       $_glyph   = $this->table->data[$_component->glyphIndex];
44
45       if ($_glyph !== $this) {
46         $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs());
47       }
48     }
49
50     return $glyphIDs;
51   }
52
53   /*function parse() {
54     //$this->parseData();
55   }*/
56
57   function parseData() {
58     parent::parseData();
59
60     $font = $this->getFont();
61
62     do {
63       $flags      = $font->readUInt16();
64       $glyphIndex = $font->readUInt16();
65
66       $a = 1.0;
67       $b = 0.0;
68       $c = 0.0;
69       $d = 1.0;
70       $e = 0.0;
71       $f = 0.0;
72
73       $point_compound  = null;
74       $point_component = null;
75
76       $instructions = null;
77
78       if ($flags & self::ARG_1_AND_2_ARE_WORDS) {
79         if ($flags & self::ARGS_ARE_XY_VALUES) {
80           $e = $font->readInt16();
81           $f = $font->readInt16();
82         }
83         else {
84           $point_compound  = $font->readUInt16();
85           $point_component = $font->readUInt16();
86         }
87       }
88       else {
89         if ($flags & self::ARGS_ARE_XY_VALUES) {
90           $e = $font->readInt8();
91           $f = $font->readInt8();
92         }
93         else {
94           $point_compound  = $font->readUInt8();
95           $point_component = $font->readUInt8();
96         }
97       }
98
99       if ($flags & self::WE_HAVE_A_SCALE) {
100         $a = $d = $font->readInt16();
101       }
102       elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
103         $a = $font->readInt16();
104         $d = $font->readInt16();
105       }
106       elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) {
107         $a = $font->readInt16();
108         $b = $font->readInt16();
109         $c = $font->readInt16();
110         $d = $font->readInt16();
111       }
112
113       //if ($flags & self::WE_HAVE_INSTRUCTIONS) {
114       //
115       //}
116
117       $component                  = new OutlineComponent();
118       $component->flags           = $flags;
119       $component->glyphIndex      = $glyphIndex;
120       $component->a               = $a;
121       $component->b               = $b;
122       $component->c               = $c;
123       $component->d               = $d;
124       $component->e               = $e;
125       $component->f               = $f;
126       $component->point_compound  = $point_compound;
127       $component->point_component = $point_component;
128       $component->instructions    = $instructions;
129
130       $this->components[] = $component;
131     } while ($flags & self::MORE_COMPONENTS);
132   }
133
134   function encode() {
135     $font = $this->getFont();
136
137     $gids = $font->getSubset();
138
139     $size = $font->writeInt16(-1);
140     $size += $font->writeFWord($this->xMin);
141     $size += $font->writeFWord($this->yMin);
142     $size += $font->writeFWord($this->xMax);
143     $size += $font->writeFWord($this->yMax);
144
145     foreach ($this->components as $_i => $_component) {
146       $flags = 0;
147       if ($_component->point_component === null && $_component->point_compound === null) {
148         $flags |= self::ARGS_ARE_XY_VALUES;
149
150         if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) {
151           $flags |= self::ARG_1_AND_2_ARE_WORDS;
152         }
153       }
154       elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) {
155         $flags |= self::ARG_1_AND_2_ARE_WORDS;
156       }
157
158       if ($_component->b == 0 && $_component->c == 0) {
159         if ($_component->a == $_component->d) {
160           if ($_component->a != 1.0) {
161             $flags |= self::WE_HAVE_A_SCALE;
162           }
163         }
164         else {
165           $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE;
166         }
167       }
168       else {
169         $flags |= self::WE_HAVE_A_TWO_BY_TWO;
170       }
171
172       if ($_i < count($this->components) - 1) {
173         $flags |= self::MORE_COMPONENTS;
174       }
175
176       $size += $font->writeUInt16($flags);
177
178       $new_gid = array_search($_component->glyphIndex, $gids);
179       $size += $font->writeUInt16($new_gid);
180
181       if ($flags & self::ARG_1_AND_2_ARE_WORDS) {
182         if ($flags & self::ARGS_ARE_XY_VALUES) {
183           $size += $font->writeInt16($_component->e);
184           $size += $font->writeInt16($_component->f);
185         }
186         else {
187           $size += $font->writeUInt16($_component->point_compound);
188           $size += $font->writeUInt16($_component->point_component);
189         }
190       }
191       else {
192         if ($flags & self::ARGS_ARE_XY_VALUES) {
193           $size += $font->writeInt8($_component->e);
194           $size += $font->writeInt8($_component->f);
195         }
196         else {
197           $size += $font->writeUInt8($_component->point_compound);
198           $size += $font->writeUInt8($_component->point_component);
199         }
200       }
201
202       if ($flags & self::WE_HAVE_A_SCALE) {
203         $size += $font->writeInt16($_component->a);
204       }
205       elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
206         $size += $font->writeInt16($_component->a);
207         $size += $font->writeInt16($_component->d);
208       }
209       elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) {
210         $size += $font->writeInt16($_component->a);
211         $size += $font->writeInt16($_component->b);
212         $size += $font->writeInt16($_component->c);
213         $size += $font->writeInt16($_component->d);
214       }
215     }
216
217     return $size;
218   }
219
220   public function getSVGContours() {
221     $contours = array();
222
223     /** @var \FontLib\Table\Type\glyf $glyph_data */
224     $glyph_data = $this->getFont()->getTableObject("glyf");
225
226     /** @var Outline[] $glyphs */
227     $glyphs = $glyph_data->data;
228
229     foreach ($this->components as $component) {
230       $_glyph = $glyphs[$component->glyphIndex];
231
232       if ($_glyph !== $this) {
233         $contours[] = array(
234           "contours"  => $_glyph->getSVGContours(),
235           "transform" => $component->getMatrix(),
236         );
237       }
238     }
239
240     return $contours;
241   }
242 }