@web-ppt/fonts 0.5.0-beta.2 → 0.5.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/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * @web-ppt/fonts —— 字体替换与按需加载。
3
3
  *
4
- * 文件带了嵌入字体时不需要这个包(`setFontDecoder` 那条路保真度更高);
5
- * 这里解决的是**文件没带字体、本机也没装**的情况:拉丁用度量兼容的免费字体,
4
+ * 默认入口解决的是**文件没带字体、本机也没装**的情况:拉丁用度量兼容的免费字体,
6
5
  * 断行与 PowerPoint 逐字对齐;中文换成思源系,行高靠 @font-face 描述符拉近。
7
6
  *
8
7
  * 包里**一个字节的字体都没有**:切片指向 fontsource 的已发布版本,
9
8
  * 由 jsDelivr 分发,用不到就不下载。
9
+ * 显式字体字节与字形能力见独立的 ./glyphs 按需入口。
10
10
  */
11
11
  export { SUBSTITUTIONS, substituteFor } from './substitute';
12
12
  export type { Substitution } from './substitute';
package/dist/load.d.ts CHANGED
@@ -56,7 +56,9 @@ export declare function isInstalled(family: string, doc?: Document): boolean;
56
56
  * (我们是把 CSS 文本注入到页面里,相对路径会按页面地址解析,必然 404)。
57
57
  * `unicode-range` 原样保留——按需下载全靠它。
58
58
  */
