@cantoo/fontkit 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/dist/browser-module.mjs +13660 -0
  4. package/dist/browser-module.mjs.map +1 -0
  5. package/dist/browser.cjs +13689 -0
  6. package/dist/browser.cjs.map +1 -0
  7. package/dist/main.cjs +13712 -0
  8. package/dist/main.cjs.map +1 -0
  9. package/dist/module.mjs +13673 -0
  10. package/dist/module.mjs.map +1 -0
  11. package/package.json +99 -0
  12. package/src/CmapProcessor.js +285 -0
  13. package/src/DFont.js +113 -0
  14. package/src/TTFFont.js +621 -0
  15. package/src/TrueTypeCollection.js +65 -0
  16. package/src/WOFF2Font.js +222 -0
  17. package/src/WOFFFont.js +56 -0
  18. package/src/aat/AATFeatureMap.js +545 -0
  19. package/src/aat/AATLayoutEngine.js +48 -0
  20. package/src/aat/AATLookupTable.js +125 -0
  21. package/src/aat/AATMorxProcessor.js +429 -0
  22. package/src/aat/AATStateMachine.js +96 -0
  23. package/src/base.js +29 -0
  24. package/src/cff/CFFCharsets.js +99 -0
  25. package/src/cff/CFFDict.js +166 -0
  26. package/src/cff/CFFEncodings.js +48 -0
  27. package/src/cff/CFFFont.js +158 -0
  28. package/src/cff/CFFIndex.js +150 -0
  29. package/src/cff/CFFOperand.js +135 -0
  30. package/src/cff/CFFPointer.js +50 -0
  31. package/src/cff/CFFPrivateDict.js +39 -0
  32. package/src/cff/CFFStandardStrings.js +71 -0
  33. package/src/cff/CFFTop.js +236 -0
  34. package/src/decorators.js +36 -0
  35. package/src/encodings.js +219 -0
  36. package/src/fs.js +12 -0
  37. package/src/glyph/BBox.js +72 -0
  38. package/src/glyph/CBDTGlyph.js +9 -0
  39. package/src/glyph/CFFGlyph.js +635 -0
  40. package/src/glyph/COLRGlyph.js +108 -0
  41. package/src/glyph/Glyph.js +270 -0
  42. package/src/glyph/GlyphVariationProcessor.js +487 -0
  43. package/src/glyph/Path.js +257 -0
  44. package/src/glyph/SBIXGlyph.js +54 -0
  45. package/src/glyph/StandardNames.js +27 -0
  46. package/src/glyph/TTFGlyph.js +408 -0
  47. package/src/glyph/TTFGlyphEncoder.js +158 -0
  48. package/src/glyph/WOFF2Glyph.js +70 -0
  49. package/src/index.js +15 -0
  50. package/src/layout/GlyphPosition.js +30 -0
  51. package/src/layout/GlyphRun.js +108 -0
  52. package/src/layout/KernProcessor.js +97 -0
  53. package/src/layout/LayoutEngine.js +190 -0
  54. package/src/layout/Script.js +231 -0
  55. package/src/layout/UnicodeLayoutEngine.js +250 -0
  56. package/src/node.js +16 -0
  57. package/src/opentype/GPOSProcessor.js +311 -0
  58. package/src/opentype/GSUBProcessor.js +208 -0
  59. package/src/opentype/GlyphInfo.js +57 -0
  60. package/src/opentype/GlyphIterator.js +82 -0
  61. package/src/opentype/OTLayoutEngine.js +117 -0
  62. package/src/opentype/OTProcessor.js +472 -0
  63. package/src/opentype/ShapingPlan.js +121 -0
  64. package/src/opentype/shapers/ArabicShaper.js +124 -0
  65. package/src/opentype/shapers/DefaultShaper.js +116 -0
  66. package/src/opentype/shapers/HangulShaper.js +285 -0
  67. package/src/opentype/shapers/HebrewShaper.js +105 -0
  68. package/src/opentype/shapers/IndicShaper.js +914 -0
  69. package/src/opentype/shapers/ThaiShaper.js +238 -0
  70. package/src/opentype/shapers/UniversalShaper.js +186 -0
  71. package/src/opentype/shapers/data.trie +0 -0
  72. package/src/opentype/shapers/gen-indic.js +208 -0
  73. package/src/opentype/shapers/gen-use.js +287 -0
  74. package/src/opentype/shapers/generate-data.js +33 -0
  75. package/src/opentype/shapers/index.js +109 -0
  76. package/src/opentype/shapers/indic-data.js +175 -0
  77. package/src/opentype/shapers/indic.json +1 -0
  78. package/src/opentype/shapers/indic.machine +31 -0
  79. package/src/opentype/shapers/indic.trie +0 -0
  80. package/src/opentype/shapers/use.json +1 -0
  81. package/src/opentype/shapers/use.machine +44 -0
  82. package/src/opentype/shapers/use.trie +0 -0
  83. package/src/packages/unicode-properties/LICENSE +8 -0
  84. package/src/packages/unicode-properties/README.md +12 -0
  85. package/src/packages/unicode-properties/data-trie.js +1 -0
  86. package/src/packages/unicode-properties/data.js +1 -0
  87. package/src/packages/unicode-properties/data.json +1 -0
  88. package/src/packages/unicode-properties/data.trie +0 -0
  89. package/src/packages/unicode-properties/dist/index.cjs +257 -0
  90. package/src/packages/unicode-properties/dist/index.cjs.map +7 -0
  91. package/src/packages/unicode-properties/dist/index.mjs +234 -0
  92. package/src/packages/unicode-properties/dist/index.mjs.map +7 -0
  93. package/src/packages/unicode-properties/generate.js +107 -0
  94. package/src/packages/unicode-properties/index.js +184 -0
  95. package/src/packages/unicode-properties/package.json +50 -0
  96. package/src/packages/unicode-trie/LICENSE +8 -0
  97. package/src/packages/unicode-trie/README.md +13 -0
  98. package/src/packages/unicode-trie/builder.js +965 -0
  99. package/src/packages/unicode-trie/dist/builder.cjs +711 -0
  100. package/src/packages/unicode-trie/dist/builder.cjs.map +7 -0
  101. package/src/packages/unicode-trie/dist/builder.mjs +690 -0
  102. package/src/packages/unicode-trie/dist/builder.mjs.map +7 -0
  103. package/src/packages/unicode-trie/dist/index.cjs +112 -0
  104. package/src/packages/unicode-trie/dist/index.cjs.map +7 -0
  105. package/src/packages/unicode-trie/dist/index.mjs +91 -0
  106. package/src/packages/unicode-trie/dist/index.mjs.map +7 -0
  107. package/src/packages/unicode-trie/index.js +135 -0
  108. package/src/packages/unicode-trie/package.json +49 -0
  109. package/src/packages/unicode-trie/swap.js +21 -0
  110. package/src/subset/CFFSubset.js +176 -0
  111. package/src/subset/Subset.js +63 -0
  112. package/src/subset/TTFSubset.js +130 -0
  113. package/src/tables/BASE.js +78 -0
  114. package/src/tables/COLR.js +25 -0
  115. package/src/tables/CPAL.js +24 -0
  116. package/src/tables/DSIG.js +21 -0
  117. package/src/tables/EBDT.js +91 -0
  118. package/src/tables/EBLC.js +80 -0
  119. package/src/tables/GDEF.js +57 -0
  120. package/src/tables/GPOS.js +209 -0
  121. package/src/tables/GSUB.js +85 -0
  122. package/src/tables/HVAR.js +44 -0
  123. package/src/tables/JSTF.js +43 -0
  124. package/src/tables/LTSH.js +10 -0
  125. package/src/tables/OS2.js +84 -0
  126. package/src/tables/PCLT.js +21 -0
  127. package/src/tables/STAT.js +99 -0
  128. package/src/tables/VDMX.js +33 -0
  129. package/src/tables/VORG.js +14 -0
  130. package/src/tables/WOFF2Directory.js +73 -0
  131. package/src/tables/WOFFDirectory.js +37 -0
  132. package/src/tables/aat.js +157 -0
  133. package/src/tables/avar.js +19 -0
  134. package/src/tables/bsln.js +31 -0
  135. package/src/tables/cmap.js +127 -0
  136. package/src/tables/cvt.js +6 -0
  137. package/src/tables/directory.js +58 -0
  138. package/src/tables/feat.js +28 -0
  139. package/src/tables/fpgm.js +8 -0
  140. package/src/tables/fvar.js +31 -0
  141. package/src/tables/gasp.js +15 -0
  142. package/src/tables/glyf.js +4 -0
  143. package/src/tables/gvar.js +27 -0
  144. package/src/tables/hdmx.js +15 -0
  145. package/src/tables/head.js +25 -0
  146. package/src/tables/hhea.js +19 -0
  147. package/src/tables/hmtx.js +11 -0
  148. package/src/tables/index.js +119 -0
  149. package/src/tables/just.js +81 -0
  150. package/src/tables/kern.js +91 -0
  151. package/src/tables/loca.js +30 -0
  152. package/src/tables/maxp.js +20 -0
  153. package/src/tables/morx.js +79 -0
  154. package/src/tables/name.js +157 -0
  155. package/src/tables/opbd.js +15 -0
  156. package/src/tables/opentype.js +217 -0
  157. package/src/tables/post.js +34 -0
  158. package/src/tables/prep.js +6 -0
  159. package/src/tables/sbix.js +17 -0
  160. package/src/tables/variations.js +80 -0
  161. package/src/tables/vhea.js +19 -0
  162. package/src/tables/vmtx.js +12 -0
  163. package/src/utils.js +62 -0
