PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.3
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.3
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
easy-invoice / vendor / dompdf / php-font-lib / src / FontLib / Glyph / OutlineSimple.php

OutlineSimple.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.4.3, at vendor/dompdf/php-font-lib/src/FontLib/Glyph/OutlineSimple.php

335 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package php-font-lib
4 * @link https://github.com/dompdf/php-font-lib
5 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
6 * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $
7 */
8
9 namespace FontLib\Glyph;
10
11 /**
12 * `glyf` font table.
13 *
14 * @package php-font-lib
15 */
16 class OutlineSimple extends Outline {
17 const ON_CURVE = 0x01;
18 const X_SHORT_VECTOR = 0x02;
19 const Y_SHORT_VECTOR = 0x04;
20 const REPEAT = 0x08;
21 const THIS_X_IS_SAME = 0x10;
22 const THIS_Y_IS_SAME = 0x20;
23
24 public $instructions;
25 public $points;
26
27 function parseData() {
28 parent::parseData();
29
30 if (!$this->size) {
31 return;
32 }
33
34 $font = $this->getFont();
35
36 $noc = $this->numberOfContours;
37
38 if ($noc == 0) {
39 return;
40 }
41
42 $endPtsOfContours = $font->r(array(self::uint16, $noc));
43
44 $instructionLength = $font->readUInt16();
45 $this->instructions = $font->r(array(self::uint8, $instructionLength));
46
47 $count = $endPtsOfContours[$noc - 1] + 1;
48
49 // Flags
50 $flags = array();
51 for ($index = 0; $index < $count; $index++) {
52 $flags[$index] = $font->readUInt8();
53
54 if ($flags[$index] & self::REPEAT) {
55 $repeats = $font->readUInt8();
56
57 for ($i = 1; $i <= $repeats; $i++) {
58 $flags[$index + $i] = $flags[$index];
59 }
60
61 $index += $repeats;
62 }
63 }
64
65 $points = array();
66 foreach ($flags as $i => $flag) {
67 $points[$i]["onCurve"] = $flag & self::ON_CURVE;
68 $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours);
69 }
70
71 // X Coords
72 $x = 0;
73 for ($i = 0; $i < $count; $i++) {
74 $flag = $flags[$i];
75
76 if ($flag & self::THIS_X_IS_SAME) {
77 if ($flag & self::X_SHORT_VECTOR) {
78 $x += $font->readUInt8();
79 }
80 }
81 else {
82 if ($flag & self::X_SHORT_VECTOR) {
83 $x -= $font->readUInt8();
84 }
85 else {
86 $x += $font->readInt16();
87 }
88 }
89
90 $points[$i]["x"] = $x;
91 }
92
93 // Y Coords
94 $y = 0;
95 for ($i = 0; $i < $count; $i++) {
96 $flag = $flags[$i];
97
98 if ($flag & self::THIS_Y_IS_SAME) {
99 if ($flag & self::Y_SHORT_VECTOR) {
100 $y += $font->readUInt8();
101 }
102 }
103 else {
104 if ($flag & self::Y_SHORT_VECTOR) {
105 $y -= $font->readUInt8();
106 }
107 else {
108 $y += $font->readInt16();
109 }
110 }
111
112 $points[$i]["y"] = $y;
113 }
114
115 $this->points = $points;
116 }
117
118 public function splitSVGPath($path) {
119 preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER);
120
121 return $matches[0];
122 }
123
124 public function makePoints($path) {
125 $path = $this->splitSVGPath($path);
126 $l = count($path);
127 $i = 0;
128
129 $points = array();
130
131 while ($i < $l) {
132 switch ($path[$i]) {
133 // moveTo
134 case "M":
135 $points[] = array(
136 "onCurve" => true,
137 "x" => $path[++$i],
138 "y" => $path[++$i],
139 "endOfContour" => false,
140 );
141 break;
142
143 // lineTo
144 case "L":
145 $points[] = array(
146 "onCurve" => true,
147 "x" => $path[++$i],
148 "y" => $path[++$i],
149 "endOfContour" => false,
150 );
151 break;
152
153 // quadraticCurveTo
154 case "Q":
155 $points[] = array(
156 "onCurve" => false,
157 "x" => $path[++$i],
158 "y" => $path[++$i],
159 "endOfContour" => false,
160 );
161 $points[] = array(
162 "onCurve" => true,
163 "x" => $path[++$i],
164 "y" => $path[++$i],
165 "endOfContour" => false,
166 );
167 break;
168
169 // closePath
170 /** @noinspection PhpMissingBreakStatementInspection */
171 case "z":
172 $points[count($points) - 1]["endOfContour"] = true;
173
174 default:
175 $i++;
176 break;
177 }
178 }
179
180 return $points;
181 }
182
183 function encode() {
184 if (empty($this->points)) {
185 return parent::encode();
186 }
187
188 return $this->size = $this->encodePoints($this->points);
189 }
190
191 public function encodePoints($points) {
192 $endPtsOfContours = array();
193 $flags = array();
194 $coords_x = array();
195 $coords_y = array();
196
197 $last_x = 0;
198 $last_y = 0;
199 $xMin = $yMin = 0xFFFF;
200 $xMax = $yMax = -0xFFFF;
201 foreach ($points as $i => $point) {
202 $flag = 0;
203 if ($point["onCurve"]) {
204 $flag |= self::ON_CURVE;
205 }
206
207 if ($point["endOfContour"]) {
208 $endPtsOfContours[] = $i;
209 }
210
211 // Simplified, we could do some optimizations
212 if ($point["x"] == $last_x) {
213 $flag |= self::THIS_X_IS_SAME;
214 }
215 else {
216 $x = intval($point["x"]);
217 $xMin = min($x, $xMin);
218 $xMax = max($x, $xMax);
219 $coords_x[] = $x - $last_x; // int16
220 }
221
222 // Simplified, we could do some optimizations
223 if ($point["y"] == $last_y) {
224 $flag |= self::THIS_Y_IS_SAME;
225 }
226 else {
227 $y = intval($point["y"]);
228 $yMin = min($y, $yMin);
229 $yMax = max($y, $yMax);
230 $coords_y[] = $y - $last_y; // int16
231 }
232
233 $flags[] = $flag;
234 $last_x = $point["x"];
235 $last_y = $point["y"];
236 }
237
238 $font = $this->getFont();
239
240 $l = 0;
241 $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours
242 $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin
243 $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin
244 $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax
245 $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax
246
247 // Simple glyf
248 $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours
249 $l += $font->writeUInt16(0); // instructionLength
250 $l += $font->w(array(self::uint8, count($flags)), $flags); // flags
251 $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates
252 $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates
253 return $l;
254 }
255
256 public function getSVGContours($points = null) {
257 $path = "";
258
259 if (!$points) {
260 if (empty($this->points)) {
261 $this->parseData();
262 }
263
264 $points = $this->points;
265 }
266
267 $length = (empty($points) ? 0 : count($points));
268 $firstIndex = 0;
269 $count = 0;
270
271 for ($i = 0; $i < $length; $i++) {
272 $count++;
273
274 if ($points[$i]["endOfContour"]) {
275 $path .= $this->getSVGPath($points, $firstIndex, $count);
276 $firstIndex = $i + 1;
277 $count = 0;
278 }
279 }
280
281 return $path;
282 }
283
284 protected function getSVGPath($points, $startIndex, $count) {
285 $offset = 0;
286 $path = "";
287
288 while ($offset < $count) {
289 $point = $points[$startIndex + $offset % $count];
290 $point_p1 = $points[$startIndex + ($offset + 1) % $count];
291
292 if ($offset == 0) {
293 $path .= "M{$point['x']},{$point['y']} ";
294 }
295
296 if ($point["onCurve"]) {
297 if ($point_p1["onCurve"]) {
298 $path .= "L{$point_p1['x']},{$point_p1['y']} ";
299 $offset++;
300 }
301 else {
302 $point_p2 = $points[$startIndex + ($offset + 2) % $count];
303
304 if ($point_p2["onCurve"]) {
305 $path .= "Q{$point_p1['x']},{$point_p1['y']},{$point_p2['x']},{$point_p2['y']} ";
306 }
307 else {
308 $path .= "Q{$point_p1['x']},{$point_p1['y']}," . $this->midValue($point_p1['x'], $point_p2['x']) . "," . $this->midValue($point_p1['y'], $point_p2['y']) . " ";
309 }
310
311 $offset += 2;
312 }
313 }
314 else {
315 if ($point_p1["onCurve"]) {
316 $path .= "Q{$point['x']},{$point['y']},{$point_p1['x']},{$point_p1['y']} ";
317 }
318 else {
319 $path .= "Q{$point['x']},{$point['y']}," . $this->midValue($point['x'], $point_p1['x']) . "," . $this->midValue($point['y'], $point_p1['y']) . " ";
320 }
321
322 $offset++;
323 }
324 }
325
326 $path .= "z ";
327
328 return $path;
329 }
330
331 function midValue($a, $b) {
332 return $a + ($b - $a) / 2;
333 }
334 }
335