composer package updates
[openemr.git] / vendor / phenx / php-font-lib / src / FontLib / Glyph / OutlineComposite.php
blob8ab0d2c66caec56f00e99804224b178b576165af
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 */
10 namespace FontLib\Glyph;
12 /**
13 * Composite glyph outline
15 * @package php-font-lib
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;
29 /**
30 * @var OutlineComponent[]
32 public $components = array();
34 function getGlyphIDs() {
35 if (empty($this->components)) {
36 $this->parseData();
39 $glyphIDs = array();
40 foreach ($this->components as $_component) {
41 $glyphIDs[] = $_component->glyphIndex;
43 $_glyph = $this->table->data[$_component->glyphIndex];
45 if ($_glyph !== $this) {
46 $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs());
50 return $glyphIDs;
53 /*function parse() {
54 //$this->parseData();
55 }*/
57 function parseData() {
58 parent::parseData();
60 $font = $this->getFont();
62 do {
63 $flags = $font->readUInt16();
64 $glyphIndex = $font->readUInt16();
66 $a = 1.0;
67 $b = 0.0;
68 $c = 0.0;
69 $d = 1.0;
70 $e = 0.0;
71 $f = 0.0;
73 $point_compound = null;
74 $point_component = null;
76 $instructions = null;
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();
83 else {
84 $point_compound = $font->readUInt16();
85 $point_component = $font->readUInt16();
88 else {
89 if ($flags & self::ARGS_ARE_XY_VALUES) {
90 $e = $font->readInt8();
91 $f = $font->readInt8();
93 else {
94 $point_compound = $font->readUInt8();
95 $point_component = $font->readUInt8();
99 if ($flags & self::WE_HAVE_A_SCALE) {
100 $a = $d = $font->readInt16();
102 elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
103 $a = $font->readInt16();
104 $d = $font->readInt16();
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();
113 //if ($flags & self::WE_HAVE_INSTRUCTIONS) {
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;
130 $this->components[] = $component;
131 } while ($flags & self::MORE_COMPONENTS);
134 function encode() {
135 $font = $this->getFont();
137 $gids = $font->getSubset();
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);
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;
150 if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) {
151 $flags |= self::ARG_1_AND_2_ARE_WORDS;
154 elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) {
155 $flags |= self::ARG_1_AND_2_ARE_WORDS;
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;
164 else {
165 $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE;
168 else {
169 $flags |= self::WE_HAVE_A_TWO_BY_TWO;
172 if ($_i < count($this->components) - 1) {
173 $flags |= self::MORE_COMPONENTS;
176 $size += $font->writeUInt16($flags);
178 $new_gid = array_search($_component->glyphIndex, $gids);
179 $size += $font->writeUInt16($new_gid);
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);
186 else {
187 $size += $font->writeUInt16($_component->point_compound);
188 $size += $font->writeUInt16($_component->point_component);
191 else {
192 if ($flags & self::ARGS_ARE_XY_VALUES) {
193 $size += $font->writeInt8($_component->e);
194 $size += $font->writeInt8($_component->f);
196 else {
197 $size += $font->writeUInt8($_component->point_compound);
198 $size += $font->writeUInt8($_component->point_component);
202 if ($flags & self::WE_HAVE_A_SCALE) {
203 $size += $font->writeInt16($_component->a);
205 elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
206 $size += $font->writeInt16($_component->a);
207 $size += $font->writeInt16($_component->d);
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);
217 return $size;
220 public function getSVGContours() {
221 $contours = array();
223 /** @var \FontLib\Table\Type\glyf $glyph_data */
224 $glyph_data = $this->getFont()->getTableObject("glyf");
226 /** @var Outline[] $glyphs */
227 $glyphs = $glyph_data->data;
229 foreach ($this->components as $component) {
230 $_glyph = $glyphs[$component->glyphIndex];
232 if ($_glyph !== $this) {
233 $contours[] = array(
234 "contours" => $_glyph->getSVGContours(),
235 "transform" => $component->getMatrix(),
240 return $contours;