@@ -0,0 +1,635 @@
1
+ import Glyph from './Glyph';
2
+ import Path from './Path';
3
+ import { StandardEncoding } from '../cff/CFFEncodings';
4
+
5
+ /**
6
+ * Represents an OpenType PostScript glyph, in the Compact Font Format.
7
+ */
8
+ export default class CFFGlyph extends Glyph {
9
+ type = 'CFF';
10
+
11
+ _getName() {
12
+ if (this._font.CFF2) {
13
+ return super._getName();
14
+ }
15
+
16
+ return this._font['CFF '].getGlyphName(this.id);
17
+ }
18
+
19
+ bias(s) {
20
+ if (s.length < 1240) {
21
+ return 107;
22
+ } else if (s.length < 33900) {
23
+ return 1131;
24
+ } else {
25
+ return 32768;
26
+ }
27
+ }
28
+
29
+ _getPath() {
30
+ let cff = this._font.CFF2 || this._font['CFF '];
31
+ let { stream } = cff;
32
+ let str = cff.topDict.CharStrings[this.id];
33
+ let end = str.offset + str.length;
34
+ stream.pos = str.offset;
35
+
36
+ let path = new Path;
37
+ let stack = [];
38
+ let trans = [];
39
+
40
+ let width = null;
41
+ let nStems = 0;
42
+ let x = 0, y = 0;
43
+ let usedGsubrs;
44
+ let usedSubrs;
45
+ let open = false;
46
+
47
+ this._usedGsubrs = usedGsubrs = {};
48
+ this._usedSubrs = usedSubrs = {};
49
+
50
+ let gsubrs = cff.globalSubrIndex || [];
51
+ let gsubrsBias = this.bias(gsubrs);
52
+
53
+ let privateDict = cff.privateDictForGlyph(this.id) || {};
54
+ let subrs = privateDict.Subrs || [];
55
+ let subrsBias = this.bias(subrs);
56
+
57
+ let vstore = cff.topDict.vstore && cff.topDict.vstore.itemVariationStore;
58
+ let vsindex = privateDict.vsindex;
59
+ let variationProcessor = this._font._variationProcessor;
60
+ let font = this._font;
61
+
62
+ function checkWidth() {
63
+ if (width == null) {
64
+ width = stack.shift() + privateDict.nominalWidthX;
65
+ }
66
+ }
67
+
68
+ function parseStems() {
69
+ if (stack.length % 2 !== 0) {
70
+ checkWidth();
71
+ }
72
+
73
+ nStems += stack.length >> 1;
74
+ return stack.length = 0;
75
+ }
76
+
77
+ function moveTo(x, y) {
78
+ if (open) {
79
+ path.closePath();
80
+ }
81
+
82
+ path.moveTo(x, y);
83
+ open = true;
84
+ }
85
+
86
+ function glyphForName(name) {
87
+ if (name) {
88
+ for (let i = 0; i < font.numGlyphs; i++) {
89
+ if (cff.getGlyphName(i) === name) {
90
+ return font.getGlyph(i);
91
+ }
92
+ }
93
+ }
94
+ return font.getGlyph(0);
95
+ }
96
+
97
+ let parse = function () {
98
+ while (stream.pos < end) {
99
+ let op = stream.readUInt8();
100
+ if (op < 32) {
101
+ let index, subr, phase;
102
+ let c1x, c1y, c2x, c2y, c3x, c3y;
103
+ let c4x, c4y, c5x, c5y, c6x, c6y;
104
+ let pts;
105
+
106
+ switch (op) {
107
+ case 1: // hstem
108
+ case 3: // vstem
109
+ case 18: // hstemhm
110
+ case 23: // vstemhm
111
+ parseStems();
112
+ break;
113
+
114
+ case 4: // vmoveto
115
+ if (stack.length > 1) {
116
+ checkWidth();
117
+ }
118
+
119
+ y += stack.shift();
120
+ moveTo(x, y);
121
+ break;
122
+
123
+ case 5: // rlineto
124
+ while (stack.length >= 2) {
125
+ x += stack.shift();
126
+ y += stack.shift();
127
+ path.lineTo(x, y);
128
+ }
129
+ break;
130
+
131
+ case 6: // hlineto
132
+ case 7: // vlineto
133
+ phase = op === 6;
134
+ while (stack.length >= 1) {
135
+ if (phase) {
136
+ x += stack.shift();
137
+ } else {
138
+ y += stack.shift();
139
+ }
140
+
141
+ path.lineTo(x, y);
142
+ phase = !phase;
143
+ }
144
+ break;
145
+
146
+ case 8: // rrcurveto
147
+ while (stack.length > 0) {
148
+ c1x = x + stack.shift();
149
+ c1y = y + stack.shift();
150
+ c2x = c1x + stack.shift();
151
+ c2y = c1y + stack.shift();
152
+ x = c2x + stack.shift();
153
+ y = c2y + stack.shift();
154
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
155
+ }
156
+ break;
157
+
158
+ case 10: // callsubr
159
+ index = stack.pop() + subrsBias;
160
+ subr = subrs[index];
161
+ if (subr) {
162
+ usedSubrs[index] = true;
163
+ let p = stream.pos;
164
+ let e = end;
165
+ stream.pos = subr.offset;
166
+ end = subr.offset + subr.length;
167
+ parse();
168
+ stream.pos = p;
169
+ end = e;
170
+ }
171
+ break;
172
+
173
+ case 11: // return
174
+ if (cff.version >= 2) {
175
+ break;
176
+ }
177
+ return;
178
+
179
+ case 14: // endchar
180
+ if (cff.version >= 2) {
181
+ break;
182
+ }
183
+
184
+ // Deprecated seac: [width?] adx ady bchar achar endchar (TN5177 App. C)
185
+ if (stack.length >= 4) {
186
+ if (stack.length > 4) {
187
+ checkWidth();
188
+ }
189
+ let a = glyphForName(StandardEncoding[stack.pop()]);
190
+ let b = glyphForName(StandardEncoding[stack.pop()]);
191
+ let ady = stack.pop();
192
+ let adx = stack.pop();
193
+ let pos = stream.pos;
194
+ path.commands = b.path.commands.concat(a.path.translate(adx, ady).commands);
195
+ stream.pos = pos;
196
+ open = false;
197
+ } else if (stack.length > 0) {
198
+ checkWidth();
199
+ }
200
+
201
+ if (open) {
202
+ path.closePath();
203
+ open = false;
204
+ }
205
+ break;
206
+
207
+ case 15: { // vsindex
208
+ if (cff.version < 2) {
209
+ throw new Error('vsindex operator not supported in CFF v1');
210
+ }
211
+
212
+ vsindex = stack.pop();
213
+ break;
214
+ }
215
+
216
+ case 16: { // blend
217
+ if (cff.version < 2) {
218
+ throw new Error('blend operator not supported in CFF v1');
219
+ }
220
+
221
+ if (!variationProcessor) {
222
+ throw new Error('blend operator in non-variation font');
223
+ }
224
+
225
+ let blendVector = variationProcessor.getBlendVector(vstore, vsindex);
226
+ let numBlends = stack.pop();
227
+ let numOperands = numBlends * blendVector.length;
228
+ let delta = stack.length - numOperands;
229
+ let base = delta - numBlends;
230
+
231
+ for (let i = 0; i < numBlends; i++) {
232
+ let sum = stack[base + i];
233
+ for (let j = 0; j < blendVector.length; j++) {
234
+ sum += blendVector[j] * stack[delta++];
235
+ }
236
+
237
+ stack[base + i] = sum;
238
+ }
239
+
240
+ while (numOperands--) {
241
+ stack.pop();
242
+ }
243
+
244
+ break;
245
+ }
246
+
247
+ case 19: // hintmask
248
+ case 20: // cntrmask
249
+ parseStems();
250
+ stream.pos += (nStems + 7) >> 3;
251
+ break;
252
+
253
+ case 21: // rmoveto
254
+ if (stack.length > 2) {
255
+ checkWidth();
256
+ }
257
+
258
+ x += stack.shift();
259
+ y += stack.shift();
260
+ moveTo(x, y);
261
+ break;
262
+
263
+ case 22: // hmoveto
264
+ if (stack.length > 1) {
265
+ checkWidth();
266
+ }
267
+
268
+ x += stack.shift();
269
+ moveTo(x, y);
270
+ break;
271
+
272
+ case 24: // rcurveline
273
+ while (stack.length >= 8) {
274
+ c1x = x + stack.shift();
275
+ c1y = y + stack.shift();
276
+ c2x = c1x + stack.shift();
277
+ c2y = c1y + stack.shift();
278
+ x = c2x + stack.shift();
279
+ y = c2y + stack.shift();
280
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
281
+ }
282
+
283
+ x += stack.shift();
284
+ y += stack.shift();
285
+ path.lineTo(x, y);
286
+ break;
287
+
288
+ case 25: // rlinecurve
289
+ while (stack.length >= 8) {
290
+ x += stack.shift();
291
+ y += stack.shift();
292
+ path.lineTo(x, y);
293
+ }
294
+
295
+ c1x = x + stack.shift();
296
+ c1y = y + stack.shift();
297
+ c2x = c1x + stack.shift();
298
+ c2y = c1y + stack.shift();
299
+ x = c2x + stack.shift();
300
+ y = c2y + stack.shift();
301
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
302
+ break;
303
+
304
+ case 26: // vvcurveto
305
+ if (stack.length % 2) {
306
+ x += stack.shift();
307
+ }
308
+
309
+ while (stack.length >= 4) {
310
+ c1x = x;
311
+ c1y = y + stack.shift();
312
+ c2x = c1x + stack.shift();
313
+ c2y = c1y + stack.shift();
314
+ x = c2x;
315
+ y = c2y + stack.shift();
316
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
317
+ }
318
+ break;
319
+
320
+ case 27: // hhcurveto
321
+ if (stack.length % 2) {
322
+ y += stack.shift();
323
+ }
324
+
325
+ while (stack.length >= 4) {
326
+ c1x = x + stack.shift();
327
+ c1y = y;
328
+ c2x = c1x + stack.shift();
329
+ c2y = c1y + stack.shift();
330
+ x = c2x + stack.shift();
331
+ y = c2y;
332
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
333
+ }
334
+ break;
335
+
336
+ case 28: // shortint
337
+ stack.push(stream.readInt16BE());
338
+ break;
339
+
340
+ case 29: // callgsubr
341
+ index = stack.pop() + gsubrsBias;
342
+ subr = gsubrs[index];
343
+ if (subr) {
344
+ usedGsubrs[index] = true;
345
+ let p = stream.pos;
346
+ let e = end;
347
+ stream.pos = subr.offset;
348
+ end = subr.offset + subr.length;
349
+ parse();
350
+ stream.pos = p;
351
+ end = e;
352
+ }
353
+ break;
354
+
355
+ case 30: // vhcurveto
356
+ case 31: // hvcurveto
357
+ phase = op === 31;
358
+ while (stack.length >= 4) {
359
+ if (phase) {
360
+ c1x = x + stack.shift();
361
+ c1y = y;
362
+ c2x = c1x + stack.shift();
363
+ c2y = c1y + stack.shift();
364
+ y = c2y + stack.shift();
365
+ x = c2x + (stack.length === 1 ? stack.shift() : 0);
366
+ } else {
367
+ c1x = x;
368
+ c1y = y + stack.shift();
369
+ c2x = c1x + stack.shift();
370
+ c2y = c1y + stack.shift();
371
+ x = c2x + stack.shift();
372
+ y = c2y + (stack.length === 1 ? stack.shift() : 0);
373
+ }
374
+
375
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
376
+ phase = !phase;
377
+ }
378
+ break;
379
+
380
+ case 12: {
381
+ op = stream.readUInt8();
382
+ let a, b, val, idx;
383
+ switch (op) {
384
+ case 3: // and
385
+ a = stack.pop();
386
+ b = stack.pop();
387
+ stack.push(a && b ? 1 : 0);
388
+ break;
389
+
390
+ case 4: // or
391
+ a = stack.pop();
392
+ b = stack.pop();
393
+ stack.push(a || b ? 1 : 0);
394
+ break;
395
+
396
+ case 5: // not
397
+ a = stack.pop();
398
+ stack.push(a ? 0 : 1);
399
+ break;
400
+
401
+ case 9: // abs
402
+ a = stack.pop();
403
+ stack.push(Math.abs(a));
404
+ break;
405
+
406
+ case 10: // add
407
+ a = stack.pop();
408
+ b = stack.pop();
409
+ stack.push(a + b);
410
+ break;
411
+
412
+ case 11: // sub
413
+ a = stack.pop();
414
+ b = stack.pop();
415
+ stack.push(a - b);
416
+ break;
417
+
418
+ case 12: // div
419
+ a = stack.pop();
420
+ b = stack.pop();
421
+ stack.push(a / b);
422
+ break;
423
+
424
+ case 14: // neg
425
+ a = stack.pop();
426
+ stack.push(-a);
427
+ break;
428
+
429
+ case 15: // eq
430
+ a = stack.pop();
431
+ b = stack.pop();
432
+ stack.push(a === b ? 1 : 0);
433
+ break;
434
+
435
+ case 18: // drop
436
+ stack.pop();
437
+ break;
438
+
439
+ case 20: // put
440
+ val = stack.pop();
441
+ idx = stack.pop();
442
+ trans[idx] = val;
443
+ break;
444
+
445
+ case 21: // get
446
+ idx = stack.pop();
447
+ stack.push(trans[idx] || 0);
448
+ break;
449
+
450
+ case 22: { // ifelse
451
+ let s1 = stack.pop();
452
+ let s2 = stack.pop();
453
+ let v1 = stack.pop();
454
+ let v2 = stack.pop();
455
+ stack.push(v1 <= v2 ? s1 : s2);
456
+ break;
457
+ }
458
+
459
+ case 23: // random
460
+ stack.push(Math.random());
461
+ break;
462
+
463
+ case 24: // mul
464
+ a = stack.pop();
465
+ b = stack.pop();
466
+ stack.push(a * b);
467
+ break;
468
+
469
+ case 26: // sqrt
470
+ a = stack.pop();
471
+ stack.push(Math.sqrt(a));
472
+ break;
473
+
474
+ case 27: // dup
475
+ a = stack.pop();
476
+ stack.push(a, a);
477
+ break;
478
+
479
+ case 28: // exch
480
+ a = stack.pop();
481
+ b = stack.pop();
482
+ stack.push(b, a);
483
+ break;
484
+
485
+ case 29: // index
486
+ idx = stack.pop();
487
+ if (idx < 0) {
488
+ idx = 0;
489
+ } else if (idx > stack.length - 1) {
490
+ idx = stack.length - 1;
491
+ }
492
+
493
+ stack.push(stack[idx]);
494
+ break;
495
+
496
+ case 30: { // roll
497
+ let n = stack.pop();
498
+ let j = stack.pop();
499
+
500
+ if (j >= 0) {
501
+ while (j > 0) {
502
+ let t = stack[n - 1];
503
+ for (let i = n - 2; i >= 0; i--) {
504
+ stack[i + 1] = stack[i];
505
+ }
506
+
507
+ stack[0] = t;
508
+ j--;
509
+ }
510
+ } else {
511
+ while (j < 0) {
512
+ let t = stack[0];
513
+ for (let i = 0; i <= n; i++) {
514
+ stack[i] = stack[i + 1];
515
+ }
516
+
517
+ stack[n - 1] = t;
518
+ j++;
519
+ }
520
+ }
521
+ break;
522
+ }
523
+
524
+ case 34: // hflex
525
+ c1x = x + stack.shift();
526
+ c1y = y;
527
+ c2x = c1x + stack.shift();
528
+ c2y = c1y + stack.shift();
529
+ c3x = c2x + stack.shift();
530
+ c3y = c2y;
531
+ c4x = c3x + stack.shift();
532
+ c4y = c3y;
533
+ c5x = c4x + stack.shift();
534
+ c5y = c4y;
535
+ c6x = c5x + stack.shift();
536
+ c6y = c5y;
537
+ x = c6x;
538
+ y = c6y;
539
+
540
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
541
+ path.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
542
+ break;
543
+
544
+ case 35: // flex
545
+ pts = [];
546
+
547
+ for (let i = 0; i <= 5; i++) {
548
+ x += stack.shift();
549
+ y += stack.shift();
550
+ pts.push(x, y);
551
+ }
552
+
553
+ path.bezierCurveTo(...pts.slice(0, 6));
554
+ path.bezierCurveTo(...pts.slice(6));
555
+ stack.shift(); // fd
556
+ break;
557
+
558
+ case 36: // hflex1
559
+ c1x = x + stack.shift();
560
+ c1y = y + stack.shift();
561
+ c2x = c1x + stack.shift();
562
+ c2y = c1y + stack.shift();
563
+ c3x = c2x + stack.shift();
564
+ c3y = c2y;
565
+ c4x = c3x + stack.shift();
566
+ c4y = c3y;
567
+ c5x = c4x + stack.shift();
568
+ c5y = c4y + stack.shift();
569
+ c6x = c5x + stack.shift();
570
+ c6y = c5y;
571
+ x = c6x;
572
+ y = c6y;
573
+
574
+ path.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
575
+ path.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
576
+ break;
577
+
578
+ case 37: { // flex1
579
+ let startx = x;
580
+ let starty = y;
581
+
582
+ pts = [];
583
+ for (let i = 0; i <= 4; i++) {
584
+ x += stack.shift();
585
+ y += stack.shift();
586
+ pts.push(x, y);
587
+ }
588
+
589
+ if (Math.abs(x - startx) > Math.abs(y - starty)) { // horizontal
590
+ x += stack.shift();
591
+ y = starty;
592
+ } else {
593
+ x = startx;
594
+ y += stack.shift();
595
+ }
596
+
597
+ pts.push(x, y);
598
+ path.bezierCurveTo(...pts.slice(0, 6));
599
+ path.bezierCurveTo(...pts.slice(6));
600
+ break;
601
+ }
602
+
603
+ default:
604
+ throw new Error(`Unknown op: 12 ${op}`);
605
+ }
606
+ break;
607
+ }
608
+
609
+ default:
610
+ throw new Error(`Unknown op: ${op}`);
611
+ }
612
+
613
+ } else if (op < 247) {
614
+ stack.push(op - 139);
615
+ } else if (op < 251) {
616
+ let b1 = stream.readUInt8();
617
+ stack.push((op - 247) * 256 + b1 + 108);
618
+ } else if (op < 255) {
619
+ let b1 = stream.readUInt8();
620
+ stack.push(-(op - 251) * 256 - b1 - 108);
621
+ } else {
622
+ stack.push(stream.readInt32BE() / 65536);
623
+ }
624
+ }
625
+ };
626
+
627
+ parse();
628
+
629
+ if (open) {
630
+ path.closePath();
631
+ }
632
+
633
+ return path;
634
+ }
635
+ }