@pixerate/editor 0.112.0 → 0.114.0
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.
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/dist/animation-editor/index.cjs +60 -54
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +3 -3
- package/dist/animation-editor/index.d.ts +3 -3
- package/dist/animation-editor/index.js +14 -8
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/builtin-CY97ppKM.d.cts +354 -0
- package/dist/builtin-CY97ppKM.d.ts +354 -0
- package/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +9 -9
- package/dist/chunk-26PGXHY7.cjs +753 -0
- package/dist/chunk-26PGXHY7.cjs.map +1 -0
- package/dist/chunk-2OJACTPR.cjs +929 -0
- package/dist/chunk-2OJACTPR.cjs.map +1 -0
- package/dist/chunk-3UFGNHSP.js +929 -0
- package/dist/chunk-3UFGNHSP.js.map +1 -0
- package/dist/{chunk-YGIMK4NX.cjs → chunk-5OVJHMZQ.cjs} +757 -825
- package/dist/chunk-5OVJHMZQ.cjs.map +1 -0
- package/dist/chunk-643B2HKC.cjs +534 -0
- package/dist/chunk-643B2HKC.cjs.map +1 -0
- package/dist/chunk-6FCKOS2B.js +534 -0
- package/dist/chunk-6FCKOS2B.js.map +1 -0
- package/dist/chunk-BRLYOPLT.js +2574 -0
- package/dist/chunk-BRLYOPLT.js.map +1 -0
- package/dist/{chunk-LQEEDHOP.js → chunk-C6C5PDKU.js} +759 -761
- package/dist/chunk-C6C5PDKU.js.map +1 -0
- package/dist/chunk-DFQEX3AM.cjs +781 -0
- package/dist/chunk-DFQEX3AM.cjs.map +1 -0
- package/dist/{chunk-CZOXTEMN.js → chunk-EUVSQ25B.js} +336 -404
- package/dist/chunk-EUVSQ25B.js.map +1 -0
- package/dist/chunk-G5NMLUVF.cjs +2574 -0
- package/dist/chunk-G5NMLUVF.cjs.map +1 -0
- package/dist/chunk-LKCYANMW.js +781 -0
- package/dist/chunk-LKCYANMW.js.map +1 -0
- package/dist/{chunk-W3GXSUSQ.cjs → chunk-LPLCWZTM.cjs} +5087 -1283
- package/dist/chunk-LPLCWZTM.cjs.map +1 -0
- package/dist/chunk-MMVHBKMM.js +753 -0
- package/dist/chunk-MMVHBKMM.js.map +1 -0
- package/dist/{chunk-POGBUYWE.cjs → chunk-ST7E3NEE.cjs} +857 -859
- package/dist/chunk-ST7E3NEE.cjs.map +1 -0
- package/dist/{chunk-7VOHOPLW.cjs → chunk-TCKIXI46.cjs} +59 -59
- package/dist/{chunk-7VOHOPLW.cjs.map → chunk-TCKIXI46.cjs.map} +1 -1
- package/dist/{chunk-XIOMMGPD.cjs → chunk-TFOPHZ3U.cjs} +1 -1
- package/dist/chunk-TFOPHZ3U.cjs.map +1 -0
- package/dist/{chunk-Z4BC6M74.js → chunk-UBIXVXPR.js} +2 -2
- package/dist/{chunk-BLWCAQCW.js → chunk-VXR7XWMF.js} +4574 -770
- package/dist/chunk-VXR7XWMF.js.map +1 -0
- package/dist/{chunk-HNS7UHCM.js → chunk-XK5LZKBD.js} +1 -1
- package/dist/chunk-XK5LZKBD.js.map +1 -0
- package/dist/cms/index.cjs +146 -0
- package/dist/cms/index.cjs.map +1 -0
- package/dist/cms/index.d.cts +51 -0
- package/dist/cms/index.d.ts +51 -0
- package/dist/cms/index.js +146 -0
- package/dist/{export-DNu_Jr8p.d.ts → export-_1dUKwpF.d.ts} +326 -195
- package/dist/{export-DBba-buV.d.cts → export-b6NjCZ5-.d.cts} +326 -195
- package/dist/image-editor/index.cjs +2377 -1291
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +149 -97
- package/dist/image-editor/index.d.ts +149 -97
- package/dist/image-editor/index.js +1343 -257
- package/dist/image-editor/index.js.map +1 -1
- package/dist/opentype-BZEOSOX3.d.ts +188 -0
- package/dist/opentype-Dpe75vL5.d.cts +188 -0
- package/dist/paint/index.cjs +63 -4
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +30 -3
- package/dist/paint/index.d.ts +30 -3
- package/dist/paint/index.js +62 -3
- package/dist/paint-editor/index.cjs +146 -145
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +9 -8
- package/dist/paint-editor/index.d.ts +9 -8
- package/dist/paint-editor/index.js +6 -5
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +53 -3
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +62 -91
- package/dist/raster/index.d.ts +62 -91
- package/dist/raster/index.js +59 -9
- package/dist/{render-BEriFuqK.d.cts → render-B1K_OoLy.d.cts} +87 -2
- package/dist/{render-tjzKaik-.d.ts → render-CrmHOgpo.d.ts} +87 -2
- package/dist/{blending-aOE6Y3UE.d.cts → retouch-Bxkuc0KH.d.cts} +219 -2
- package/dist/{blending-DXl06NSx.d.ts → retouch-Do6tBs2H.d.ts} +219 -2
- package/dist/{surface-C8RRg_Bh.d.ts → surface-Cn30xIV6.d.cts} +6 -1
- package/dist/{surface-C8RRg_Bh.d.cts → surface-Cn30xIV6.d.ts} +6 -1
- package/dist/{svg-D_cfkhlB.d.cts → svg-BnRj0q8i.d.cts} +16 -4
- package/dist/{svg-wIaKLrU0.d.ts → svg-CmmBFfGT.d.ts} +16 -4
- package/dist/{types-DtL_qLFz.d.ts → types-1SUQKDAw.d.ts} +273 -4
- package/dist/{types-DyQq-WPY.d.cts → types-yINF17Ta.d.cts} +273 -4
- package/dist/vector/index.cjs +12170 -7343
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +1579 -16
- package/dist/vector/index.d.ts +1579 -16
- package/dist/vector/index.js +6303 -1476
- package/dist/vector/index.js.map +1 -1
- package/dist/warp-B39VsOtd.d.cts +348 -0
- package/dist/warp-DMN30aY6.d.ts +348 -0
- package/dist/zlib-dxQdgHyN.d.cts +95 -0
- package/dist/zlib-dxQdgHyN.d.ts +95 -0
- package/package.json +6 -1
- package/skills/pixerate-image-editor/SKILL.md +34 -34
- package/skills/pixerate-image-editor/references/color-management.md +37 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +39 -0
- package/skills/pixerate-image-editor/references/retouching.md +36 -0
- package/skills/pixerate-vector/SKILL.md +154 -5
- package/dist/chunk-BLWCAQCW.js.map +0 -1
- package/dist/chunk-CZOXTEMN.js.map +0 -1
- package/dist/chunk-FTBZPI77.cjs +0 -1
- package/dist/chunk-FTBZPI77.cjs.map +0 -1
- package/dist/chunk-HNS7UHCM.js.map +0 -1
- package/dist/chunk-JLYX4V57.cjs +0 -2001
- package/dist/chunk-JLYX4V57.cjs.map +0 -1
- package/dist/chunk-KB2YBCVS.js +0 -2001
- package/dist/chunk-KB2YBCVS.js.map +0 -1
- package/dist/chunk-LQEEDHOP.js.map +0 -1
- package/dist/chunk-POGBUYWE.cjs.map +0 -1
- package/dist/chunk-VKK5VS2T.js +0 -1
- package/dist/chunk-W3GXSUSQ.cjs.map +0 -1
- package/dist/chunk-XIOMMGPD.cjs.map +0 -1
- package/dist/chunk-YGIMK4NX.cjs.map +0 -1
- package/dist/homography-CZ-tFjay.d.cts +0 -50
- package/dist/homography-Ctfjoc1b.d.ts +0 -50
- package/dist/warp-CWHZzE3x.d.ts +0 -118
- package/dist/warp-D5jz_tN7.d.cts +0 -118
- /package/dist/{chunk-Z4BC6M74.js.map → chunk-UBIXVXPR.js.map} +0 -0
- /package/dist/{chunk-VKK5VS2T.js.map → cms/index.js.map} +0 -0
|
@@ -0,0 +1,929 @@
|
|
|
1
|
+
// src/text/opentype.ts
|
|
2
|
+
var fail = (message) => {
|
|
3
|
+
throw new Error(message);
|
|
4
|
+
};
|
|
5
|
+
var Reader = class {
|
|
6
|
+
constructor(view, pos = 0) {
|
|
7
|
+
this.view = view;
|
|
8
|
+
this.pos = pos;
|
|
9
|
+
}
|
|
10
|
+
view;
|
|
11
|
+
pos;
|
|
12
|
+
u8() {
|
|
13
|
+
return this.view.getUint8(this.pos++);
|
|
14
|
+
}
|
|
15
|
+
i8() {
|
|
16
|
+
return this.view.getInt8(this.pos++);
|
|
17
|
+
}
|
|
18
|
+
u16() {
|
|
19
|
+
const v = this.view.getUint16(this.pos);
|
|
20
|
+
this.pos += 2;
|
|
21
|
+
return v;
|
|
22
|
+
}
|
|
23
|
+
i16() {
|
|
24
|
+
const v = this.view.getInt16(this.pos);
|
|
25
|
+
this.pos += 2;
|
|
26
|
+
return v;
|
|
27
|
+
}
|
|
28
|
+
u32() {
|
|
29
|
+
const v = this.view.getUint32(this.pos);
|
|
30
|
+
this.pos += 4;
|
|
31
|
+
return v;
|
|
32
|
+
}
|
|
33
|
+
tag() {
|
|
34
|
+
let s = "";
|
|
35
|
+
for (let i = 0; i < 4; i++) s += String.fromCharCode(this.u8());
|
|
36
|
+
return s;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function tableDirectory(view, at) {
|
|
40
|
+
const r = new Reader(view, at);
|
|
41
|
+
const version = r.tag();
|
|
42
|
+
if (version !== "\0\0\0" && version !== "OTTO" && version !== "true") fail("This is not a TrueType or OpenType font (WOFF2 is not supported; convert it to TTF or OTF).");
|
|
43
|
+
const count = r.u16();
|
|
44
|
+
r.pos += 6;
|
|
45
|
+
const tables = /* @__PURE__ */ new Map();
|
|
46
|
+
for (let i = 0; i < count; i++) {
|
|
47
|
+
const tag = r.tag();
|
|
48
|
+
r.u32();
|
|
49
|
+
const offset = r.u32();
|
|
50
|
+
const length = r.u32();
|
|
51
|
+
if (offset + length > view.byteLength) fail(`The font's "${tag}" table runs past the end of the file.`);
|
|
52
|
+
tables.set(tag, { offset, length });
|
|
53
|
+
}
|
|
54
|
+
return tables;
|
|
55
|
+
}
|
|
56
|
+
function readCmap(view, t) {
|
|
57
|
+
const r = new Reader(view, t.offset);
|
|
58
|
+
r.u16();
|
|
59
|
+
const n = r.u16();
|
|
60
|
+
const subtables = [];
|
|
61
|
+
for (let i = 0; i < n; i++) {
|
|
62
|
+
const platform = r.u16();
|
|
63
|
+
const encoding = r.u16();
|
|
64
|
+
const offset = t.offset + r.u32();
|
|
65
|
+
subtables.push({ platform, encoding, offset, format: view.getUint16(offset) });
|
|
66
|
+
}
|
|
67
|
+
const rank = (s) => s.format === 12 && (s.platform === 3 && s.encoding === 10 || s.platform === 0) ? 0 : s.format === 4 && (s.platform === 3 && (s.encoding === 1 || s.encoding === 0) || s.platform === 0) ? 1 : s.format === 12 || s.format === 4 ? 2 : 9;
|
|
68
|
+
const best = subtables.filter((s) => rank(s) < 9).sort((a, b) => rank(a) - rank(b))[0];
|
|
69
|
+
if (!best) return () => 0;
|
|
70
|
+
const map = /* @__PURE__ */ new Map();
|
|
71
|
+
const at = best.offset;
|
|
72
|
+
if (best.format === 4) {
|
|
73
|
+
const segX2 = view.getUint16(at + 6);
|
|
74
|
+
const segs = segX2 / 2;
|
|
75
|
+
const ends = at + 14;
|
|
76
|
+
const starts = ends + segX2 + 2;
|
|
77
|
+
const deltas = starts + segX2;
|
|
78
|
+
const ranges = deltas + segX2;
|
|
79
|
+
return (cp) => {
|
|
80
|
+
if (cp > 65535) return 0;
|
|
81
|
+
let lo = 0;
|
|
82
|
+
let hi = segs - 1;
|
|
83
|
+
while (lo < hi) {
|
|
84
|
+
const mid = lo + hi >> 1;
|
|
85
|
+
if (view.getUint16(ends + mid * 2) < cp) lo = mid + 1;
|
|
86
|
+
else hi = mid;
|
|
87
|
+
}
|
|
88
|
+
const start = view.getUint16(starts + lo * 2);
|
|
89
|
+
if (cp < start || cp > view.getUint16(ends + lo * 2)) return 0;
|
|
90
|
+
const delta = view.getInt16(deltas + lo * 2);
|
|
91
|
+
const rangeAt = ranges + lo * 2;
|
|
92
|
+
const range = view.getUint16(rangeAt);
|
|
93
|
+
if (range === 0) return cp + delta & 65535;
|
|
94
|
+
const g = view.getUint16(rangeAt + range + (cp - start) * 2);
|
|
95
|
+
return g === 0 ? 0 : g + delta & 65535;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const groups = view.getUint32(at + 12);
|
|
99
|
+
for (let i = 0; i < groups && i < 2e5; i++) {
|
|
100
|
+
const g = at + 16 + i * 12;
|
|
101
|
+
const start = view.getUint32(g);
|
|
102
|
+
const end = view.getUint32(g + 4);
|
|
103
|
+
const glyph = view.getUint32(g + 8);
|
|
104
|
+
if (end - start > 1114111) continue;
|
|
105
|
+
map.set(start, glyph);
|
|
106
|
+
for (let c = start + 1; c <= end; c++) map.set(c, glyph + c - start);
|
|
107
|
+
}
|
|
108
|
+
return (cp) => map.get(cp) ?? 0;
|
|
109
|
+
}
|
|
110
|
+
function readNames(view, t) {
|
|
111
|
+
const out = /* @__PURE__ */ new Map();
|
|
112
|
+
if (!t) return out;
|
|
113
|
+
const r = new Reader(view, t.offset);
|
|
114
|
+
r.u16();
|
|
115
|
+
const count = r.u16();
|
|
116
|
+
const strings = t.offset + r.u16();
|
|
117
|
+
const ranked = /* @__PURE__ */ new Map();
|
|
118
|
+
for (let i = 0; i < count; i++) {
|
|
119
|
+
const platform = r.u16();
|
|
120
|
+
const encoding = r.u16();
|
|
121
|
+
const language = r.u16();
|
|
122
|
+
const id = r.u16();
|
|
123
|
+
const length = r.u16();
|
|
124
|
+
const offset = r.u16();
|
|
125
|
+
let rank;
|
|
126
|
+
let text = "";
|
|
127
|
+
if (platform === 3 && (encoding === 1 || encoding === 10)) {
|
|
128
|
+
rank = language === 1033 ? 0 : 2;
|
|
129
|
+
for (let k = 0; k + 1 < length; k += 2) text += String.fromCharCode(view.getUint16(strings + offset + k));
|
|
130
|
+
} else if (platform === 1 && encoding === 0) {
|
|
131
|
+
rank = language === 0 ? 1 : 3;
|
|
132
|
+
for (let k = 0; k < length; k++) text += String.fromCharCode(view.getUint8(strings + offset + k));
|
|
133
|
+
} else if (platform === 0) {
|
|
134
|
+
rank = 2;
|
|
135
|
+
for (let k = 0; k + 1 < length; k += 2) text += String.fromCharCode(view.getUint16(strings + offset + k));
|
|
136
|
+
} else continue;
|
|
137
|
+
if (!text || (ranked.get(id) ?? 9) <= rank) continue;
|
|
138
|
+
ranked.set(id, rank);
|
|
139
|
+
out.set(id, text);
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
function glyfOutlines(view, glyf, loca, longLoca, numGlyphs) {
|
|
144
|
+
const offsetOf = (g) => longLoca ? view.getUint32(loca.offset + g * 4) : view.getUint16(loca.offset + g * 2) * 2;
|
|
145
|
+
const contoursOf = (g, depth) => {
|
|
146
|
+
if (g < 0 || g >= numGlyphs || depth > 8) return [];
|
|
147
|
+
const start = offsetOf(g);
|
|
148
|
+
const end = offsetOf(g + 1);
|
|
149
|
+
if (end <= start) return [];
|
|
150
|
+
const r = new Reader(view, glyf.offset + start);
|
|
151
|
+
const n = r.i16();
|
|
152
|
+
r.pos += 8;
|
|
153
|
+
if (n >= 0) {
|
|
154
|
+
const ends = [];
|
|
155
|
+
for (let i = 0; i < n; i++) ends.push(r.u16());
|
|
156
|
+
const count = n ? ends[n - 1] + 1 : 0;
|
|
157
|
+
const instructions = r.u16();
|
|
158
|
+
r.pos += instructions;
|
|
159
|
+
const flags = [];
|
|
160
|
+
while (flags.length < count) {
|
|
161
|
+
const f = r.u8();
|
|
162
|
+
flags.push(f);
|
|
163
|
+
if (f & 8) for (let k = r.u8(); k > 0; k--) flags.push(f);
|
|
164
|
+
}
|
|
165
|
+
const xs = [];
|
|
166
|
+
let v = 0;
|
|
167
|
+
for (const f of flags) {
|
|
168
|
+
if (f & 2) v += f & 16 ? r.u8() : -r.u8();
|
|
169
|
+
else if (!(f & 16)) v += r.i16();
|
|
170
|
+
xs.push(v);
|
|
171
|
+
}
|
|
172
|
+
const ys = [];
|
|
173
|
+
v = 0;
|
|
174
|
+
for (const f of flags) {
|
|
175
|
+
if (f & 4) v += f & 32 ? r.u8() : -r.u8();
|
|
176
|
+
else if (!(f & 32)) v += r.i16();
|
|
177
|
+
ys.push(v);
|
|
178
|
+
}
|
|
179
|
+
const out2 = [];
|
|
180
|
+
let s = 0;
|
|
181
|
+
for (const e of ends) {
|
|
182
|
+
const c = [];
|
|
183
|
+
for (let i = s; i <= e && i < count; i++) c.push({ x: xs[i], y: ys[i], on: (flags[i] & 1) === 1 });
|
|
184
|
+
out2.push(c);
|
|
185
|
+
s = e + 1;
|
|
186
|
+
}
|
|
187
|
+
return out2;
|
|
188
|
+
}
|
|
189
|
+
const out = [];
|
|
190
|
+
for (; ; ) {
|
|
191
|
+
const flags = r.u16();
|
|
192
|
+
const glyph = r.u16();
|
|
193
|
+
let dx;
|
|
194
|
+
let dy;
|
|
195
|
+
if (flags & 1) {
|
|
196
|
+
dx = flags & 2 ? r.i16() : r.u16();
|
|
197
|
+
dy = flags & 2 ? r.i16() : r.u16();
|
|
198
|
+
} else {
|
|
199
|
+
dx = flags & 2 ? r.i8() : r.u8();
|
|
200
|
+
dy = flags & 2 ? r.i8() : r.u8();
|
|
201
|
+
}
|
|
202
|
+
if (!(flags & 2)) dx = dy = 0;
|
|
203
|
+
let a = 1;
|
|
204
|
+
let b = 0;
|
|
205
|
+
let c = 0;
|
|
206
|
+
let d = 1;
|
|
207
|
+
const f2 = () => r.i16() / 16384;
|
|
208
|
+
if (flags & 8) a = d = f2();
|
|
209
|
+
else if (flags & 64) {
|
|
210
|
+
a = f2();
|
|
211
|
+
d = f2();
|
|
212
|
+
} else if (flags & 128) {
|
|
213
|
+
a = f2();
|
|
214
|
+
b = f2();
|
|
215
|
+
c = f2();
|
|
216
|
+
d = f2();
|
|
217
|
+
}
|
|
218
|
+
for (const contour of contoursOf(glyph, depth + 1)) out.push(contour.map((p) => ({ x: a * p.x + c * p.y + dx, y: b * p.x + d * p.y + dy, on: p.on })));
|
|
219
|
+
if (!(flags & 32)) break;
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
};
|
|
223
|
+
return (g) => {
|
|
224
|
+
const cmds = [];
|
|
225
|
+
for (const c of contoursOf(g, 0)) {
|
|
226
|
+
if (!c.length) continue;
|
|
227
|
+
let first = c.findIndex((p) => p.on);
|
|
228
|
+
let pts = c;
|
|
229
|
+
if (first < 0) {
|
|
230
|
+
const m = { x: (c[0].x + c[1 % c.length].x) / 2, y: (c[0].y + c[1 % c.length].y) / 2, on: true };
|
|
231
|
+
pts = [m, ...c.slice(1), c[0]];
|
|
232
|
+
first = 0;
|
|
233
|
+
} else pts = [...c.slice(first), ...c.slice(0, first)];
|
|
234
|
+
const start = pts[0];
|
|
235
|
+
cmds.push({ type: "M", x: start.x, y: start.y });
|
|
236
|
+
let ctrl = null;
|
|
237
|
+
for (let i = 1; i <= pts.length; i++) {
|
|
238
|
+
const p = i === pts.length ? start : pts[i];
|
|
239
|
+
if (p.on) {
|
|
240
|
+
if (ctrl) cmds.push({ type: "Q", x1: ctrl.x, y1: ctrl.y, x: p.x, y: p.y });
|
|
241
|
+
else if (i < pts.length) cmds.push({ type: "L", x: p.x, y: p.y });
|
|
242
|
+
ctrl = null;
|
|
243
|
+
} else {
|
|
244
|
+
if (ctrl) cmds.push({ type: "Q", x1: ctrl.x, y1: ctrl.y, x: (ctrl.x + p.x) / 2, y: (ctrl.y + p.y) / 2 });
|
|
245
|
+
ctrl = p;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
cmds.push({ type: "Z" });
|
|
249
|
+
}
|
|
250
|
+
return cmds;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function cffIndex(view, at) {
|
|
254
|
+
const count = view.getUint16(at);
|
|
255
|
+
if (count === 0) return { items: [], end: at + 2 };
|
|
256
|
+
const size = view.getUint8(at + 2);
|
|
257
|
+
const read = (i) => {
|
|
258
|
+
let v = 0;
|
|
259
|
+
for (let k = 0; k < size; k++) v = v * 256 + view.getUint8(at + 3 + i * size + k);
|
|
260
|
+
return v;
|
|
261
|
+
};
|
|
262
|
+
const base = at + 2 + (count + 1) * size;
|
|
263
|
+
const items = [];
|
|
264
|
+
for (let i = 0; i < count; i++) items.push([base + read(i), base + read(i + 1)]);
|
|
265
|
+
return { items, end: base + read(count) };
|
|
266
|
+
}
|
|
267
|
+
function cffDict(view, start, end) {
|
|
268
|
+
const out = /* @__PURE__ */ new Map();
|
|
269
|
+
let ops = [];
|
|
270
|
+
let p = start;
|
|
271
|
+
while (p < end) {
|
|
272
|
+
const b = view.getUint8(p++);
|
|
273
|
+
if (b <= 21) {
|
|
274
|
+
const op = b === 12 ? 1200 + view.getUint8(p++) : b;
|
|
275
|
+
out.set(op, ops);
|
|
276
|
+
ops = [];
|
|
277
|
+
} else if (b === 28) {
|
|
278
|
+
ops.push(view.getInt16(p));
|
|
279
|
+
p += 2;
|
|
280
|
+
} else if (b === 29) {
|
|
281
|
+
ops.push(view.getInt32(p));
|
|
282
|
+
p += 4;
|
|
283
|
+
} else if (b === 30) {
|
|
284
|
+
let s = "";
|
|
285
|
+
const nib = "0123456789.EE?-";
|
|
286
|
+
for (; ; ) {
|
|
287
|
+
const v = view.getUint8(p++);
|
|
288
|
+
const hi = v >> 4;
|
|
289
|
+
const lo = v & 15;
|
|
290
|
+
if (hi === 15) break;
|
|
291
|
+
s += hi === 12 ? "E-" : nib[hi];
|
|
292
|
+
if (lo === 15) break;
|
|
293
|
+
s += lo === 12 ? "E-" : nib[lo];
|
|
294
|
+
}
|
|
295
|
+
ops.push(parseFloat(s));
|
|
296
|
+
} else if (b >= 32 && b <= 246) ops.push(b - 139);
|
|
297
|
+
else if (b >= 247 && b <= 250) ops.push((b - 247) * 256 + view.getUint8(p++) + 108);
|
|
298
|
+
else if (b >= 251 && b <= 254) ops.push(-(b - 251) * 256 - view.getUint8(p++) - 108);
|
|
299
|
+
else break;
|
|
300
|
+
}
|
|
301
|
+
return out;
|
|
302
|
+
}
|
|
303
|
+
var subrBias = (n) => n < 1240 ? 107 : n < 33900 ? 1131 : 32768;
|
|
304
|
+
function cffOutlines(view, t, numGlyphs) {
|
|
305
|
+
const base = t.offset;
|
|
306
|
+
const hdrSize = view.getUint8(base + 2);
|
|
307
|
+
const names = cffIndex(view, base + hdrSize);
|
|
308
|
+
const tops = cffIndex(view, names.end);
|
|
309
|
+
const strings = cffIndex(view, tops.end);
|
|
310
|
+
const gsubrs = cffIndex(view, strings.end).items;
|
|
311
|
+
if (!tops.items.length) fail("The font's CFF table has no Top DICT.");
|
|
312
|
+
const top = cffDict(view, tops.items[0][0], tops.items[0][1]);
|
|
313
|
+
const charStrings = cffIndex(view, base + (top.get(17)?.[0] ?? fail("The font's CFF table has no CharStrings."))).items;
|
|
314
|
+
const privateOf = (dict) => {
|
|
315
|
+
const pv = dict.get(18);
|
|
316
|
+
if (!pv || pv.length < 2) return { subrs: [], defaultWidth: 0, nominalWidth: 0 };
|
|
317
|
+
const [size, off] = pv;
|
|
318
|
+
const priv = cffDict(view, base + off, base + off + size);
|
|
319
|
+
const subrsOff = priv.get(19)?.[0];
|
|
320
|
+
return {
|
|
321
|
+
subrs: subrsOff !== void 0 ? cffIndex(view, base + off + subrsOff).items : [],
|
|
322
|
+
defaultWidth: priv.get(20)?.[0] ?? 0,
|
|
323
|
+
nominalWidth: priv.get(21)?.[0] ?? 0
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
let fdFor;
|
|
327
|
+
const fdArrayOff = top.get(1236)?.[0];
|
|
328
|
+
const fdSelectOff = top.get(1237)?.[0];
|
|
329
|
+
if (fdArrayOff !== void 0 && fdSelectOff !== void 0) {
|
|
330
|
+
const fds = cffIndex(view, base + fdArrayOff).items.map(([a, b]) => privateOf(cffDict(view, a, b)));
|
|
331
|
+
const sel = base + fdSelectOff;
|
|
332
|
+
const format = view.getUint8(sel);
|
|
333
|
+
if (format === 0) fdFor = (g) => fds[view.getUint8(sel + 1 + g)] ?? fds[0];
|
|
334
|
+
else {
|
|
335
|
+
const ranges = view.getUint16(sel + 1);
|
|
336
|
+
fdFor = (g) => {
|
|
337
|
+
for (let i = 0; i < ranges; i++) {
|
|
338
|
+
const first = view.getUint16(sel + 3 + i * 3);
|
|
339
|
+
const next = view.getUint16(sel + 3 + (i + 1) * 3);
|
|
340
|
+
if (g >= first && g < next) return fds[view.getUint8(sel + 5 + i * 3)] ?? fds[0];
|
|
341
|
+
}
|
|
342
|
+
return fds[0];
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
const p = privateOf(top);
|
|
347
|
+
fdFor = () => p;
|
|
348
|
+
}
|
|
349
|
+
const widths = /* @__PURE__ */ new Map();
|
|
350
|
+
const run = (g) => {
|
|
351
|
+
const priv = fdFor(g);
|
|
352
|
+
const cmds = [];
|
|
353
|
+
const stack = [];
|
|
354
|
+
let x = 0;
|
|
355
|
+
let y = 0;
|
|
356
|
+
let stems = 0;
|
|
357
|
+
let open = false;
|
|
358
|
+
let width = null;
|
|
359
|
+
let haveWidth = false;
|
|
360
|
+
let done = false;
|
|
361
|
+
const moveTo = (nx, ny) => {
|
|
362
|
+
if (open) cmds.push({ type: "Z" });
|
|
363
|
+
x = nx;
|
|
364
|
+
y = ny;
|
|
365
|
+
cmds.push({ type: "M", x, y });
|
|
366
|
+
open = true;
|
|
367
|
+
};
|
|
368
|
+
const lineTo = (nx, ny) => {
|
|
369
|
+
x = nx;
|
|
370
|
+
y = ny;
|
|
371
|
+
cmds.push({ type: "L", x, y });
|
|
372
|
+
};
|
|
373
|
+
const curveTo = (x1, y1, x2, y2, nx, ny) => {
|
|
374
|
+
x = nx;
|
|
375
|
+
y = ny;
|
|
376
|
+
cmds.push({ type: "C", x1, y1, x2, y2, x, y });
|
|
377
|
+
};
|
|
378
|
+
const takeWidth = () => {
|
|
379
|
+
if (haveWidth) return;
|
|
380
|
+
haveWidth = true;
|
|
381
|
+
if (stack.length % 2 === 1) width = priv.nominalWidth + stack.shift();
|
|
382
|
+
};
|
|
383
|
+
const exec = (start, end, depth) => {
|
|
384
|
+
let p = start;
|
|
385
|
+
while (p < end && !done) {
|
|
386
|
+
const b = view.getUint8(p++);
|
|
387
|
+
if (b >= 32 || b === 28) {
|
|
388
|
+
if (b === 28) {
|
|
389
|
+
stack.push(view.getInt16(p));
|
|
390
|
+
p += 2;
|
|
391
|
+
} else if (b <= 246) stack.push(b - 139);
|
|
392
|
+
else if (b <= 250) stack.push((b - 247) * 256 + view.getUint8(p++) + 108);
|
|
393
|
+
else if (b <= 254) stack.push(-(b - 251) * 256 - view.getUint8(p++) - 108);
|
|
394
|
+
else {
|
|
395
|
+
stack.push(view.getInt32(p) / 65536);
|
|
396
|
+
p += 4;
|
|
397
|
+
}
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
switch (b) {
|
|
401
|
+
case 1:
|
|
402
|
+
case 3:
|
|
403
|
+
case 18:
|
|
404
|
+
case 23:
|
|
405
|
+
takeWidth();
|
|
406
|
+
stems += stack.length >> 1;
|
|
407
|
+
stack.length = 0;
|
|
408
|
+
break;
|
|
409
|
+
case 19:
|
|
410
|
+
case 20:
|
|
411
|
+
takeWidth();
|
|
412
|
+
stems += stack.length >> 1;
|
|
413
|
+
stack.length = 0;
|
|
414
|
+
p += stems + 7 >> 3;
|
|
415
|
+
break;
|
|
416
|
+
case 21:
|
|
417
|
+
takeWidth();
|
|
418
|
+
moveTo(x + stack[0], y + stack[1]);
|
|
419
|
+
stack.length = 0;
|
|
420
|
+
break;
|
|
421
|
+
case 22:
|
|
422
|
+
if (!haveWidth) {
|
|
423
|
+
haveWidth = true;
|
|
424
|
+
if (stack.length > 1) width = priv.nominalWidth + stack.shift();
|
|
425
|
+
}
|
|
426
|
+
moveTo(x + stack[0], y);
|
|
427
|
+
stack.length = 0;
|
|
428
|
+
break;
|
|
429
|
+
case 4:
|
|
430
|
+
if (!haveWidth) {
|
|
431
|
+
haveWidth = true;
|
|
432
|
+
if (stack.length > 1) width = priv.nominalWidth + stack.shift();
|
|
433
|
+
}
|
|
434
|
+
moveTo(x, y + stack[0]);
|
|
435
|
+
stack.length = 0;
|
|
436
|
+
break;
|
|
437
|
+
case 5:
|
|
438
|
+
for (let i = 0; i + 1 < stack.length; i += 2) lineTo(x + stack[i], y + stack[i + 1]);
|
|
439
|
+
stack.length = 0;
|
|
440
|
+
break;
|
|
441
|
+
case 6:
|
|
442
|
+
case 7: {
|
|
443
|
+
let horizontal = b === 6;
|
|
444
|
+
for (const v of stack) {
|
|
445
|
+
if (horizontal) lineTo(x + v, y);
|
|
446
|
+
else lineTo(x, y + v);
|
|
447
|
+
horizontal = !horizontal;
|
|
448
|
+
}
|
|
449
|
+
stack.length = 0;
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
case 8:
|
|
453
|
+
for (let i = 0; i + 5 < stack.length; i += 6) curveTo(x + stack[i], y + stack[i + 1], x + stack[i] + stack[i + 2], y + stack[i + 1] + stack[i + 3], x + stack[i] + stack[i + 2] + stack[i + 4], y + stack[i + 1] + stack[i + 3] + stack[i + 5]);
|
|
454
|
+
stack.length = 0;
|
|
455
|
+
break;
|
|
456
|
+
case 24: {
|
|
457
|
+
let i = 0;
|
|
458
|
+
for (; i + 7 < stack.length; i += 6) curveTo(x + stack[i], y + stack[i + 1], x + stack[i] + stack[i + 2], y + stack[i + 1] + stack[i + 3], x + stack[i] + stack[i + 2] + stack[i + 4], y + stack[i + 1] + stack[i + 3] + stack[i + 5]);
|
|
459
|
+
lineTo(x + stack[i], y + stack[i + 1]);
|
|
460
|
+
stack.length = 0;
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case 25: {
|
|
464
|
+
let i = 0;
|
|
465
|
+
for (; i + 7 < stack.length; i += 2) lineTo(x + stack[i], y + stack[i + 1]);
|
|
466
|
+
curveTo(x + stack[i], y + stack[i + 1], x + stack[i] + stack[i + 2], y + stack[i + 1] + stack[i + 3], x + stack[i] + stack[i + 2] + stack[i + 4], y + stack[i + 1] + stack[i + 3] + stack[i + 5]);
|
|
467
|
+
stack.length = 0;
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
case 26: {
|
|
471
|
+
let i = 0;
|
|
472
|
+
let dx = 0;
|
|
473
|
+
if (stack.length % 2) dx = stack[i++];
|
|
474
|
+
for (; i + 3 < stack.length; i += 4) {
|
|
475
|
+
const x1 = x + dx;
|
|
476
|
+
const y1 = y + stack[i];
|
|
477
|
+
curveTo(x1, y1, x1 + stack[i + 1], y1 + stack[i + 2], x1 + stack[i + 1], y1 + stack[i + 2] + stack[i + 3]);
|
|
478
|
+
dx = 0;
|
|
479
|
+
}
|
|
480
|
+
stack.length = 0;
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
case 27: {
|
|
484
|
+
let i = 0;
|
|
485
|
+
let dy = 0;
|
|
486
|
+
if (stack.length % 2) dy = stack[i++];
|
|
487
|
+
for (; i + 3 < stack.length; i += 4) {
|
|
488
|
+
const x1 = x + stack[i];
|
|
489
|
+
const y1 = y + dy;
|
|
490
|
+
curveTo(x1, y1, x1 + stack[i + 1], y1 + stack[i + 2], x1 + stack[i + 1] + stack[i + 3], y1 + stack[i + 2]);
|
|
491
|
+
dy = 0;
|
|
492
|
+
}
|
|
493
|
+
stack.length = 0;
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
case 30:
|
|
497
|
+
case 31: {
|
|
498
|
+
let horizontal = b === 31;
|
|
499
|
+
let i = 0;
|
|
500
|
+
while (i + 3 < stack.length) {
|
|
501
|
+
const last = stack.length - i === 5;
|
|
502
|
+
if (horizontal) {
|
|
503
|
+
const x1 = x + stack[i];
|
|
504
|
+
const y1 = y;
|
|
505
|
+
const x2 = x1 + stack[i + 1];
|
|
506
|
+
const y2 = y1 + stack[i + 2];
|
|
507
|
+
const y3 = y2 + stack[i + 3];
|
|
508
|
+
curveTo(x1, y1, x2, y2, last ? x2 + stack[i + 4] : x2, y3);
|
|
509
|
+
} else {
|
|
510
|
+
const x1 = x;
|
|
511
|
+
const y1 = y + stack[i];
|
|
512
|
+
const x2 = x1 + stack[i + 1];
|
|
513
|
+
const y2 = y1 + stack[i + 2];
|
|
514
|
+
const x3 = x2 + stack[i + 3];
|
|
515
|
+
curveTo(x1, y1, x2, y2, x3, last ? y2 + stack[i + 4] : y2);
|
|
516
|
+
}
|
|
517
|
+
i += last ? 5 : 4;
|
|
518
|
+
horizontal = !horizontal;
|
|
519
|
+
}
|
|
520
|
+
stack.length = 0;
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
case 10:
|
|
524
|
+
case 29: {
|
|
525
|
+
const list = b === 10 ? priv.subrs : gsubrs;
|
|
526
|
+
const idx = stack.pop() + subrBias(list.length);
|
|
527
|
+
const sub = list[idx];
|
|
528
|
+
if (sub && depth < 10) exec(sub[0], sub[1], depth + 1);
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case 11:
|
|
532
|
+
return;
|
|
533
|
+
case 14:
|
|
534
|
+
takeWidth();
|
|
535
|
+
if (open) cmds.push({ type: "Z" });
|
|
536
|
+
open = false;
|
|
537
|
+
done = true;
|
|
538
|
+
stack.length = 0;
|
|
539
|
+
return;
|
|
540
|
+
case 12: {
|
|
541
|
+
const op = view.getUint8(p++);
|
|
542
|
+
const s = stack;
|
|
543
|
+
if (op === 35 && s.length >= 13) {
|
|
544
|
+
curveTo(x + s[0], y + s[1], x + s[0] + s[2], y + s[1] + s[3], x + s[0] + s[2] + s[4], y + s[1] + s[3] + s[5]);
|
|
545
|
+
curveTo(x + s[6], y + s[7], x + s[6] + s[8], y + s[7] + s[9], x + s[6] + s[8] + s[10], y + s[7] + s[9] + s[11]);
|
|
546
|
+
} else if (op === 34 && s.length >= 7) {
|
|
547
|
+
const y0 = y;
|
|
548
|
+
curveTo(x + s[0], y, x + s[0] + s[1], y + s[2], x + s[0] + s[1] + s[3], y + s[2]);
|
|
549
|
+
curveTo(x + s[4], y, x + s[4] + s[5], y0, x + s[4] + s[5] + s[6], y0);
|
|
550
|
+
} else if (op === 36 && s.length >= 9) {
|
|
551
|
+
const y0 = y;
|
|
552
|
+
curveTo(x + s[0], y + s[1], x + s[0] + s[2], y + s[1] + s[3], x + s[0] + s[2] + s[4], y + s[1] + s[3]);
|
|
553
|
+
curveTo(x + s[5], y, x + s[5] + s[6], y + s[7], x + s[5] + s[6] + s[8], y0);
|
|
554
|
+
} else if (op === 37 && s.length >= 11) {
|
|
555
|
+
const x0 = x;
|
|
556
|
+
const y0 = y;
|
|
557
|
+
const x1 = x + s[0];
|
|
558
|
+
const y1 = y + s[1];
|
|
559
|
+
const x2 = x1 + s[2];
|
|
560
|
+
const y2 = y1 + s[3];
|
|
561
|
+
const x3 = x2 + s[4];
|
|
562
|
+
const y3 = y2 + s[5];
|
|
563
|
+
const x4 = x3 + s[6];
|
|
564
|
+
const y4 = y3 + s[7];
|
|
565
|
+
const x5 = x4 + s[8];
|
|
566
|
+
const y5 = y4 + s[9];
|
|
567
|
+
curveTo(x1, y1, x2, y2, x3, y3);
|
|
568
|
+
if (Math.abs(x5 - x0) > Math.abs(y5 - y0)) curveTo(x4, y4, x5, y5, x5 + s[10], y0);
|
|
569
|
+
else curveTo(x4, y4, x5, y5, x0, y5 + s[10]);
|
|
570
|
+
}
|
|
571
|
+
stack.length = 0;
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
default:
|
|
575
|
+
stack.length = 0;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
const cs = charStrings[g];
|
|
580
|
+
if (cs) exec(cs[0], cs[1], 0);
|
|
581
|
+
if (open) cmds.push({ type: "Z" });
|
|
582
|
+
widths.set(g, width ?? (haveWidth ? priv.defaultWidth : null));
|
|
583
|
+
return cmds;
|
|
584
|
+
};
|
|
585
|
+
return {
|
|
586
|
+
path: (g) => g >= 0 && g < numGlyphs ? run(g) : [],
|
|
587
|
+
width: (g) => {
|
|
588
|
+
if (!widths.has(g)) run(g);
|
|
589
|
+
return widths.get(g) ?? null;
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function readKern(view, t) {
|
|
594
|
+
const out = /* @__PURE__ */ new Map();
|
|
595
|
+
if (!t) return out;
|
|
596
|
+
const r = new Reader(view, t.offset);
|
|
597
|
+
const version = r.u16();
|
|
598
|
+
if (version !== 0) return out;
|
|
599
|
+
const n = r.u16();
|
|
600
|
+
for (let i = 0; i < n; i++) {
|
|
601
|
+
const start = r.pos;
|
|
602
|
+
r.u16();
|
|
603
|
+
const length = r.u16();
|
|
604
|
+
const coverage = r.u16();
|
|
605
|
+
if (coverage >> 8 === 0 && (coverage & 1) === 1) {
|
|
606
|
+
const pairs = r.u16();
|
|
607
|
+
r.pos += 6;
|
|
608
|
+
for (let k = 0; k < pairs; k++) {
|
|
609
|
+
const left = r.u16();
|
|
610
|
+
const right = r.u16();
|
|
611
|
+
out.set(left * 65536 + right, r.i16());
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
r.pos = start + length;
|
|
615
|
+
}
|
|
616
|
+
return out;
|
|
617
|
+
}
|
|
618
|
+
function coverageIndex(view, at, g) {
|
|
619
|
+
const format = view.getUint16(at);
|
|
620
|
+
const n = view.getUint16(at + 2);
|
|
621
|
+
if (format === 1) {
|
|
622
|
+
let lo = 0;
|
|
623
|
+
let hi = n - 1;
|
|
624
|
+
while (lo <= hi) {
|
|
625
|
+
const mid = lo + hi >> 1;
|
|
626
|
+
const v = view.getUint16(at + 4 + mid * 2);
|
|
627
|
+
if (v === g) return mid;
|
|
628
|
+
if (v < g) lo = mid + 1;
|
|
629
|
+
else hi = mid - 1;
|
|
630
|
+
}
|
|
631
|
+
return -1;
|
|
632
|
+
}
|
|
633
|
+
for (let i = 0; i < n; i++) {
|
|
634
|
+
const r = at + 4 + i * 6;
|
|
635
|
+
const s = view.getUint16(r);
|
|
636
|
+
const e = view.getUint16(r + 2);
|
|
637
|
+
if (g >= s && g <= e) return view.getUint16(r + 4) + g - s;
|
|
638
|
+
}
|
|
639
|
+
return -1;
|
|
640
|
+
}
|
|
641
|
+
function classOf(view, at, g) {
|
|
642
|
+
const format = view.getUint16(at);
|
|
643
|
+
if (format === 1) {
|
|
644
|
+
const start = view.getUint16(at + 2);
|
|
645
|
+
const n2 = view.getUint16(at + 4);
|
|
646
|
+
return g >= start && g < start + n2 ? view.getUint16(at + 6 + (g - start) * 2) : 0;
|
|
647
|
+
}
|
|
648
|
+
const n = view.getUint16(at + 2);
|
|
649
|
+
for (let i = 0; i < n; i++) {
|
|
650
|
+
const r = at + 4 + i * 6;
|
|
651
|
+
if (g >= view.getUint16(r) && g <= view.getUint16(r + 2)) return view.getUint16(r + 4);
|
|
652
|
+
}
|
|
653
|
+
return 0;
|
|
654
|
+
}
|
|
655
|
+
var valueSize = (format) => {
|
|
656
|
+
let n = 0;
|
|
657
|
+
for (let f = format; f; f >>= 1) n += f & 1;
|
|
658
|
+
return n * 2;
|
|
659
|
+
};
|
|
660
|
+
function xAdvance(view, at, format) {
|
|
661
|
+
if (!(format & 4)) return 0;
|
|
662
|
+
let skip = 0;
|
|
663
|
+
if (format & 1) skip += 2;
|
|
664
|
+
if (format & 2) skip += 2;
|
|
665
|
+
return view.getInt16(at + skip);
|
|
666
|
+
}
|
|
667
|
+
function gposKerning(view, t) {
|
|
668
|
+
if (!t) return null;
|
|
669
|
+
const base = t.offset;
|
|
670
|
+
const scripts = base + view.getUint16(base + 4);
|
|
671
|
+
const features = base + view.getUint16(base + 6);
|
|
672
|
+
const lookups = base + view.getUint16(base + 8);
|
|
673
|
+
void scripts;
|
|
674
|
+
const lookupIds = /* @__PURE__ */ new Set();
|
|
675
|
+
const nf = view.getUint16(features);
|
|
676
|
+
for (let i = 0; i < nf; i++) {
|
|
677
|
+
const rec = features + 2 + i * 6;
|
|
678
|
+
let tag = "";
|
|
679
|
+
for (let k = 0; k < 4; k++) tag += String.fromCharCode(view.getUint8(rec + k));
|
|
680
|
+
if (tag !== "kern") continue;
|
|
681
|
+
const f = features + view.getUint16(rec + 4);
|
|
682
|
+
const n = view.getUint16(f + 2);
|
|
683
|
+
for (let k = 0; k < n; k++) lookupIds.add(view.getUint16(f + 4 + k * 2));
|
|
684
|
+
}
|
|
685
|
+
const subtables = [];
|
|
686
|
+
const nl = view.getUint16(lookups);
|
|
687
|
+
for (const id of [...lookupIds].sort((a, b) => a - b)) {
|
|
688
|
+
if (id >= nl) continue;
|
|
689
|
+
const l = lookups + view.getUint16(lookups + 2 + id * 2);
|
|
690
|
+
let type = view.getUint16(l);
|
|
691
|
+
const n = view.getUint16(l + 4);
|
|
692
|
+
for (let k = 0; k < n; k++) {
|
|
693
|
+
let st = l + view.getUint16(l + 6 + k * 2);
|
|
694
|
+
if (type === 9) {
|
|
695
|
+
type = view.getUint16(st + 2);
|
|
696
|
+
st = st + view.getUint32(st + 4);
|
|
697
|
+
}
|
|
698
|
+
if (type === 2) subtables.push(st);
|
|
699
|
+
type = view.getUint16(l);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (!subtables.length) return null;
|
|
703
|
+
return (a, b) => {
|
|
704
|
+
for (const st of subtables) {
|
|
705
|
+
const format = view.getUint16(st);
|
|
706
|
+
const ci = coverageIndex(view, st + view.getUint16(st + 2), a);
|
|
707
|
+
if (ci < 0) continue;
|
|
708
|
+
const vf1 = view.getUint16(st + 4);
|
|
709
|
+
const vf2 = view.getUint16(st + 6);
|
|
710
|
+
const recSize = valueSize(vf1) + valueSize(vf2);
|
|
711
|
+
if (format === 1) {
|
|
712
|
+
const set = st + view.getUint16(st + 10 + ci * 2);
|
|
713
|
+
const n = view.getUint16(set);
|
|
714
|
+
let lo = 0;
|
|
715
|
+
let hi = n - 1;
|
|
716
|
+
while (lo <= hi) {
|
|
717
|
+
const mid = lo + hi >> 1;
|
|
718
|
+
const rec = set + 2 + mid * (2 + recSize);
|
|
719
|
+
const g = view.getUint16(rec);
|
|
720
|
+
if (g === b) return xAdvance(view, rec + 2, vf1);
|
|
721
|
+
if (g < b) lo = mid + 1;
|
|
722
|
+
else hi = mid - 1;
|
|
723
|
+
}
|
|
724
|
+
} else if (format === 2) {
|
|
725
|
+
const c1 = classOf(view, st + view.getUint16(st + 8), a);
|
|
726
|
+
const c2 = classOf(view, st + view.getUint16(st + 10), b);
|
|
727
|
+
const n2 = view.getUint16(st + 14);
|
|
728
|
+
const rec = st + 16 + (c1 * n2 + c2) * recSize;
|
|
729
|
+
const v = xAdvance(view, rec, vf1);
|
|
730
|
+
if (v) return v;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return 0;
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
var toView = (data) => data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
737
|
+
function parseOpenTypeFont(data, options = {}) {
|
|
738
|
+
const view = toView(data);
|
|
739
|
+
if (view.byteLength < 12) fail("The font file is too short.");
|
|
740
|
+
let at = 0;
|
|
741
|
+
if (view.getUint32(0) === 1953784678) {
|
|
742
|
+
const n = view.getUint32(8);
|
|
743
|
+
const index = options.index ?? 0;
|
|
744
|
+
if (index < 0 || index >= n) fail(`The collection has ${n} faces; index ${index} is out of range.`);
|
|
745
|
+
at = view.getUint32(12 + index * 4);
|
|
746
|
+
}
|
|
747
|
+
const tables = tableDirectory(view, at);
|
|
748
|
+
const need = (tag) => tables.get(tag) ?? fail(`The font has no "${tag}" table.`);
|
|
749
|
+
const head = need("head");
|
|
750
|
+
const unitsPerEm = view.getUint16(head.offset + 18) || 1e3;
|
|
751
|
+
const longLoca = view.getInt16(head.offset + 50) === 1;
|
|
752
|
+
const macStyle = view.getUint16(head.offset + 44);
|
|
753
|
+
const hhea = need("hhea");
|
|
754
|
+
let ascender = view.getInt16(hhea.offset + 4);
|
|
755
|
+
let descender = view.getInt16(hhea.offset + 6);
|
|
756
|
+
const numHMetrics = view.getUint16(hhea.offset + 34);
|
|
757
|
+
const numGlyphs = view.getUint16(need("maxp").offset + 4);
|
|
758
|
+
const hmtx = need("hmtx");
|
|
759
|
+
const os2 = tables.get("OS/2");
|
|
760
|
+
let weight = macStyle & 1 ? 700 : 400;
|
|
761
|
+
let fsSelection = macStyle & 2 ? 1 : 0;
|
|
762
|
+
if (os2 && os2.length >= 78) {
|
|
763
|
+
weight = view.getUint16(os2.offset + 4) || weight;
|
|
764
|
+
fsSelection = view.getUint16(os2.offset + 62);
|
|
765
|
+
if (fsSelection & 128) {
|
|
766
|
+
ascender = view.getInt16(os2.offset + 68);
|
|
767
|
+
descender = view.getInt16(os2.offset + 70);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
if (!ascender && !descender) {
|
|
771
|
+
ascender = Math.round(unitsPerEm * 0.8);
|
|
772
|
+
descender = -Math.round(unitsPerEm * 0.2);
|
|
773
|
+
}
|
|
774
|
+
const names = readNames(view, tables.get("name"));
|
|
775
|
+
const family = names.get(16) ?? names.get(1) ?? "Font";
|
|
776
|
+
const style = names.get(17) ?? names.get(2) ?? "Regular";
|
|
777
|
+
const postScriptName = names.get(6) ?? family.replace(/\s+/g, "");
|
|
778
|
+
const italic = Boolean(fsSelection & 1) || /italic|oblique/i.test(style);
|
|
779
|
+
const cmap = readCmap(view, need("cmap"));
|
|
780
|
+
const glyf = tables.get("glyf");
|
|
781
|
+
const cff = tables.get("CFF ");
|
|
782
|
+
let pathOf;
|
|
783
|
+
let cffWidth = null;
|
|
784
|
+
let outlines;
|
|
785
|
+
if (glyf) {
|
|
786
|
+
pathOf = glyfOutlines(view, glyf, need("loca"), longLoca, numGlyphs);
|
|
787
|
+
outlines = "glyf";
|
|
788
|
+
} else if (cff) {
|
|
789
|
+
const c = cffOutlines(view, cff, numGlyphs);
|
|
790
|
+
pathOf = c.path;
|
|
791
|
+
cffWidth = c.width;
|
|
792
|
+
outlines = "cff";
|
|
793
|
+
} else return fail('The font has neither TrueType ("glyf") nor CFF outlines (CFF2 and bitmap fonts are not supported).');
|
|
794
|
+
const advance = (g) => {
|
|
795
|
+
if (g < 0 || g >= numGlyphs) return 0;
|
|
796
|
+
const i = Math.min(g, numHMetrics - 1);
|
|
797
|
+
if (i >= 0 && hmtx.offset + i * 4 + 2 <= hmtx.offset + hmtx.length) return view.getUint16(hmtx.offset + i * 4);
|
|
798
|
+
return cffWidth?.(g) ?? 0;
|
|
799
|
+
};
|
|
800
|
+
const kernPairs = readKern(view, tables.get("kern"));
|
|
801
|
+
const gpos = gposKerning(view, tables.get("GPOS"));
|
|
802
|
+
const kerning = (a, b) => (gpos ? gpos(a, b) : 0) || kernPairs.get(a * 65536 + b) || 0;
|
|
803
|
+
const glyphIndex = (cp) => cmap(cp);
|
|
804
|
+
const pathCache = /* @__PURE__ */ new Map();
|
|
805
|
+
const glyphPath = (g) => {
|
|
806
|
+
let p = pathCache.get(g);
|
|
807
|
+
if (!p) {
|
|
808
|
+
p = pathOf(g);
|
|
809
|
+
if (pathCache.size > 4096) pathCache.clear();
|
|
810
|
+
pathCache.set(g, p);
|
|
811
|
+
}
|
|
812
|
+
return p;
|
|
813
|
+
};
|
|
814
|
+
const glyphs = (text) => {
|
|
815
|
+
const out = [];
|
|
816
|
+
for (const ch of text) {
|
|
817
|
+
const cp = ch.codePointAt(0);
|
|
818
|
+
if (cp >= 55296 && cp <= 57343 || cp === 10 || cp === 13) continue;
|
|
819
|
+
out.push(glyphIndex(cp));
|
|
820
|
+
}
|
|
821
|
+
return out;
|
|
822
|
+
};
|
|
823
|
+
const layout = (text, kern) => {
|
|
824
|
+
const gs = glyphs(text);
|
|
825
|
+
const xs = [];
|
|
826
|
+
let x = 0;
|
|
827
|
+
for (let i = 0; i < gs.length; i++) {
|
|
828
|
+
if (i > 0 && kern) x += kerning(gs[i - 1], gs[i]);
|
|
829
|
+
xs.push(x);
|
|
830
|
+
x += advance(gs[i]);
|
|
831
|
+
}
|
|
832
|
+
return { gs, xs, width: x };
|
|
833
|
+
};
|
|
834
|
+
return {
|
|
835
|
+
family,
|
|
836
|
+
style,
|
|
837
|
+
postScriptName,
|
|
838
|
+
weight,
|
|
839
|
+
italic,
|
|
840
|
+
numGlyphs,
|
|
841
|
+
outlines,
|
|
842
|
+
unitsPerEm,
|
|
843
|
+
ascender,
|
|
844
|
+
descender,
|
|
845
|
+
names: { fontFamily: { en: family }, postScriptName: { en: postScriptName } },
|
|
846
|
+
tables: { os2: { usWeightClass: weight, fsSelection: italic ? fsSelection | 1 : fsSelection } },
|
|
847
|
+
glyphIndex,
|
|
848
|
+
advance,
|
|
849
|
+
kerning,
|
|
850
|
+
glyphPath,
|
|
851
|
+
getAdvanceWidth(text, fontSize, opts) {
|
|
852
|
+
return layout(text, opts?.kerning !== false).width * fontSize / unitsPerEm;
|
|
853
|
+
},
|
|
854
|
+
getPath(text, x, y, fontSize, opts) {
|
|
855
|
+
const k = fontSize / unitsPerEm;
|
|
856
|
+
const { gs, xs } = layout(text, opts?.kerning !== false);
|
|
857
|
+
const commands = [];
|
|
858
|
+
gs.forEach((g, i) => {
|
|
859
|
+
const ox = x + xs[i] * k;
|
|
860
|
+
for (const c of glyphPath(g)) {
|
|
861
|
+
if (c.type === "Z") commands.push({ type: "Z" });
|
|
862
|
+
else {
|
|
863
|
+
const m = { type: c.type, x: ox + c.x * k, y: y - c.y * k };
|
|
864
|
+
if (c.x1 !== void 0) {
|
|
865
|
+
m.x1 = ox + c.x1 * k;
|
|
866
|
+
m.y1 = y - c.y1 * k;
|
|
867
|
+
}
|
|
868
|
+
if (c.x2 !== void 0) {
|
|
869
|
+
m.x2 = ox + c.x2 * k;
|
|
870
|
+
m.y2 = y - c.y2 * k;
|
|
871
|
+
}
|
|
872
|
+
commands.push(m);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
return { commands };
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
async function loadOpenTypeFont(data, options = {}) {
|
|
881
|
+
const buffer = typeof Blob !== "undefined" && data instanceof Blob ? await data.arrayBuffer() : data;
|
|
882
|
+
const view = toView(buffer);
|
|
883
|
+
const sig = view.byteLength >= 4 ? view.getUint32(0) : 0;
|
|
884
|
+
if (sig === 2001684018) fail("WOFF2 fonts are not supported (they need Brotli); use the TTF, OTF or WOFF file.");
|
|
885
|
+
if (sig !== 2001684038) return parseOpenTypeFont(view, options);
|
|
886
|
+
return parseOpenTypeFont(await unwoff(view), options);
|
|
887
|
+
}
|
|
888
|
+
async function inflate(bytes) {
|
|
889
|
+
if (typeof DecompressionStream === "undefined") fail("Reading WOFF fonts needs DecompressionStream, which this platform lacks; use the TTF or OTF file.");
|
|
890
|
+
const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream("deflate"));
|
|
891
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
892
|
+
}
|
|
893
|
+
async function unwoff(view) {
|
|
894
|
+
const r = new Reader(view, 4);
|
|
895
|
+
const flavor = r.u32();
|
|
896
|
+
r.u32();
|
|
897
|
+
const n = r.u16();
|
|
898
|
+
r.u16();
|
|
899
|
+
const total = r.u32();
|
|
900
|
+
const out = new Uint8Array(total);
|
|
901
|
+
const o = new DataView(out.buffer);
|
|
902
|
+
o.setUint32(0, flavor);
|
|
903
|
+
o.setUint16(4, n);
|
|
904
|
+
let pos = 12 + n * 16;
|
|
905
|
+
for (let i = 0; i < n; i++) {
|
|
906
|
+
const e = 44 + i * 20;
|
|
907
|
+
const tag = view.getUint32(e);
|
|
908
|
+
const offset = view.getUint32(e + 4);
|
|
909
|
+
const comp = view.getUint32(e + 8);
|
|
910
|
+
const orig = view.getUint32(e + 12);
|
|
911
|
+
const checksum = view.getUint32(e + 16);
|
|
912
|
+
const raw = new Uint8Array(view.buffer, view.byteOffset + offset, comp);
|
|
913
|
+
const bytes = comp < orig ? await inflate(raw) : raw;
|
|
914
|
+
out.set(bytes.subarray(0, orig), pos);
|
|
915
|
+
const d = 12 + i * 16;
|
|
916
|
+
o.setUint32(d, tag);
|
|
917
|
+
o.setUint32(d + 4, checksum);
|
|
918
|
+
o.setUint32(d + 8, pos);
|
|
919
|
+
o.setUint32(d + 12, orig);
|
|
920
|
+
pos += orig + 3 & ~3;
|
|
921
|
+
}
|
|
922
|
+
return o;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
export {
|
|
926
|
+
parseOpenTypeFont,
|
|
927
|
+
loadOpenTypeFont
|
|
928
|
+
};
|
|
929
|
+
//# sourceMappingURL=chunk-3UFGNHSP.js.map
|