59
- export declare function rewriteFontFaceCss(css: string, original: string, cssHref: string): string;
59
+ export declare function rewriteFontFaceCss(css: string, original: string, cssHref: string, opts?: {
60
+ readonly preferLocal?: boolean;
61
+ }): string;
60
62
  /**
61
63
  * 为一份演示文稿的字体用量准备好网络字体。
62
64
  *
@@ -0,0 +1,617 @@
1
+ import { F as v, r as M, i as F } from "./fault-HMYM9DhC.js";
2
+ function Q(n, e) {
3
+ if (!e) return n;
4
+ const o = ["installable", "editable", "view-print", "restricted"];
5
+ if (!o.includes(e.usage) || typeof e.subsetAllowed != "boolean" || typeof e.outlineAllowed != "boolean")
6
+ throw new Error("invalid-font");
7
+ return {
8
+ usage: o[Math.max(o.indexOf(n.usage), o.indexOf(e.usage))],
9
+ subsetAllowed: n.subsetAllowed && e.subsetAllowed,
10
+ outlineAllowed: n.outlineAllowed && e.outlineAllowed
11
+ };
12
+ }
13
+ function _(n, e) {
14
+ const o = n & 15;
15
+ if (e > 5 || o & 1 || e >= 3 && ![0, 2, 4, 8].includes(o) || e >= 2 && n & 64752) throw new Error("invalid-font");
16
+ return {
17
+ usage: o & 8 ? "editable" : o & 4 ? "view-print" : o & 2 ? "restricted" : "installable",
18
+ subsetAllowed: e < 2 || !(n & 256),
19
+ outlineAllowed: e < 2 || !(n & 512)
20
+ };
21
+ }
22
+ function N(n, e) {
23
+ if (!n.outlineAllowed) return "bitmap-only";
24
+ if (n.usage === "restricted") return "embedding-restricted";
25
+ if (n.usage === "view-print" && e !== "view-print") return "preview-print-only";
26
+ }
27
+ function K(n) {
28
+ var C;
29
+ const e = new DataView(n.buffer, n.byteOffset, n.byteLength), o = F;
30
+ n.length < 4 && o();
31
+ const c = e.getUint32(0);
32
+ if ([2001684038, 2001684018].includes(c)) throw new v("needs-container-decoder");
33
+ if (c === 1953784678) throw new v("collection-not-supported");
34
+ (n.length < 12 || ![65536, 1953658213, 1330926671].includes(c)) && o();
35
+ const a = e.getUint16(4), g = 12 + a * 16;
36
+ (!a || a > 256 || g > n.length) && o();
37
+ const w = /* @__PURE__ */ new Map();
38
+ for (let f = 0; f < a; f++) {
39
+ const p = 12 + f * 16, x = String.fromCharCode(...n.subarray(p, p + 4)), S = e.getUint32(p + 8), B = e.getUint32(p + 12);
40
+ (w.has(x) || S < g || S % 4 || S + B > n.length) && o(), w.set(x, { offset: S, length: B });
41
+ }
42
+ const k = [...w.values()].filter((f) => f.length).sort((f, p) => f.offset - p.offset);
43
+ k.some((f, p) => p > 0 && k[p - 1].offset + k[p - 1].length > f.offset) && o();
44
+ const b = (f, p) => {
45
+ const x = w.get(f);
46
+ return !x || x.length < p ? o() : x.offset;
47
+ };
48
+ if (w.has("fvar")) throw new v("variable-not-supported");
49
+ if (w.has("CFF ") || w.has("CFF2")) throw new v("cff-not-supported");
50
+ if (["COLR", "CPAL", "CBDT", "CBLC", "sbix", "SVG "].some((f) => w.has(f))) throw new v("color-font-not-supported");
51
+ c === 1330926671 && o(), b("glyf", 0), b("loca", 4), b("cmap", 4), b("hmtx", 4);
52
+ const U = b("head", 54), i = b("OS/2", 78), u = b("maxp", 32), r = e.getUint16(i);
53
+ b("OS/2", r === 0 ? 78 : r === 1 ? 86 : r < 5 ? 96 : 100), b("hhea", 36);
54
+ const t = e.getUint16(U + 18), s = e.getUint16(u + 4), l = e.getUint16(i + 4), d = e.getUint16(i + 8);
55
+ (e.getUint32(U + 12) !== 1594834165 || t < 16 || t > 16384 || !s || l < 1 || l > 1e3 || e.getUint32(u) !== 65536) && o();
56
+ const y = b("name", 6), A = w.get("name").length, O = e.getUint16(y + 2), m = e.getUint16(y + 4);
57
+ (6 + O * 12 > A || m < 6 + O * 12 || m > A) && o(), O > 1024 && M();
58
+ const h = [];
59
+ let L = 65536;
60
+ for (let f = 0; f < O; f++) {
61
+ const p = y + 6 + f * 12, x = e.getUint16(p), S = e.getUint16(p + 4), B = e.getUint16(p + 6), I = e.getUint16(p + 8), z = m + e.getUint16(p + 10);
62
+ if (z + I > A && o(), B !== 16 && B !== 1 || ![0, 3].includes(x) || I % 2 || I > 512) continue;
63
+ L -= I, L < 0 && M();
64
+ const P = new TextDecoder("utf-16be", { fatal: !0 }).decode(n.subarray(y + z, y + z + I)).trim();
65
+ P && P.length <= 256 && !/[\u0000-\u001f\u007f]/.test(P) && h.push({ value: P, rank: (B === 16 ? 10 : 0) + (S === 1033 ? 2 : 0) });
66
+ }
67
+ const E = (C = h.sort((f, p) => p.rank - f.rank)[0]) == null ? void 0 : C.value;
68
+ return E || o(), { tables: w, info: {
69
+ sourceFamily: E,
70
+ weight: l,
71
+ italic: !!(e.getUint16(i + 62) & 1),
72
+ format: "ttf-glyf",
73
+ unitsPerEm: t,
74
+ glyphCount: s,
75
+ bbox: [36, 38, 40, 42].map((f) => e.getInt16(U + f)),
76
+ fsType: d,
77
+ os2Version: e.getUint16(i),
78
+ embedding: _(d, e.getUint16(i)),
79
+ byteLength: n.length
80
+ } };
81
+ }
82
+ async function W(n, e, o, c) {
83
+ const a = o.length - 1, g = Array.from({ length: a }, () => []);
84
+ for (let i = 0; i < a; i++) {
85
+ const u = c();
86
+ u && await u;
87
+ const r = e + o[i], t = e + o[i + 1];
88
+ if (r === t) continue;
89
+ let s = r + 10;
90
+ const l = (O) => {
91
+ s + O > t && F();
92
+ }, d = () => {
93
+ l(2);
94
+ const O = n.getUint16(s);
95
+ return s += 2, O;
96
+ }, y = () => (l(1), n.getUint8(s++)), A = n.getInt16(r);
97
+ if ((n.getInt16(r + 2) > n.getInt16(r + 6) || n.getInt16(r + 4) > n.getInt16(r + 8)) && F(), A >= 0) {
98
+ let O = -1;
99
+ for (let E = 0; E < A; E++) {
100
+ const C = d();
101
+ C <= O && F(), O = C;
102
+ }
103
+ if (!A && s === t) continue;
104
+ const m = d();
105
+ l(m), s += m;
106
+ const h = O + 1;
107
+ let L = 0;
108
+ for (let E = 0; E < h; ) {
109
+ const C = y(), f = C & 8 ? y() + 1 : 1;
110
+ (C & 128 || E + f > h) && F(), L += f * ((C & 2 ? 1 : C & 16 ? 0 : 2) + (C & 4 ? 1 : C & 32 ? 0 : 2)), E += f;
111
+ }
112
+ l(L);
113
+ } else {
114
+ let O = !0, m = !1;
115
+ for (; O; ) {
116
+ const h = d(), L = d();
117
+ (L >= a || h & 57360 || (h & 6144) === 6144 || !g[i].length && !(h & 2)) && F(), [8, 64, 128].filter((f) => h & f).length > 1 && F();
118
+ const C = (h & 1 ? 4 : 2) + (h & 8 ? 2 : h & 64 ? 4 : h & 128 ? 8 : 0);
119
+ l(C), s += C, g[i].push(L), g[i].length > 4096 && M(), m || (m = !!(h & 256)), O = !!(h & 32);
120
+ }
121
+ if (m) {
122
+ const h = d();
123
+ l(h);
124
+ }
125
+ }
126
+ }
127
+ const w = new Uint8Array(a), k = new Uint8Array(a), b = new Uint32Array(a), U = (i, u) => {
128
+ if (w[i] === 1 && F(), u > 32 && M(), w[i] === 2) return;
129
+ w[i] = 1;
130
+ let r = 0, t = 1;
131
+ for (const s of g[i])
132
+ U(s, u + 1), r = Math.max(r, k[s] + 1), t += b[s], (r > 32 || t > 16384) && M();
133
+ k[i] = r, b[i] = t, w[i] = 2;
134
+ };
135
+ for (let i = 0; i < a; i++) {
136
+ const u = c();
137
+ u && await u, U(i, 0);
138
+ }
139
+ }
140
+ async function X(n, e, o) {
141
+ const c = new DataView(n.buffer, n.byteOffset, n.byteLength), { tables: a, info: g } = e, w = a.get("head"), k = a.get("loca"), b = a.get("glyf"), U = a.get("hhea"), i = a.get("hmtx"), u = c.getInt16(w.offset + 50), r = u === 0 ? 2 : 4, t = c.getUint16(U.offset + 34);
142
+ if (![0, 1].includes(u) || k.length < (g.glyphCount + 1) * r || !t || t > g.glyphCount || i.length < t * 4 + (g.glyphCount - t) * 2)
143
+ throw new Error("invalid-font");
144
+ let s = 0;
145
+ const l = new Uint32Array(g.glyphCount + 1);
146
+ for (let d = 0; d <= g.glyphCount; d++) {
147
+ const y = r === 2 ? c.getUint16(k.offset + d * 2) * 2 : c.getUint32(k.offset + d * 4);
148
+ if (y < s || y > b.length || d > 0 && y !== s && y - s < 10)
149
+ throw new Error("invalid-font");
150
+ s = l[d] = y;
151
+ }
152
+ await W(c, b.offset, l, o);
153
+ }
154
+ async function Y(n, e, o) {
155
+ const c = e.tables.get("cmap"), a = new DataView(n.buffer, n.byteOffset + c.offset, c.length), g = a.getUint16(2), w = 4 + g * 8;
156
+ (a.getUint16(0) || !g || w > a.byteLength) && F(), g > 256 && M();
157
+ let k = !1, b = 2e6;
158
+ const U = /* @__PURE__ */ new Set(), i = (r) => {
159
+ r >= e.info.glyphCount && F();
160
+ }, u = (r) => {
161
+ b -= r, b < 0 && M();
162
+ };
163
+ for (let r = 0; r < g; r++) {
164
+ const t = o();
165
+ t && await t;
166
+ const s = 4 + r * 8, l = a.getUint16(s), d = a.getUint16(s + 2), y = a.getUint32(s + 4);
167
+ (y < w || y + 6 > a.byteLength) && F();
168
+ const A = a.getUint16(y);
169
+ if ((l === 0 && d !== 5 || l === 3 && [1, 10].includes(d)) && [4, 6, 10, 12, 13].includes(A) && (k = !0), ![0, 4, 6, 10, 12, 13, 14].includes(A)) throw new v("cmap-not-supported");
170
+ A >= 10 && A !== 14 && y + 12 > a.byteLength && F();
171
+ const O = A === 14 ? a.getUint32(y + 2) : A >= 10 ? a.getUint32(y + 4) : a.getUint16(y + 2);
172
+ (O < 6 || y + O > a.byteLength) && F();
173
+ const m = new DataView(n.buffer, n.byteOffset + c.offset + y, O), h = (L, E) => {
174
+ (L < 0 || L + E > O) && F();
175
+ };
176
+ if (l !== 1 && A !== 14 && (A >= 10 ? m.getUint32(8) : m.getUint16(4)) && F(), !U.has(y))
177
+ if (U.add(y), A === 0) {
178
+ h(6, 256), u(256);
179
+ for (let L = 0; L < 256; L++) i(m.getUint8(6 + L));
180
+ } else if (A === 4) {
181
+ h(0, 16);
182
+ const L = m.getUint16(6), E = L / 2, C = 16 + E * 8;
183
+ (!L || L % 2) && F(), h(0, C), m.getUint16(14 + E * 2) && F();
184
+ let f = -1;
185
+ for (let p = 0; p < E; p++) {
186
+ const x = o();
187
+ x && await x;
188
+ const S = m.getUint16(14 + p * 2), B = m.getUint16(16 + E * 2 + p * 2), I = m.getInt16(16 + E * 4 + p * 2), z = 16 + E * 6 + p * 2, P = m.getUint16(z);
189
+ (B > S || B <= f || P % 2 || p === E - 1 && (B !== 65535 || S !== 65535)) && F(), f = S, u(S - B + 1), P && z + P < C && F(), P && h(z + P, (S - B + 1) * 2);
190
+ for (let D = B; D <= S; D++) {
191
+ const V = P ? m.getUint16(z + P + (D - B) * 2) : D;
192
+ i(P && !V ? 0 : V + I & 65535);
193
+ }
194
+ }
195
+ } else if (A === 6 || A === 10) {
196
+ const L = A === 10, E = L ? 20 : 10;
197
+ h(0, E);
198
+ const C = L ? m.getUint32(12) : m.getUint16(6), f = L ? m.getUint32(16) : m.getUint16(8);
199
+ (C + f > (L ? 1114112 : 65536) || L && m.getUint16(2)) && F(), h(E, f * 2), u(f);
200
+ for (let p = 0; p < f; p++) {
201
+ if (p % 256 === 0) {
202
+ const x = o();
203
+ x && await x;
204
+ }
205
+ i(m.getUint16(E + p * 2));
206
+ }
207
+ } else if (A === 12 || A === 13) {
208
+ h(0, 16);
209
+ const L = m.getUint32(12);
210
+ m.getUint16(2) && F(), h(16, L * 12), u(L);
211
+ let E = -1;
212
+ for (let C = 0; C < L; C++) {
213
+ if (C % 256 === 0) {
214
+ const B = o();
215
+ B && await B;
216
+ }
217
+ const f = 16 + C * 12, p = m.getUint32(f), x = m.getUint32(f + 4), S = m.getUint32(f + 8);
218
+ (p > x || p <= E || x > 1114111) && F(), i(S), i(S + (A === 12 ? x - p : 0)), E = x;
219
+ }
220
+ } else {
221
+ h(0, 10);
222
+ const L = m.getUint32(6), E = 10 + L * 11;
223
+ h(0, E), u(L);
224
+ const C = (p) => m.getUint16(p) * 256 + m.getUint8(p + 2);
225
+ let f = -1;
226
+ for (let p = 0; p < L; p++) {
227
+ const x = o();
228
+ x && await x;
229
+ const S = 10 + p * 11, B = C(S);
230
+ (B <= f || !(B >= 65024 && B <= 65039 || B >= 917760 && B <= 917999)) && F(), f = B;
231
+ for (const I of [0, 1]) {
232
+ const z = m.getUint32(S + 3 + I * 4);
233
+ if (!z) continue;
234
+ z < E && F(), h(z, 4);
235
+ const P = m.getUint32(z), D = I ? 5 : 4;
236
+ h(z + 4, P * D), u(P);
237
+ let V = -1;
238
+ for (let T = 0; T < P; T++) {
239
+ if (T % 256 === 0) {
240
+ const $ = o();
241
+ $ && await $;
242
+ }
243
+ const j = z + 4 + T * D, G = C(j), H = G + (I ? 0 : m.getUint8(j + 3));
244
+ (G <= V || H > 1114111 || G <= 57343 && H >= 55296) && F(), I && i(m.getUint16(j + 3)), V = H;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ if (!k) throw new v("cmap-not-supported");
251
+ }
252
+ function J(n, e) {
253
+ const o = n.codePointAt(0), c = { start: e, end: e + n.length };
254
+ if (o >= 55296 && o <= 57343 || /[\u0000-\u001f\u007f-\u009f]/u.test(n)) throw new v("invalid-text", void 0, c);
255
+ if (/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/u.test(n)) throw new v("unsupported-direction", void 0, c);
256
+ if (new RegExp("\\p{Script=Latin}", "u").test(n)) return "Latn";
257
+ if (new RegExp("\\p{Script=Han}", "u").test(n)) return "Hani";
258
+ if (!/[\p{Script=Common}\p{Script=Inherited}]/u.test(n)) throw new v("unsupported-script", void 0, c);
259
+ }
260
+ function at(n, e) {
261
+ var c;
262
+ if (e.direction !== "ltr") return { ok: !1, reason: "unsupported-direction" };
263
+ if (n.length > 1e5) return { ok: !1, reason: "resource-limit" };
264
+ const o = [];
265
+ try {
266
+ let a = 0;
267
+ for (const U of n)
268
+ o.push({ start: a, script: J(U, a) }), a += U.length;
269
+ const g = [];
270
+ let w = 0, k = ((c = o.find((U) => U.script)) == null ? void 0 : c.script) ?? "Latn";
271
+ const b = (U) => {
272
+ U > w && g.push({ start: w, end: U, text: n.slice(w, U), script: k, ...e });
273
+ };
274
+ for (const U of o)
275
+ !U.script || U.script === k || (b(U.start), w = U.start, k = U.script);
276
+ return b(n.length), { ok: !0, value: g };
277
+ } catch (a) {
278
+ return a instanceof v ? { ok: !1, reason: a.reason, range: a.range } : { ok: !1, reason: "invalid-text" };
279
+ }
280
+ }
281
+ function q(n, e, o) {
282
+ if (e.direction !== "ltr") throw new v("unsupported-direction");
283
+ if (!["Latn", "Hani"].includes(e.script)) throw new v("unsupported-script");
284
+ if (n.length > o) throw new v("resource-limit");
285
+ if (typeof e.language != "string" || !/^[a-zA-Z]{2,8}(?:-[a-zA-Z0-9]{1,8})*$/.test(e.language))
286
+ throw new v("invalid-text");
287
+ let c = 0;
288
+ for (const a of n) {
289
+ const g = J(a, c);
290
+ if (g && g !== e.script) throw new v("script-mismatch", void 0, { start: c, end: c + a.length });
291
+ c += a.length;
292
+ }
293
+ }
294
+ function tt(n, e, o, c) {
295
+ const a = () => {
296
+ throw new v("shaper-failed");
297
+ };
298
+ if (c.length > Math.max(256, e.length * 32)) throw new v("resource-limit");
299
+ (e.length && !c.length || !e.length && c.length) && a();
300
+ const g = [];
301
+ let w = -1, k = 0, b = 0;
302
+ const U = c.map((r, t) => {
303
+ const { id: s, cluster: l, xOffset: d, yOffset: y } = r;
304
+ if ((!Number.isInteger(s) || s < 0 || s >= n.glyphCount || !Number.isInteger(l) || l < w || l >= e.length || t === 0 && l !== 0 || l > 0 && /[\udc00-\udfff]/u.test(e[l]) || ![r.xAdvance, r.yAdvance, d, y].every((A) => Number.isFinite(A) && Math.abs(A) <= 1e9)) && a(), l !== w) {
305
+ const A = g[g.length - 1];
306
+ A && (A.end = l, A.text = e.slice(A.start, l), A.glyphEnd = t), g.push({ start: l, end: e.length, text: "", glyphStart: t, glyphEnd: c.length }), w = l;
307
+ }
308
+ return k += r.xAdvance, b += r.yAdvance, { id: s, xAdvance: r.xAdvance, yAdvance: r.yAdvance, xOffset: d, yOffset: y };
309
+ }), i = g[g.length - 1];
310
+ i && (i.text = e.slice(i.start));
311
+ const u = g.filter((r) => U.slice(r.glyphStart, r.glyphEnd).some((t) => t.id === 0)).map(({ start: r, end: t, text: s }) => ({ start: r, end: t, text: s }));
312
+ return u.length ? { ok: !1, reason: "missing-glyphs", faceId: n.id, missing: u } : { ok: !0, value: {
313
+ faceId: n.id,
314
+ text: e,
315
+ script: o.script,
316
+ direction: "ltr",
317
+ language: o.language,
318
+ unitsPerEm: n.unitsPerEm,
319
+ xAdvance: k,
320
+ yAdvance: b,
321
+ glyphs: U,
322
+ clusters: g
323
+ } };
324
+ }
325
+ function R(n, e) {
326
+ return new Promise((o, c) => {
327
+ const a = () => {
328
+ e.removeEventListener("abort", a), c(new v("aborted"));
329
+ };
330
+ e.aborted ? a() : e.addEventListener("abort", a, { once: !0 }), n.then(o, c).finally(() => e.removeEventListener("abort", a));
331
+ });
332
+ }
333
+ function et(n, e) {
334
+ const o = new AbortController(), c = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), g = /* @__PURE__ */ new Map();
335
+ let w, k;
336
+ const b = () => n.loadShaper ? w ?? (w = Promise.resolve().then(() => {
337
+ if (o.signal.aborted) throw new v("provider-disposed");
338
+ return n.loadShaper(o.signal);
339
+ }).then((i) => {
340
+ if (o.signal.aborted)
341
+ throw i.dispose(), new v("provider-disposed");
342
+ return k = i, i;
343
+ }).catch((i) => {
344
+ throw w = void 0, i;
345
+ })) : Promise.reject(new v("shaper-unavailable")), U = async (i, u, r, t) => {
346
+ var d, y, A, O, m;
347
+ if (o.signal.aborted) return { ok: !1, reason: "provider-disposed", faceId: i };
348
+ const s = new AbortController(), l = () => s.abort();
349
+ g.has(i) || g.set(i, /* @__PURE__ */ new Set()), g.get(i).add(s), o.signal.addEventListener("abort", l, { once: !0 }), (d = u.signal) == null || d.addEventListener("abort", l, { once: !0 }), (y = u.signal) != null && y.aborted && l();
350
+ try {
351
+ if (s.signal.aborted) throw new v("aborted");
352
+ const h = await e(i, u);
353
+ if (!h.ok) return h;
354
+ if (a.has(i)) throw new v("face-unavailable");
355
+ if (s.signal.aborted) throw new v("aborted");
356
+ r(h.value);
357
+ let L = c.get(i);
358
+ if (!L) {
359
+ const C = new AbortController();
360
+ let f;
361
+ f = { pending: R(b(), C.signal).then((x) => {
362
+ if (a.has(i)) throw new v("face-unavailable");
363
+ return x.open({ ...h.value, bytes: h.value.bytes.slice() }, C.signal);
364
+ }).then((x) => {
365
+ if (o.signal.aborted || a.has(i))
366
+ throw x.dispose(), new v(o.signal.aborted ? "provider-disposed" : "face-unavailable");
367
+ return f.face = x, x;
368
+ }).catch((x) => {
369
+ throw c.delete(i), x;
370
+ }), controller: C }, c.set(i, f), L = f;
371
+ }
372
+ const E = await R(L.pending, s.signal);
373
+ return await R(Promise.resolve().then(() => {
374
+ if (s.signal.aborted) throw new v("aborted");
375
+ return t(E, h.value, s.signal);
376
+ }), s.signal);
377
+ } catch (h) {
378
+ return {
379
+ ok: !1,
380
+ faceId: i,
381
+ reason: o.signal.aborted ? "provider-disposed" : a.has(i) ? "face-unavailable" : s.signal.aborted ? "aborted" : h instanceof v ? h.reason : "shaper-failed",
382
+ ...h instanceof v && h.missing ? { missing: h.missing } : {},
383
+ ...h instanceof v && h.range ? { range: h.range } : {}
384
+ };
385
+ } finally {
386
+ o.signal.removeEventListener("abort", l), (A = u.signal) == null || A.removeEventListener("abort", l), (O = g.get(i)) == null || O.delete(s), (m = g.get(i)) != null && m.size || g.delete(i);
387
+ }
388
+ };
389
+ return {
390
+ release(i) {
391
+ var r;
392
+ a.add(i);
393
+ const u = c.get(i);
394
+ c.delete(i), (r = u == null ? void 0 : u.face) == null || r.dispose(), u == null || u.controller.abort();
395
+ for (const t of g.get(i) ?? []) t.abort();
396
+ },
397
+ shape(i, u, r) {
398
+ return U(i, r, () => {
399
+ var t;
400
+ return q(u, r, ((t = n.limits) == null ? void 0 : t.maxTextLength) ?? 1e5);
401
+ }, async (t, s, l) => {
402
+ const d = u ? await t.shape(u, { ...r, signal: l }) : [];
403
+ return tt(s.info, u, r, d);
404
+ });
405
+ },
406
+ outline(i, u, r) {
407
+ return U(i, r, (t) => {
408
+ if (!Number.isInteger(u) || u < 0 || u >= t.info.glyphCount) throw new v("invalid-glyph-id");
409
+ }, async (t, s, l) => {
410
+ const d = await t.outline(u, { ...r, signal: l });
411
+ if (d.length > 4e6) throw new v("resource-limit");
412
+ if (!/^[MmLlHhVvCcSsQqTtAaZz\d\s.,+eE-]*$/.test(d)) throw new v("shaper-failed");
413
+ return { ok: !0, value: d };
414
+ });
415
+ },
416
+ dispose() {
417
+ if (!o.signal.aborted) {
418
+ k == null || k.dispose(), k = void 0, o.abort();
419
+ for (const i of c.values())
420
+ i.controller.abort(), i.pending.then((u) => u.dispose(), () => {
421
+ });
422
+ c.clear();
423
+ }
424
+ }
425
+ };
426
+ }
427
+ function nt(n = {}) {
428
+ const e = {
429
+ maxFontBytes: 33554432,
430
+ maxTotalFontBytes: 67108864,
431
+ maxFaces: 64,
432
+ maxGlyphs: 65535,
433
+ maxTextLength: 1e5,
434
+ ...n
435
+ };
436
+ if (!Object.values(e).every((o) => Number.isSafeInteger(o) && o > 0)) throw new RangeError("Invalid font resource budget");
437
+ return e;
438
+ }
439
+ function it(n) {
440
+ let e = 0;
441
+ return () => {
442
+ if (n(), !(Date.now() < e))
443
+ return new Promise((o) => setTimeout(o, 0)).then(() => {
444
+ n(), e = Date.now() + 8;
445
+ });
446
+ };
447
+ }
448
+ function Z(n) {
449
+ if (n.length < 36 || n[34] !== 76 || n[35] !== 80) return !1;
450
+ const e = new DataView(n.buffer, n.byteOffset, n.byteLength).getUint32(0);
451
+ return ![65536, 1953658213, 1330926671, 1953784678, 2001684038, 2001684018].includes(e);
452
+ }
453
+ function ot(n) {
454
+ const e = new DataView(n.buffer, n.byteOffset, n.byteLength);
455
+ (n.length < 96 || !Z(n) || e.getUint32(0, !0) !== n.length) && F();
456
+ const o = e.getUint32(8, !0), c = e.getUint32(12, !0), a = e.getUint32(4, !0);
457
+ if (![65536, 131073, 131074].includes(o) || c & -268435702) throw new v("eot-feature-not-supported");
458
+ (!a || a > n.length - 96) && F();
459
+ const g = n.length - a;
460
+ let w = 80;
461
+ const k = (r) => {
462
+ w + r > g && F();
463
+ }, b = () => {
464
+ k(2);
465
+ const r = e.getUint16(w, !0);
466
+ return w += 2, r;
467
+ }, U = () => {
468
+ k(4);
469
+ const r = e.getUint32(w, !0);
470
+ return w += 4, r;
471
+ }, i = () => {
472
+ b() && F();
473
+ const r = b();
474
+ r % 2 && F(), k(r);
475
+ const t = new TextDecoder("utf-16le", { fatal: !0 }).decode(n.subarray(w, w + r));
476
+ return w += r, t;
477
+ };
478
+ for (let r = 64; r < 80; r += 4) e.getUint32(r, !0) && F();
479
+ for (let r = 0; r < 4; r++) i();
480
+ if (o !== 65536) {
481
+ if (i().replace(/\0/g, "")) throw new v("eot-root-restricted");
482
+ if (o === 131074) {
483
+ const t = U();
484
+ U(), t !== 1346851650 && F(), b() && F();
485
+ const s = b();
486
+ k(s), w += s;
487
+ const l = U(), d = U();
488
+ if (k(d), w += d, s || l || d) throw new v("eot-feature-not-supported");
489
+ }
490
+ }
491
+ if (w !== g && F(), c & 32) throw new v("eot-feature-not-supported");
492
+ const u = _(e.getUint16(32, !0), 2);
493
+ if (c & 1 && !u.subsetAllowed) throw new v("subset-not-permitted");
494
+ return { offset: g, size: a, flags: c, rights: u };
495
+ }
496
+ function rt(n, e) {
497
+ const o = n.slice(e.offset);
498
+ if (e.flags & 268435456) for (let c = 0; c < o.length; c++) o[c] ^= 80;
499
+ return o;
500
+ }
501
+ function lt(n = {}) {
502
+ let e = !1, o = 0;
503
+ const c = new AbortController(), a = n.decodeEot, g = nt(n.limits), w = /* @__PURE__ */ new Set(), k = /* @__PURE__ */ new Set(), b = /* @__PURE__ */ new Map(), U = (t) => ({ ...t, bbox: [...t.bbox], embedding: { ...t.embedding } }), i = (t, s) => {
504
+ var l;
505
+ return e ? { ok: !1, reason: "provider-disposed", faceId: s } : (l = t.signal) != null && l.aborted ? { ok: !1, reason: "aborted", faceId: s } : void 0;
506
+ }, u = async (t, s) => {
507
+ const l = i(s, t);
508
+ if (l) return l;
509
+ const d = b.get(t), y = d && N(d.info.embedding, s.purpose);
510
+ return y ? { ok: !1, reason: y, faceId: t } : d ? { ok: !0, value: { bytes: d.bytes, info: U(d.info) } } : { ok: !1, reason: "face-unavailable", faceId: t };
511
+ }, r = et({ ...n, limits: g }, u);
512
+ return {
513
+ async register(t, s) {
514
+ var L, E, C;
515
+ t = { ...t, restrictions: t.restrictions && { ...t.restrictions } }, s = { ...s };
516
+ const l = i(s, t.id);
517
+ if (l) return l;
518
+ const d = (f) => ({ ok: !1, reason: f, faceId: t.id });
519
+ if (!((L = t.bytes) != null && L.length)) return d("font-bytes-unavailable");
520
+ if (!t.id || t.id.length > 256) return d("invalid-font");
521
+ if (!["explicit", "embedded", "substitute"].includes(t.origin) || !["edit", "view-print"].includes(s.purpose) || t.family !== void 0 && (!t.family.trim() || t.family.length > 256 || /[\u0000-\u001f\u007f]/.test(t.family))) return d("invalid-request");
522
+ if (b.has(t.id) || w.has(t.id) || k.has(t.id)) return d("duplicate-face-id");
523
+ const y = t.bytes.length, A = y + (Z(t.bytes) ? g.maxFontBytes : 0), O = [...b.values()].reduce((f, p) => f + p.bytes.length, 0);
524
+ if (y > g.maxFontBytes || O + o + A > g.maxTotalFontBytes || b.size + w.size >= g.maxFaces) return d("resource-limit");
525
+ w.add(t.id), o += A;
526
+ const m = new AbortController(), h = () => m.abort();
527
+ c.signal.addEventListener("abort", h, { once: !0 }), (E = s.signal) == null || E.addEventListener("abort", h, { once: !0 });
528
+ try {
529
+ let f = new Uint8Array(t.bytes);
530
+ const p = it(() => {
531
+ const P = i(s);
532
+ if (P) throw new v(P.reason);
533
+ });
534
+ await p();
535
+ const x = Z(f) ? ot(f) : void 0;
536
+ if (x) {
537
+ const P = N(x.rights, s.purpose);
538
+ if (P) return d(P);
539
+ if (x.flags & 4) {
540
+ if (!a) return d("decoder-unavailable");
541
+ let D;
542
+ try {
543
+ D = await R(Promise.resolve().then(() => {
544
+ if (m.signal.aborted) throw new v("aborted");
545
+ return a(f, { signal: m.signal, maxOutputBytes: g.maxFontBytes });
546
+ }), m.signal);
547
+ } catch (V) {
548
+ return d(e ? "provider-disposed" : m.signal.aborted ? "aborted" : V instanceof v ? V.reason : "decode-failed");
549
+ }
550
+ if (!(D != null && D.length)) return d("decode-failed");
551
+ if (D.length > g.maxFontBytes) return d("resource-limit");
552
+ f = new Uint8Array(D);
553
+ } else f = rt(f, x);
554
+ }
555
+ const S = K(f);
556
+ if (S.info.embedding = Q(Q(S.info.embedding, x == null ? void 0 : x.rights), t.restrictions), x && x.flags & 1 && !S.info.embedding.subsetAllowed) return d("subset-not-permitted");
557
+ if (S.info.glyphCount > g.maxGlyphs) return d("resource-limit");
558
+ const B = N(S.info.embedding, s.purpose);
559
+ if (B) return d(B);
560
+ await X(f, S, p), await Y(f, S, p);
561
+ const I = i(s, t.id);
562
+ if (I) return I;
563
+ const z = {
564
+ ...S.info,
565
+ id: t.id,
566
+ family: t.family ?? S.info.sourceFamily,
567
+ origin: t.origin,
568
+ sourceLabel: t.sourceLabel,
569
+ embeddingEvidence: t.embeddingEvidence
570
+ };
571
+ return b.set(t.id, { info: z, bytes: f }), { ok: !0, value: U(z) };
572
+ } catch (f) {
573
+ return d(f instanceof v ? f.reason : "invalid-font");
574
+ } finally {
575
+ w.delete(t.id), o -= A, c.signal.removeEventListener("abort", h), (C = s.signal) == null || C.removeEventListener("abort", h);
576
+ }
577
+ },
578
+ async resolve(t) {
579
+ const s = i(t);
580
+ if (s) return s;
581
+ const l = [...b.values()].filter(({ info: y }) => y.family.toLowerCase() === t.family.toLowerCase() && y.weight === t.weight && y.italic === t.italic), d = l.length === 1 ? N(l[0].info.embedding, t.purpose) : void 0;
582
+ return d ? { ok: !1, reason: d, faceId: l[0].info.id } : l.length === 1 ? { ok: !0, value: U(l[0].info) } : { ok: !1, reason: l.length ? "ambiguous-face" : "face-unavailable" };
583
+ },
584
+ async embedding(t, s) {
585
+ const l = await u(t, s);
586
+ return l.ok ? { ok: !0, value: { info: l.value.info, bytes: l.value.bytes.slice() } } : l;
587
+ },
588
+ async faceInfo(t, s) {
589
+ const l = await u(t, s);
590
+ return l.ok ? { ok: !0, value: l.value.info } : l;
591
+ },
592
+ shape: r.shape,
593
+ outline: r.outline,
594
+ /** 释放已注册 face;同一文稿内身份不可复用,避免迟到请求混用新旧字节。 */
595
+ release(t) {
596
+ return b.delete(t) ? (k.add(t), r.release(t), !0) : !1;
597
+ },
598
+ state() {
599
+ return {
600
+ disposed: e,
601
+ retainedFontBytes: [...b.values()].reduce((t, s) => t + s.bytes.length, 0),
602
+ reservedFontBytes: o,
603
+ pendingRegistrations: w.size,
604
+ faces: b.size
605
+ };
606
+ },
607
+ dispose() {
608
+ e = !0, r.dispose(), c.abort(), b.clear(), k.clear();
609
+ }
610
+ };
611
+ }
612
+ export {
613
+ lt as c,
614
+ nt as f,
615
+ tt as m,
616
+ at as s
617
+ };
@@ -17,6 +17,13 @@
17
17
  export interface Substitution {
18
18
  /** 替代字体的家族名 */
19
19
  family: string;
20
+ /** 中日韩字体的西文替代家族;其字形声明须在 CJK 声明之后注册。 */
21
+ latinFamily?: string;
22
+ /** 西文替代家族的实测 size-adjust(百分比):粗体整体与下划线单独缩放,用来对上原字体的前进宽度。 */
23
+ latinSizeAdjust?: {
24
+ readonly bold: number;
25
+ readonly underscore: number;
26
+ };
20
27
  /**
21
28
  * 前进宽度与原字体逐字相等。为真时断行与 PowerPoint 完全一致,
22
29
  * 为假时只是形近,行高仍可能要靠 `size-adjust` 修。