@unmade/text-renderer 1.0.0 → 1.1.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.js +565 -515
- package/dist/node/index.js +432 -382
- package/dist/worker/index.js +1351 -1301
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -3,206 +3,256 @@ import { svgPathProperties as Pt } from "svg-path-properties";
|
|
|
3
3
|
import { DOMParser as Tt } from "linkedom";
|
|
4
4
|
import "node:path";
|
|
5
5
|
import Lt from "@thednp/dommatrix";
|
|
6
|
-
function
|
|
7
|
-
let t = 1 / 0, n = 1 / 0, o = -1 / 0,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
function Ct(e) {
|
|
7
|
+
let t = 1 / 0, n = 1 / 0, o = -1 / 0, l = -1 / 0, r = 0, a = 0;
|
|
8
|
+
function s(f, d) {
|
|
9
|
+
f < t && (t = f), f > o && (o = f), d < n && (n = d), d > l && (l = d);
|
|
10
|
+
}
|
|
11
|
+
function c(f, d, g) {
|
|
12
|
+
const w = f - 2 * d + g;
|
|
13
|
+
if (Math.abs(w) < 1e-10) return [];
|
|
14
|
+
const m = (f - d) / w;
|
|
15
|
+
return m > 0 && m < 1 ? [m] : [];
|
|
16
|
+
}
|
|
17
|
+
function h(f, d, g, w) {
|
|
18
|
+
const m = 1 - f;
|
|
19
|
+
return m * m * d + 2 * m * f * g + f * f * w;
|
|
20
|
+
}
|
|
21
|
+
function i(f, d, g, w) {
|
|
22
|
+
const m = d - f, y = g - d, $ = w - g, v = m - 2 * y + $, M = 2 * (y - m), S = m;
|
|
23
|
+
if (Math.abs(v) < 1e-10) {
|
|
24
|
+
if (Math.abs(M) < 1e-10) return [];
|
|
25
|
+
const x = -S / M;
|
|
26
|
+
return x > 0 && x < 1 ? [x] : [];
|
|
27
|
+
}
|
|
28
|
+
const A = M * M - 4 * v * S;
|
|
29
|
+
if (A < 0) return [];
|
|
30
|
+
const k = Math.sqrt(A);
|
|
31
|
+
return [(-M + k) / (2 * v), (-M - k) / (2 * v)].filter((x) => x > 0 && x < 1);
|
|
32
|
+
}
|
|
33
|
+
function b(f, d, g, w, m) {
|
|
34
|
+
const y = 1 - f;
|
|
35
|
+
return y * y * y * d + 3 * y * y * f * g + 3 * y * f * f * w + f * f * f * m;
|
|
36
|
+
}
|
|
37
|
+
const p = /([MLCQTSAZHVmlcqtsazhv])([^MLCQTSAZHVmlcqtsazhv]*)/g;
|
|
38
|
+
let u = p.exec(e);
|
|
39
|
+
for (; u !== null; ) {
|
|
40
|
+
const f = u[1].toUpperCase();
|
|
41
|
+
if (f === "Z") {
|
|
42
|
+
u = p.exec(e);
|
|
43
|
+
continue;
|
|
23
44
|
}
|
|
24
|
-
|
|
45
|
+
const d = u[2].trim().split(/[\s,]+/).filter(Boolean).map(Number);
|
|
46
|
+
if (f === "M" || f === "L" || f === "T")
|
|
47
|
+
for (let g = 0; g + 1 < d.length; g += 2)
|
|
48
|
+
r = d[g], a = d[g + 1], s(r, a);
|
|
49
|
+
else if (f === "H")
|
|
50
|
+
for (const g of d)
|
|
51
|
+
r = g, s(r, a);
|
|
52
|
+
else if (f === "V")
|
|
53
|
+
for (const g of d)
|
|
54
|
+
a = g, s(r, a);
|
|
55
|
+
else if (f === "Q")
|
|
56
|
+
for (let g = 0; g + 3 < d.length; g += 4) {
|
|
57
|
+
const [w, m, y, $] = d.slice(g, g + 4);
|
|
58
|
+
s(y, $);
|
|
59
|
+
for (const v of c(r, w, y)) s(h(v, r, w, y), h(v, a, m, $));
|
|
60
|
+
for (const v of c(a, m, $)) s(h(v, r, w, y), h(v, a, m, $));
|
|
61
|
+
r = y, a = $;
|
|
62
|
+
}
|
|
63
|
+
else if (f === "C")
|
|
64
|
+
for (let g = 0; g + 5 < d.length; g += 6) {
|
|
65
|
+
const [w, m, y, $, v, M] = d.slice(g, g + 6);
|
|
66
|
+
s(v, M);
|
|
67
|
+
for (const S of i(r, w, y, v)) s(b(S, r, w, y, v), b(S, a, m, $, M));
|
|
68
|
+
for (const S of i(a, m, $, M)) s(b(S, r, w, y, v), b(S, a, m, $, M));
|
|
69
|
+
r = v, a = M;
|
|
70
|
+
}
|
|
71
|
+
else
|
|
72
|
+
for (let g = 0; g + 1 < d.length; g += 2)
|
|
73
|
+
s(d[g], d[g + 1]);
|
|
74
|
+
u = p.exec(e);
|
|
25
75
|
}
|
|
26
|
-
return Number.isFinite(t) ? { x1: t, y1: n, x2: o, y2:
|
|
76
|
+
return Number.isFinite(t) ? { x1: t, y1: n, x2: o, y2: l } : null;
|
|
27
77
|
}
|
|
28
78
|
function Et(e, t, n, o) {
|
|
29
79
|
return e.replace(
|
|
30
80
|
/([MLCQTSAZHVmlcqtsazhv])([^MLCQTSAZHVmlcqtsazhv]*)/g,
|
|
31
|
-
(
|
|
32
|
-
const s =
|
|
33
|
-
if (s === "Z") return
|
|
34
|
-
const
|
|
81
|
+
(l, r, a) => {
|
|
82
|
+
const s = r.toUpperCase();
|
|
83
|
+
if (s === "Z") return r;
|
|
84
|
+
const c = a.trim().split(/[\s,]+/).filter(Boolean).map(Number), h = [];
|
|
35
85
|
if (s === "M" || s === "L" || s === "T")
|
|
36
|
-
for (let
|
|
37
|
-
|
|
86
|
+
for (let i = 0; i < c.length; i += 2)
|
|
87
|
+
h.push(c[i] * t + o, -c[i + 1] * n);
|
|
38
88
|
else if (s === "C")
|
|
39
|
-
for (let
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
-
|
|
89
|
+
for (let i = 0; i < c.length; i += 6)
|
|
90
|
+
h.push(
|
|
91
|
+
c[i] * t + o,
|
|
92
|
+
-c[i + 1] * n,
|
|
93
|
+
c[i + 2] * t + o,
|
|
94
|
+
-c[i + 3] * n,
|
|
95
|
+
c[i + 4] * t + o,
|
|
96
|
+
-c[i + 5] * n
|
|
47
97
|
);
|
|
48
98
|
else if (s === "Q" || s === "S")
|
|
49
|
-
for (let
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
-
|
|
99
|
+
for (let i = 0; i < c.length; i += 4)
|
|
100
|
+
h.push(
|
|
101
|
+
c[i] * t + o,
|
|
102
|
+
-c[i + 1] * n,
|
|
103
|
+
c[i + 2] * t + o,
|
|
104
|
+
-c[i + 3] * n
|
|
55
105
|
);
|
|
56
106
|
else if (s === "H")
|
|
57
|
-
for (let
|
|
58
|
-
|
|
107
|
+
for (let i = 0; i < c.length; i++)
|
|
108
|
+
h.push(c[i] * t + o);
|
|
59
109
|
else if (s === "V")
|
|
60
|
-
for (let
|
|
61
|
-
|
|
110
|
+
for (let i = 0; i < c.length; i++)
|
|
111
|
+
h.push(-c[i] * n);
|
|
62
112
|
else
|
|
63
|
-
return
|
|
64
|
-
return
|
|
113
|
+
return r + a;
|
|
114
|
+
return r + h.join(",");
|
|
65
115
|
}
|
|
66
116
|
);
|
|
67
117
|
}
|
|
68
|
-
function
|
|
69
|
-
const
|
|
70
|
-
function
|
|
71
|
-
const
|
|
118
|
+
function Ut(e, t, n, o) {
|
|
119
|
+
const l = e.upem;
|
|
120
|
+
function r(i) {
|
|
121
|
+
const b = i.codePointAt(0) ?? 0, p = t.glyph(b) ?? 0, u = t.glyphExtents(p);
|
|
72
122
|
return {
|
|
73
|
-
index:
|
|
74
|
-
advanceWidth: t.glyphHAdvance(
|
|
75
|
-
name: t.glyphName(
|
|
123
|
+
index: p,
|
|
124
|
+
advanceWidth: t.glyphHAdvance(p),
|
|
125
|
+
name: t.glyphName(p),
|
|
76
126
|
getBoundingBox() {
|
|
77
|
-
return
|
|
78
|
-
x1:
|
|
79
|
-
y1: -
|
|
80
|
-
x2:
|
|
127
|
+
return u ? {
|
|
128
|
+
x1: u.xBearing,
|
|
129
|
+
y1: -u.yBearing,
|
|
130
|
+
x2: u.xBearing + u.width,
|
|
81
131
|
// height is negative in HarfBuzz (extends downward), so subtracting gives y2 >= y1
|
|
82
|
-
y2: -(
|
|
132
|
+
y2: -(u.yBearing + u.height)
|
|
83
133
|
} : { x1: 0, y1: 0, x2: 0, y2: 0 };
|
|
84
134
|
}
|
|
85
135
|
};
|
|
86
136
|
}
|
|
87
|
-
const
|
|
88
|
-
function s(
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
let
|
|
93
|
-
return
|
|
94
|
-
const
|
|
95
|
-
return
|
|
137
|
+
const a = [new nt("liga", 0), new nt("calt", 0)];
|
|
138
|
+
function s(i, b, p, u) {
|
|
139
|
+
const f = u / l, d = new At();
|
|
140
|
+
d.addText(i), d.guessSegmentProperties(), Bt(t, d, a);
|
|
141
|
+
const g = d.getGlyphInfos(), w = d.getGlyphPositions();
|
|
142
|
+
let m = 0;
|
|
143
|
+
return g.map((y, $) => {
|
|
144
|
+
const v = w[$], M = y.codepoint, S = m + v.xOffset, A = t.glyphToPath(M), k = Et(A, f, f, S * f);
|
|
145
|
+
return m += v.xAdvance, {
|
|
96
146
|
getBoundingBox() {
|
|
97
|
-
const
|
|
98
|
-
return
|
|
147
|
+
const x = Ct(k);
|
|
148
|
+
return x || { x1: S * f, y1: 0, x2: S * f, y2: 0 };
|
|
99
149
|
},
|
|
100
|
-
toPathData(
|
|
101
|
-
return
|
|
150
|
+
toPathData(x) {
|
|
151
|
+
return k;
|
|
102
152
|
}
|
|
103
153
|
};
|
|
104
154
|
});
|
|
105
155
|
}
|
|
106
|
-
function
|
|
107
|
-
const
|
|
156
|
+
function c(i, b, p, u) {
|
|
157
|
+
const f = s(i, b, p, u);
|
|
108
158
|
return {
|
|
109
159
|
getBoundingBox() {
|
|
110
|
-
if (
|
|
160
|
+
if (f.length === 0)
|
|
111
161
|
return { x1: 0, y1: 0, x2: 0, y2: 0 };
|
|
112
|
-
const
|
|
162
|
+
const d = f.map((g) => g.getBoundingBox());
|
|
113
163
|
return {
|
|
114
|
-
x1: Math.min(...
|
|
115
|
-
y1: Math.min(...
|
|
116
|
-
x2: Math.max(...
|
|
117
|
-
y2: Math.max(...
|
|
164
|
+
x1: Math.min(...d.map((g) => g.x1)),
|
|
165
|
+
y1: Math.min(...d.map((g) => g.y1)),
|
|
166
|
+
x2: Math.max(...d.map((g) => g.x2)),
|
|
167
|
+
y2: Math.max(...d.map((g) => g.y2))
|
|
118
168
|
};
|
|
119
169
|
},
|
|
120
|
-
toPathData(
|
|
121
|
-
return
|
|
170
|
+
toPathData(d) {
|
|
171
|
+
return f.map((g) => g.toPathData()).join("");
|
|
122
172
|
}
|
|
123
173
|
};
|
|
124
174
|
}
|
|
125
175
|
return {
|
|
126
|
-
unitsPerEm:
|
|
176
|
+
unitsPerEm: l,
|
|
127
177
|
names: { fontFamily: n },
|
|
128
178
|
svgGlyphs: o,
|
|
129
|
-
charToGlyph:
|
|
130
|
-
getPath:
|
|
179
|
+
charToGlyph: r,
|
|
180
|
+
getPath: c,
|
|
131
181
|
getPaths: s
|
|
132
182
|
};
|
|
133
183
|
}
|
|
134
184
|
const X = /* @__PURE__ */ new Map(), ve = () => X;
|
|
135
185
|
async function ut(e, t) {
|
|
136
|
-
const n = new DecompressionStream(t), o = n.writable.getWriter(),
|
|
186
|
+
const n = new DecompressionStream(t), o = n.writable.getWriter(), l = n.readable.getReader();
|
|
137
187
|
o.write(new Uint8Array(e)), o.close();
|
|
138
|
-
const
|
|
188
|
+
const r = [];
|
|
139
189
|
for (; ; ) {
|
|
140
|
-
const { done:
|
|
141
|
-
if (
|
|
142
|
-
|
|
190
|
+
const { done: h, value: i } = await l.read();
|
|
191
|
+
if (h) break;
|
|
192
|
+
r.push(i);
|
|
143
193
|
}
|
|
144
|
-
const
|
|
145
|
-
let
|
|
146
|
-
for (const
|
|
147
|
-
s.set(
|
|
194
|
+
const a = r.reduce((h, i) => h + i.length, 0), s = new Uint8Array(a);
|
|
195
|
+
let c = 0;
|
|
196
|
+
for (const h of r)
|
|
197
|
+
s.set(h, c), c += h.length;
|
|
148
198
|
return s;
|
|
149
199
|
}
|
|
150
200
|
async function It(e) {
|
|
151
201
|
return ut(e, "gzip");
|
|
152
202
|
}
|
|
153
203
|
async function Wt(e) {
|
|
154
|
-
const t = new DataView(e), n = t.getUint32(4), o = t.getUint16(12),
|
|
155
|
-
for (let
|
|
156
|
-
const
|
|
157
|
-
t.getUint8(
|
|
158
|
-
t.getUint8(
|
|
159
|
-
t.getUint8(
|
|
160
|
-
t.getUint8(
|
|
204
|
+
const t = new DataView(e), n = t.getUint32(4), o = t.getUint16(12), l = [];
|
|
205
|
+
for (let u = 0; u < o; u++) {
|
|
206
|
+
const f = 44 + u * 20, d = String.fromCharCode(
|
|
207
|
+
t.getUint8(f),
|
|
208
|
+
t.getUint8(f + 1),
|
|
209
|
+
t.getUint8(f + 2),
|
|
210
|
+
t.getUint8(f + 3)
|
|
161
211
|
);
|
|
162
|
-
|
|
163
|
-
tag:
|
|
164
|
-
offset: t.getUint32(
|
|
165
|
-
compLength: t.getUint32(
|
|
166
|
-
origLength: t.getUint32(
|
|
167
|
-
checksum: t.getUint32(
|
|
212
|
+
l.push({
|
|
213
|
+
tag: d,
|
|
214
|
+
offset: t.getUint32(f + 4),
|
|
215
|
+
compLength: t.getUint32(f + 8),
|
|
216
|
+
origLength: t.getUint32(f + 12),
|
|
217
|
+
checksum: t.getUint32(f + 16)
|
|
168
218
|
});
|
|
169
219
|
}
|
|
170
|
-
const
|
|
171
|
-
for (const
|
|
172
|
-
const
|
|
173
|
-
|
|
220
|
+
const r = [];
|
|
221
|
+
for (const u of l) {
|
|
222
|
+
const f = new Uint8Array(e, u.offset, u.compLength);
|
|
223
|
+
u.compLength === u.origLength ? r.push(new Uint8Array(f)) : r.push(await ut(f, "deflate"));
|
|
174
224
|
}
|
|
175
|
-
const
|
|
176
|
-
let
|
|
177
|
-
const
|
|
178
|
-
for (let
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
for (let
|
|
183
|
-
const
|
|
184
|
-
for (let
|
|
185
|
-
|
|
225
|
+
const a = 2 ** Math.floor(Math.log2(o)) * 16, s = Math.floor(Math.log2(o)), c = o * 16 - a;
|
|
226
|
+
let h = 12 + o * 16;
|
|
227
|
+
const i = [];
|
|
228
|
+
for (let u = 0; u < l.length; u++)
|
|
229
|
+
i.push(h), h += l[u].origLength + 3 & -4;
|
|
230
|
+
const b = new Uint8Array(h), p = new DataView(b.buffer);
|
|
231
|
+
p.setUint32(0, n), p.setUint16(4, o), p.setUint16(6, a), p.setUint16(8, s), p.setUint16(10, c);
|
|
232
|
+
for (let u = 0; u < l.length; u++) {
|
|
233
|
+
const f = l[u], d = 12 + u * 16;
|
|
234
|
+
for (let g = 0; g < 4; g++) b[d + g] = f.tag.charCodeAt(g);
|
|
235
|
+
p.setUint32(d + 4, f.checksum), p.setUint32(d + 8, i[u]), p.setUint32(d + 12, f.origLength), b.set(r[u], i[u]);
|
|
186
236
|
}
|
|
187
|
-
return
|
|
237
|
+
return b.buffer;
|
|
188
238
|
}
|
|
189
239
|
async function at(e, t, n) {
|
|
190
|
-
const o = /* @__PURE__ */ new Map(),
|
|
191
|
-
for (let
|
|
192
|
-
const
|
|
193
|
-
let
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
for (let
|
|
197
|
-
const
|
|
198
|
-
let
|
|
199
|
-
|
|
240
|
+
const o = /* @__PURE__ */ new Map(), l = new DataView(e.buffer, e.byteOffset, e.byteLength), r = l.getUint32(2), a = l.getUint16(r), s = r;
|
|
241
|
+
for (let c = 0; c < a; c++) {
|
|
242
|
+
const h = r + 2 + c * 12, i = l.getUint16(h), b = l.getUint16(h + 2), p = l.getUint32(h + 4), u = l.getUint32(h + 8), f = s + p;
|
|
243
|
+
let d = e.slice(f, f + u);
|
|
244
|
+
d[0] === 31 && d[1] === 139 && (d = await It(d));
|
|
245
|
+
const g = new TextDecoder().decode(d);
|
|
246
|
+
for (let w = i; w <= b; w++) {
|
|
247
|
+
const m = t.glyphExtents(w);
|
|
248
|
+
let y;
|
|
249
|
+
m ? y = `${m.xBearing} ${-m.yBearing} ${m.width} ${-m.height}` : y = "0 0 0 0", o.set(w, { svg: g, viewbox: y });
|
|
200
250
|
}
|
|
201
251
|
}
|
|
202
252
|
return o;
|
|
203
253
|
}
|
|
204
254
|
const Gt = 2001684038;
|
|
205
|
-
async function
|
|
255
|
+
async function Ot(e) {
|
|
206
256
|
return e.byteLength >= 4 && new DataView(e).getUint32(0) === Gt ? Wt(e) : e;
|
|
207
257
|
}
|
|
208
258
|
async function it(e) {
|
|
@@ -212,31 +262,31 @@ async function it(e) {
|
|
|
212
262
|
`Failed to load font from ${e}: ${t.status} ${t.statusText}`
|
|
213
263
|
);
|
|
214
264
|
const n = await t.arrayBuffer();
|
|
215
|
-
return
|
|
265
|
+
return Ot(n);
|
|
216
266
|
}
|
|
217
|
-
const
|
|
267
|
+
const Dt = async (e, t = !1) => {
|
|
218
268
|
const n = X.get(e);
|
|
219
269
|
if (n) {
|
|
220
270
|
if (t && !n.svgGlyphs) {
|
|
221
|
-
const
|
|
222
|
-
n.svgGlyphs =
|
|
271
|
+
const i = await it(e), b = new ot(i), p = new rt(b), u = new st(p), f = p.referenceTable("SVG "), d = f ? await at(f, u, p.upem) : /* @__PURE__ */ new Map();
|
|
272
|
+
n.svgGlyphs = d;
|
|
223
273
|
}
|
|
224
274
|
return n;
|
|
225
275
|
}
|
|
226
|
-
const o = await it(e),
|
|
227
|
-
let
|
|
276
|
+
const o = await it(e), l = new ot(o), r = new rt(l), a = new st(r), s = r.getName(1, "en") ?? "";
|
|
277
|
+
let c;
|
|
228
278
|
if (t) {
|
|
229
|
-
const
|
|
230
|
-
|
|
279
|
+
const i = r.referenceTable("SVG ");
|
|
280
|
+
c = i ? await at(i, a, r.upem) : /* @__PURE__ */ new Map();
|
|
231
281
|
}
|
|
232
|
-
const
|
|
233
|
-
return X.set(e,
|
|
234
|
-
},
|
|
235
|
-
outlineWidth:
|
|
282
|
+
const h = Ut(r, a, s, c);
|
|
283
|
+
return X.set(e, h), h;
|
|
284
|
+
}, qt = 0.03125, pt = 1.1, Nt = 0.2, G = {
|
|
285
|
+
outlineWidth: qt,
|
|
236
286
|
letterSpacing: 0,
|
|
237
287
|
letterSpacingOutline: 0
|
|
238
288
|
};
|
|
239
|
-
class
|
|
289
|
+
class P {
|
|
240
290
|
constructor(t, n) {
|
|
241
291
|
this.x = t, this.y = n;
|
|
242
292
|
}
|
|
@@ -250,11 +300,11 @@ class F {
|
|
|
250
300
|
return `${this.x} ${this.y}`;
|
|
251
301
|
}
|
|
252
302
|
}
|
|
253
|
-
function
|
|
254
|
-
const o = e.X - n.X,
|
|
255
|
-
return new
|
|
303
|
+
function _t(e, t, n = new P(0, 0)) {
|
|
304
|
+
const o = e.X - n.X, l = e.Y - n.Y, r = t / 180 * Math.PI, a = Math.cos(r), s = Math.sin(r), c = o * a - l * s, h = o * s + l * a;
|
|
305
|
+
return new P(c + n.X, h + n.Y);
|
|
256
306
|
}
|
|
257
|
-
const
|
|
307
|
+
const Vt = (e) => e === void 0 || e === "flat" ? { type: "flat" } : e === "curved" ? { type: "curved" } : e, Ht = (e) => {
|
|
258
308
|
if (!e || !e.trim())
|
|
259
309
|
throw new Error("Custom baseline path must be a non-empty SVG path string");
|
|
260
310
|
if (!e.trim().startsWith("M"))
|
|
@@ -266,44 +316,44 @@ const qt = (e) => e === void 0 || e === "flat" ? { type: "flat" } : e === "curve
|
|
|
266
316
|
totalTextHeight: t,
|
|
267
317
|
baseline: n,
|
|
268
318
|
lineHeight: o,
|
|
269
|
-
verticalAlignment:
|
|
270
|
-
lineNumber:
|
|
319
|
+
verticalAlignment: l = "centre",
|
|
320
|
+
lineNumber: r = 0
|
|
271
321
|
}) => {
|
|
272
|
-
const { width:
|
|
273
|
-
let
|
|
274
|
-
switch (
|
|
322
|
+
const { width: a, height: s } = e, c = o - n;
|
|
323
|
+
let h = n;
|
|
324
|
+
switch (l) {
|
|
275
325
|
case "centre": {
|
|
276
|
-
|
|
326
|
+
h = (s - t) / 2 + o - c;
|
|
277
327
|
break;
|
|
278
328
|
}
|
|
279
329
|
case "bottom": {
|
|
280
|
-
|
|
330
|
+
h = s - t + o - c;
|
|
281
331
|
break;
|
|
282
332
|
}
|
|
283
333
|
}
|
|
284
|
-
return
|
|
334
|
+
return h += r * (o * pt), `M 0 ${h} L ${a} ${h}`;
|
|
285
335
|
}, mt = ({
|
|
286
336
|
boxDimensions: e,
|
|
287
337
|
baseline: t,
|
|
288
338
|
textHeight: n,
|
|
289
339
|
verticalAlignment: o
|
|
290
340
|
}) => {
|
|
291
|
-
const { width:
|
|
292
|
-
if (o !== "top" && (
|
|
341
|
+
const { width: l, height: r } = e, a = n * Nt, s = n + a, c = o === "top" ? 0 : r / 2 - s / 2, h = t + c, i = h + a;
|
|
342
|
+
if (o !== "top" && (i > r || h - n < 0))
|
|
293
343
|
return mt({
|
|
294
344
|
boxDimensions: e,
|
|
295
345
|
baseline: t,
|
|
296
346
|
textHeight: n,
|
|
297
347
|
verticalAlignment: "top"
|
|
298
348
|
});
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
t +
|
|
302
|
-
),
|
|
303
|
-
|
|
304
|
-
t +
|
|
305
|
-
),
|
|
306
|
-
return `${
|
|
349
|
+
const b = n / 4, p = new P(b, i), u = new P(l / 2, h), f = new P(l - b, i), d = l * 0.2, g = new P(
|
|
350
|
+
d,
|
|
351
|
+
t + c
|
|
352
|
+
), w = new P(
|
|
353
|
+
l - d,
|
|
354
|
+
t + c
|
|
355
|
+
), m = `M ${p.toSVGString()}`, y = `Q ${g.toSVGString()} ${u.toSVGString()}`, $ = `Q ${w.toSVGString()} ${f.toSVGString()}`;
|
|
356
|
+
return `${m} ${y} ${$}`;
|
|
307
357
|
}, yt = (e) => {
|
|
308
358
|
const t = ["I", "l", "1"];
|
|
309
359
|
for (const n of t) {
|
|
@@ -320,37 +370,37 @@ const qt = (e) => e === void 0 || e === "flat" ? { type: "flat" } : e === "curve
|
|
|
320
370
|
physicalSize: n,
|
|
321
371
|
spacing: o = G
|
|
322
372
|
}) => {
|
|
323
|
-
const
|
|
324
|
-
if (
|
|
373
|
+
const l = n;
|
|
374
|
+
if (l[1] !== t.physicalUnits)
|
|
325
375
|
throw new Error(
|
|
326
|
-
`Mismatched units between physicalFontSize (${
|
|
376
|
+
`Mismatched units between physicalFontSize (${l[1]}) and boxDimensions (${t.physicalUnits})`
|
|
327
377
|
);
|
|
328
|
-
const { outlineWidth:
|
|
329
|
-
|
|
378
|
+
const { outlineWidth: r } = o, a = yt(e), c = e.getPath(
|
|
379
|
+
a,
|
|
330
380
|
0,
|
|
331
381
|
0,
|
|
332
382
|
z
|
|
333
383
|
).getBoundingBox();
|
|
334
|
-
let
|
|
335
|
-
if (
|
|
336
|
-
const
|
|
337
|
-
|
|
384
|
+
let h = c.y2 - c.y1;
|
|
385
|
+
if (r > 0) {
|
|
386
|
+
const f = z * r;
|
|
387
|
+
h += f * 2;
|
|
338
388
|
}
|
|
339
|
-
const
|
|
340
|
-
return z *
|
|
389
|
+
const b = h / t.height * t.physicalHeight, p = l[0] / b;
|
|
390
|
+
return z * p;
|
|
341
391
|
}, ct = ({
|
|
342
392
|
font: e,
|
|
343
393
|
text: t,
|
|
344
394
|
fontSize: n,
|
|
345
395
|
spacing: o = G
|
|
346
396
|
}) => {
|
|
347
|
-
const { outlineWidth:
|
|
397
|
+
const { outlineWidth: l, letterSpacing: r, letterSpacingOutline: a } = o, c = e.getPath(t, 0, 0, n).getBoundingBox(), h = l ? n * l * 2 : 0, i = l > 0 ? a : r, b = t.length > 1 ? i * n * (t.length - 1) : 0, p = c.x2 - c.x1 + h + b, u = c.y2 - c.y1 + h, f = c.y1 * -1 + h / 2;
|
|
348
398
|
return {
|
|
349
|
-
width:
|
|
350
|
-
height:
|
|
351
|
-
baseline:
|
|
399
|
+
width: p,
|
|
400
|
+
height: u,
|
|
401
|
+
baseline: f
|
|
352
402
|
};
|
|
353
|
-
},
|
|
403
|
+
}, q = Tt, jt = Lt, Xt = () => new q().parseFromString("<svg></svg>", "image/svg+xml"), Zt = Xt();
|
|
354
404
|
Zt.readyState = "complete";
|
|
355
405
|
const Qt = {
|
|
356
406
|
aliceblue: "#f0f8ff",
|
|
@@ -512,15 +562,15 @@ const Qt = {
|
|
|
512
562
|
return `#${R(t)}${R(n)}${R(o)}`;
|
|
513
563
|
}, Jt = (e, t, n) => {
|
|
514
564
|
if (t === 0) {
|
|
515
|
-
const
|
|
516
|
-
return [
|
|
565
|
+
const i = Math.round(n * 255);
|
|
566
|
+
return [i, i, i];
|
|
517
567
|
}
|
|
518
|
-
const o = (e % 360 + 360) % 360,
|
|
519
|
-
let s = 0,
|
|
520
|
-
return o < 60 ? (s =
|
|
521
|
-
Math.round((s +
|
|
522
|
-
Math.round((
|
|
523
|
-
Math.round((
|
|
568
|
+
const o = (e % 360 + 360) % 360, l = (1 - Math.abs(2 * n - 1)) * t, r = l * (1 - Math.abs(o / 60 % 2 - 1)), a = n - l / 2;
|
|
569
|
+
let s = 0, c = 0, h = 0;
|
|
570
|
+
return o < 60 ? (s = l, c = r, h = 0) : o < 120 ? (s = r, c = l, h = 0) : o < 180 ? (s = 0, c = l, h = r) : o < 240 ? (s = 0, c = r, h = l) : o < 300 ? (s = r, c = 0, h = l) : (s = l, c = 0, h = r), [
|
|
571
|
+
Math.round((s + a) * 255),
|
|
572
|
+
Math.round((c + a) * 255),
|
|
573
|
+
Math.round((h + a) * 255)
|
|
524
574
|
];
|
|
525
575
|
}, Kt = (e) => /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.test(e), Z = (e) => {
|
|
526
576
|
const t = e.trim().toLowerCase();
|
|
@@ -541,12 +591,12 @@ const Qt = {
|
|
|
541
591
|
/hsla?\(\s*(\d+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*(?:,\s*[\d.]+\s*)?\)/
|
|
542
592
|
);
|
|
543
593
|
if (!o) return;
|
|
544
|
-
const
|
|
545
|
-
return lt(s,
|
|
594
|
+
const l = Number.parseInt(o[1], 10), r = Number.parseFloat(o[2]) / 100, a = Number.parseFloat(o[3]) / 100, [s, c, h] = Jt(l, r, a);
|
|
595
|
+
return lt(s, c, h);
|
|
546
596
|
}
|
|
547
597
|
const n = Qt[t];
|
|
548
598
|
if (n) return n;
|
|
549
|
-
},
|
|
599
|
+
}, E = {
|
|
550
600
|
circle: "circle",
|
|
551
601
|
ellipse: "ellipse",
|
|
552
602
|
rect: "rect",
|
|
@@ -555,28 +605,28 @@ const Qt = {
|
|
|
555
605
|
polygon: "polygon",
|
|
556
606
|
polyline: "polyline",
|
|
557
607
|
stop: "stop"
|
|
558
|
-
},
|
|
608
|
+
}, D = {
|
|
559
609
|
fill: "fill",
|
|
560
610
|
stroke: "stroke"
|
|
561
611
|
}, te = {
|
|
562
612
|
tiling: [
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
`[${
|
|
572
|
-
`[${
|
|
613
|
+
E.circle,
|
|
614
|
+
E.ellipse,
|
|
615
|
+
E.rect,
|
|
616
|
+
E.line,
|
|
617
|
+
E.path,
|
|
618
|
+
E.polygon,
|
|
619
|
+
E.polyline,
|
|
620
|
+
E.stop,
|
|
621
|
+
`[${D.fill}]`,
|
|
622
|
+
`[${D.stroke}]`
|
|
573
623
|
]
|
|
574
624
|
}, ee = (e) => Array.from(
|
|
575
625
|
e.querySelectorAll(
|
|
576
626
|
te.tiling.map((t) => `*:not(clipPath) > ${t}`).join(", ")
|
|
577
627
|
)
|
|
578
628
|
), ne = (e) => {
|
|
579
|
-
const t = e.getAttribute(
|
|
629
|
+
const t = e.getAttribute(D.stroke);
|
|
580
630
|
return t === "none" || !t ? !1 : t;
|
|
581
631
|
}, j = (e) => {
|
|
582
632
|
if (!(e === "none" || e === "transparent" || e.startsWith("url(")))
|
|
@@ -584,17 +634,17 @@ const Qt = {
|
|
|
584
634
|
}, oe = (e) => {
|
|
585
635
|
const t = ee(e).reduce(
|
|
586
636
|
(n, o) => {
|
|
587
|
-
const
|
|
588
|
-
if (!
|
|
589
|
-
const s = j(
|
|
637
|
+
const l = o.getAttribute("stop-color"), r = o.getAttribute(D.fill) || "#000", a = ne(o);
|
|
638
|
+
if (!l) {
|
|
639
|
+
const s = j(r);
|
|
590
640
|
s && n.add(s);
|
|
591
641
|
}
|
|
592
|
-
if (
|
|
593
|
-
const s = j(
|
|
642
|
+
if (l) {
|
|
643
|
+
const s = j(l);
|
|
594
644
|
s && n.add(s);
|
|
595
645
|
}
|
|
596
|
-
if (
|
|
597
|
-
const s = j(
|
|
646
|
+
if (a) {
|
|
647
|
+
const s = j(a);
|
|
598
648
|
s && n.add(s);
|
|
599
649
|
}
|
|
600
650
|
return n;
|
|
@@ -603,14 +653,14 @@ const Qt = {
|
|
|
603
653
|
);
|
|
604
654
|
return Array.from(t);
|
|
605
655
|
}, re = (e) => {
|
|
606
|
-
const t = new
|
|
656
|
+
const t = new q().parseFromString(e, "image/svg+xml").querySelector("svg");
|
|
607
657
|
return t ? oe(t) : [];
|
|
608
658
|
};
|
|
609
|
-
function
|
|
659
|
+
function bt(e) {
|
|
610
660
|
const t = e.trim(), n = t.startsWith("<svg") || t.startsWith("<?xml"), o = n ? t : `<svg>${t}</svg>`;
|
|
611
|
-
return { doc: new
|
|
661
|
+
return { doc: new q().parseFromString(o, "image/svg+xml"), wasWrapped: !n };
|
|
612
662
|
}
|
|
613
|
-
function
|
|
663
|
+
function wt(e, t) {
|
|
614
664
|
const n = e.querySelector("svg");
|
|
615
665
|
return n ? t ? n.innerHTML : n.outerHTML : "";
|
|
616
666
|
}
|
|
@@ -620,68 +670,68 @@ function $e(e) {
|
|
|
620
670
|
return [];
|
|
621
671
|
const n = /* @__PURE__ */ new Set();
|
|
622
672
|
for (const [, o] of t)
|
|
623
|
-
for (const
|
|
624
|
-
n.add(
|
|
673
|
+
for (const l of re(o.svg))
|
|
674
|
+
n.add(l);
|
|
625
675
|
return Array.from(n);
|
|
626
676
|
}
|
|
627
677
|
function se(e) {
|
|
628
678
|
return !!e && e !== "none" && e !== "transparent" && !e.startsWith("url(");
|
|
629
679
|
}
|
|
630
680
|
function ae(e) {
|
|
631
|
-
const n = new
|
|
681
|
+
const n = new q().parseFromString(e, "image/svg+xml").querySelector("svg");
|
|
632
682
|
return n ? n.innerHTML.trim() : "";
|
|
633
683
|
}
|
|
634
684
|
const ie = ["fill", "stroke", "clip-path", "mask", "filter"];
|
|
635
685
|
function ce(e, t) {
|
|
636
|
-
const { doc: n, wasWrapped: o } =
|
|
637
|
-
for (const
|
|
638
|
-
const
|
|
639
|
-
if (!
|
|
640
|
-
const s = `${t}-${
|
|
641
|
-
|
|
686
|
+
const { doc: n, wasWrapped: o } = bt(e), l = /* @__PURE__ */ new Map();
|
|
687
|
+
for (const r of n.querySelectorAll("[id]")) {
|
|
688
|
+
const a = r.getAttribute("id");
|
|
689
|
+
if (!a) continue;
|
|
690
|
+
const s = `${t}-${a}`;
|
|
691
|
+
l.set(a, s), r.setAttribute("id", s);
|
|
642
692
|
}
|
|
643
|
-
if (
|
|
693
|
+
if (l.size === 0)
|
|
644
694
|
return e;
|
|
645
|
-
for (const
|
|
646
|
-
for (const
|
|
647
|
-
const s =
|
|
695
|
+
for (const r of ie)
|
|
696
|
+
for (const a of n.querySelectorAll(`[${r}]`)) {
|
|
697
|
+
const s = a.getAttribute(r);
|
|
648
698
|
if (s) {
|
|
649
|
-
const
|
|
650
|
-
const
|
|
651
|
-
return
|
|
699
|
+
const c = s.replace(/url\(#([^)]+)\)/g, (h, i) => {
|
|
700
|
+
const b = l.get(i);
|
|
701
|
+
return b ? `url(#${b})` : `url(#${i})`;
|
|
652
702
|
});
|
|
653
|
-
|
|
703
|
+
c !== s && a.setAttribute(r, c);
|
|
654
704
|
}
|
|
655
705
|
}
|
|
656
|
-
for (const
|
|
657
|
-
for (const
|
|
658
|
-
const s =
|
|
706
|
+
for (const r of n.querySelectorAll("[href], [xlink\\:href]"))
|
|
707
|
+
for (const a of ["href", "xlink:href"]) {
|
|
708
|
+
const s = r.getAttribute(a);
|
|
659
709
|
if (s?.startsWith("#")) {
|
|
660
|
-
const
|
|
661
|
-
|
|
710
|
+
const c = s.slice(1), h = l.get(c);
|
|
711
|
+
h && r.setAttribute(a, `#${h}`);
|
|
662
712
|
}
|
|
663
713
|
}
|
|
664
|
-
return
|
|
714
|
+
return wt(n, o);
|
|
665
715
|
}
|
|
666
716
|
const le = ["fill", "stroke", "stop-color"], fe = ["path", "rect", "circle", "ellipse", "polygon", "polyline", "text"];
|
|
667
717
|
function he(e, t) {
|
|
668
|
-
const { doc: n, wasWrapped: o } =
|
|
669
|
-
for (const [
|
|
670
|
-
|
|
671
|
-
for (const
|
|
672
|
-
for (const s of n.querySelectorAll(`[${
|
|
673
|
-
const
|
|
674
|
-
if (!
|
|
675
|
-
const
|
|
676
|
-
|
|
718
|
+
const { doc: n, wasWrapped: o } = bt(e), l = {};
|
|
719
|
+
for (const [a, s] of Object.entries(t))
|
|
720
|
+
l[Z(a) ?? a.toLowerCase()] = s;
|
|
721
|
+
for (const a of le)
|
|
722
|
+
for (const s of n.querySelectorAll(`[${a}]`)) {
|
|
723
|
+
const c = s.getAttribute(a);
|
|
724
|
+
if (!c || !se(c)) continue;
|
|
725
|
+
const h = Z(c), i = h ? l[h] : void 0;
|
|
726
|
+
i && s.setAttribute(a, i.hex);
|
|
677
727
|
}
|
|
678
|
-
const
|
|
679
|
-
if (
|
|
680
|
-
const
|
|
681
|
-
for (const s of n.querySelectorAll(
|
|
682
|
-
s.setAttribute("fill",
|
|
728
|
+
const r = l["#000000"];
|
|
729
|
+
if (r) {
|
|
730
|
+
const a = fe.map((s) => `${s}:not([fill])`).join(", ");
|
|
731
|
+
for (const s of n.querySelectorAll(a))
|
|
732
|
+
s.setAttribute("fill", r.hex);
|
|
683
733
|
}
|
|
684
|
-
return
|
|
734
|
+
return wt(n, o);
|
|
685
735
|
}
|
|
686
736
|
const de = (e = [1, 0, 0, 1, 0, 0]) => {
|
|
687
737
|
const t = `matrix(${e.join(",")})`, n = new jt(t);
|
|
@@ -697,80 +747,80 @@ const ft = (e, t, n) => e / n * t, ue = ({
|
|
|
697
747
|
baselinePath: t,
|
|
698
748
|
text: n,
|
|
699
749
|
fontSize: o,
|
|
700
|
-
spacing:
|
|
701
|
-
horizontalAlignment:
|
|
702
|
-
colourMap:
|
|
750
|
+
spacing: l = G,
|
|
751
|
+
horizontalAlignment: r = "centre",
|
|
752
|
+
colourMap: a
|
|
703
753
|
}) => {
|
|
704
|
-
const { outlineWidth: s, letterSpacing:
|
|
705
|
-
let
|
|
706
|
-
|
|
707
|
-
const
|
|
708
|
-
let S = 0 -
|
|
709
|
-
|
|
710
|
-
const
|
|
711
|
-
for (let
|
|
712
|
-
const
|
|
713
|
-
if (!
|
|
754
|
+
const { outlineWidth: s, letterSpacing: c, letterSpacingOutline: h } = l, i = new Pt(t), b = s ? o * s * 2 : 0, p = i.getTotalLength(), u = e.getPaths(n, 0, 0, o, { drawSVG: !1 }), d = e.getPath(n, 0, 0, o, { drawSVG: !1 }).getBoundingBox(), g = d.x1 - b / 2, m = d.x2 + b / 2 - g, y = s > 0 ? h : c;
|
|
755
|
+
let $ = y ? y * o : 0;
|
|
756
|
+
r === "distributed" && ($ = n.length === 1 ? 0 : (p - m) / (n.length - 1));
|
|
757
|
+
const v = $ * (n.length - 1), M = m + v;
|
|
758
|
+
let S = 0 - g;
|
|
759
|
+
r === "centre" ? S = (p - M) / 2 - g : r === "right" && (S = p - m - g - v);
|
|
760
|
+
const A = [];
|
|
761
|
+
for (let k = 0; k < u.length; k++) {
|
|
762
|
+
const x = u[k], F = x.getBoundingBox(), T = e.charToGlyph(n[k]), { advanceWidth: U } = T;
|
|
763
|
+
if (!U)
|
|
714
764
|
throw new Error(
|
|
715
|
-
`No advance width for character: ${n[
|
|
765
|
+
`No advance width for character: ${n[k]} in font ${e.names.fontFamily}`
|
|
716
766
|
);
|
|
717
|
-
const { x1: xt, x2: vt } =
|
|
718
|
-
|
|
767
|
+
const { x1: xt, x2: vt } = T.getBoundingBox(), $t = ft(
|
|
768
|
+
U,
|
|
719
769
|
o,
|
|
720
770
|
e.unitsPerEm
|
|
721
771
|
), Y = ft(vt - xt, o, e.unitsPerEm);
|
|
722
|
-
let I = S +
|
|
723
|
-
if (
|
|
772
|
+
let I = S + F.x1;
|
|
773
|
+
if (k > 0 && (I += $ * k), I + Y > p)
|
|
724
774
|
throw new Error(
|
|
725
|
-
`TOO_WIDE: character "${n[
|
|
775
|
+
`TOO_WIDE: character "${n[k]}" at index ${k} exceeds baseline path length (${Math.round(I + Y)} > ${Math.round(p)})`
|
|
726
776
|
);
|
|
727
|
-
const St = I + $t / 2, J =
|
|
728
|
-
new F
|
|
729
|
-
|
|
777
|
+
const St = I + $t / 2, J = i.getTangentAtLength(St), O = Math.atan2(J.y, J.x) * 180 / Math.PI, K = i.getPointAtLength(I), kt = K.x, Mt = K.y, tt = F.x2 - F.x1, Ft = new P(F.x1 + tt / 2, 0), et = _t(
|
|
778
|
+
new P(F.x1, 0),
|
|
779
|
+
O,
|
|
730
780
|
Ft
|
|
731
|
-
),
|
|
732
|
-
let
|
|
733
|
-
|
|
734
|
-
let
|
|
735
|
-
if (
|
|
736
|
-
const
|
|
737
|
-
|
|
781
|
+
), N = kt - et.X, _ = Mt - et.Y;
|
|
782
|
+
let B = de();
|
|
783
|
+
B = B.translate(N, _);
|
|
784
|
+
let V;
|
|
785
|
+
if (O) {
|
|
786
|
+
const C = F.x1 + tt / 2;
|
|
787
|
+
B = B.translate(C, 0), B = B.rotate(O), B = B.translate(-C, 0), V = `translate(${N} ${_}) translate(${C} 0) rotate(${O}) translate(${-C} 0)`;
|
|
738
788
|
} else
|
|
739
|
-
|
|
740
|
-
let
|
|
741
|
-
|
|
789
|
+
V = `translate(${N} ${_})`;
|
|
790
|
+
let L = x.toPathData(2);
|
|
791
|
+
L.length && !L.endsWith("Z") && (L += "Z", L = L.replace(/M/g, "ZM"), L = L.substring(1));
|
|
742
792
|
let H;
|
|
743
793
|
if (e.svgGlyphs) {
|
|
744
|
-
const
|
|
745
|
-
if (
|
|
746
|
-
let W = ae(
|
|
747
|
-
W = ce(W, `g${
|
|
794
|
+
const C = e.svgGlyphs.get(T.index);
|
|
795
|
+
if (C) {
|
|
796
|
+
let W = ae(C.svg);
|
|
797
|
+
W = ce(W, `g${T.index}-${k}`), a && (W = he(W, a)), H = {
|
|
748
798
|
content: W,
|
|
749
|
-
viewBox:
|
|
750
|
-
x:
|
|
751
|
-
y:
|
|
752
|
-
width:
|
|
753
|
-
height:
|
|
754
|
-
glyphIndex:
|
|
799
|
+
viewBox: C.viewbox,
|
|
800
|
+
x: F.x1,
|
|
801
|
+
y: F.y1,
|
|
802
|
+
width: F.x2 - F.x1,
|
|
803
|
+
height: F.y2 - F.y1,
|
|
804
|
+
glyphIndex: T.index
|
|
755
805
|
};
|
|
756
806
|
}
|
|
757
807
|
}
|
|
758
|
-
|
|
759
|
-
path:
|
|
760
|
-
matrix:
|
|
808
|
+
A.push({
|
|
809
|
+
path: x,
|
|
810
|
+
matrix: B,
|
|
761
811
|
attributes: {
|
|
762
|
-
d:
|
|
763
|
-
"data-character": ge(n[
|
|
764
|
-
transform:
|
|
812
|
+
d: L,
|
|
813
|
+
"data-character": ge(n[k]),
|
|
814
|
+
transform: V
|
|
765
815
|
},
|
|
766
816
|
glyphData: {
|
|
767
|
-
index:
|
|
768
|
-
bbox:
|
|
817
|
+
index: T.index,
|
|
818
|
+
bbox: F
|
|
769
819
|
},
|
|
770
820
|
...H ? { svgGlyph: H } : {}
|
|
771
821
|
});
|
|
772
822
|
}
|
|
773
|
-
return
|
|
823
|
+
return A;
|
|
774
824
|
}, ht = { hex: "#FFFFFF" }, Q = (e, t) => {
|
|
775
825
|
const n = `data-${e}-colour-url`, o = [`${e}="${t.hex}"`];
|
|
776
826
|
return t.reference && o.push(`${n}="${t.reference}"`), o.join(" ");
|
|
@@ -782,128 +832,128 @@ const ft = (e, t, n) => e / n * t, ue = ({
|
|
|
782
832
|
paths: t,
|
|
783
833
|
spacing: n = G,
|
|
784
834
|
fontSize: o = 0,
|
|
785
|
-
fillColour:
|
|
786
|
-
strokeColour:
|
|
835
|
+
fillColour: l = ht,
|
|
836
|
+
strokeColour: r = ht
|
|
787
837
|
}) => {
|
|
788
|
-
const { width:
|
|
789
|
-
let
|
|
790
|
-
if (
|
|
791
|
-
const
|
|
792
|
-
({ attributes:
|
|
838
|
+
const { width: a, height: s } = e, { outlineWidth: c } = n, h = c > 0 && o > 0;
|
|
839
|
+
let i;
|
|
840
|
+
if (h) {
|
|
841
|
+
const p = o * c * 2, u = t.filter((d) => !d.svgGlyph).map(
|
|
842
|
+
({ attributes: d }) => `<path d="${d.d}" ${Q("fill", r)} ${Q("stroke", r)} stroke-width="${p}" stroke-linejoin="round" transform="${d.transform}" data-character="${d["data-character"]}"/>`
|
|
793
843
|
).join(`
|
|
794
|
-
`),
|
|
844
|
+
`), f = t.map((d) => dt(d, l)).join(`
|
|
795
845
|
`);
|
|
796
|
-
|
|
797
|
-
${
|
|
846
|
+
i = `${u}
|
|
847
|
+
${f}`;
|
|
798
848
|
} else
|
|
799
|
-
|
|
849
|
+
i = t.map((p) => dt(p, l)).join(`
|
|
800
850
|
`);
|
|
801
|
-
const
|
|
802
|
-
${
|
|
851
|
+
const b = i ? `
|
|
852
|
+
${i}
|
|
803
853
|
` : "";
|
|
804
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${
|
|
854
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${a}" height="${s}" viewBox="0 0 ${a} ${s}">${b}</svg>`;
|
|
805
855
|
}, gt = (e) => {
|
|
806
856
|
const {
|
|
807
857
|
text: t,
|
|
808
858
|
font: n,
|
|
809
859
|
physicalSize: o,
|
|
810
|
-
fontSize:
|
|
811
|
-
boxDimensions:
|
|
812
|
-
spacing:
|
|
860
|
+
fontSize: l,
|
|
861
|
+
boxDimensions: r,
|
|
862
|
+
spacing: a = G,
|
|
813
863
|
verticalAlignment: s = "centre",
|
|
814
|
-
baseline:
|
|
815
|
-
horizontalAlignment:
|
|
816
|
-
fillColour:
|
|
817
|
-
strokeColour:
|
|
818
|
-
colourMap:
|
|
819
|
-
} = e, { width:
|
|
820
|
-
if (
|
|
864
|
+
baseline: c = "flat",
|
|
865
|
+
horizontalAlignment: h = "left",
|
|
866
|
+
fillColour: i = { hex: "#FFFFFF" },
|
|
867
|
+
strokeColour: b = { hex: "#FFFFFF" },
|
|
868
|
+
colourMap: p
|
|
869
|
+
} = e, { width: u, height: f, physicalWidth: d, physicalHeight: g } = r;
|
|
870
|
+
if (u <= 0 || f <= 0)
|
|
821
871
|
throw new Error(
|
|
822
|
-
`boxDimensions width and height must be positive (got ${
|
|
872
|
+
`boxDimensions width and height must be positive (got ${u}x${f})`
|
|
823
873
|
);
|
|
824
|
-
if (
|
|
874
|
+
if (d <= 0 || g <= 0)
|
|
825
875
|
throw new Error(
|
|
826
|
-
`boxDimensions physicalWidth and physicalHeight must be positive (got ${
|
|
876
|
+
`boxDimensions physicalWidth and physicalHeight must be positive (got ${d}x${g})`
|
|
827
877
|
);
|
|
828
878
|
if (o[0] <= 0)
|
|
829
879
|
throw new Error(
|
|
830
880
|
`physicalSize height must be positive (got ${o[0]})`
|
|
831
881
|
);
|
|
832
|
-
const
|
|
882
|
+
const w = l ?? Rt({
|
|
833
883
|
font: n,
|
|
834
|
-
boxDimensions:
|
|
884
|
+
boxDimensions: r,
|
|
835
885
|
physicalSize: o,
|
|
836
|
-
spacing:
|
|
837
|
-
}),
|
|
838
|
-
let
|
|
839
|
-
`).filter((
|
|
840
|
-
|
|
841
|
-
const
|
|
842
|
-
(
|
|
843
|
-
),
|
|
844
|
-
for (let
|
|
845
|
-
let
|
|
846
|
-
switch (
|
|
886
|
+
spacing: a
|
|
887
|
+
}), m = Vt(c);
|
|
888
|
+
let y = t.split(`
|
|
889
|
+
`).filter((x) => x.length > 0);
|
|
890
|
+
y.length || (y = [""]), (m.type === "curved" || m.type === "custom") && (y = [y.join("")]);
|
|
891
|
+
const $ = y.map(
|
|
892
|
+
(x) => ct({ font: n, text: x, fontSize: w, spacing: a })
|
|
893
|
+
), v = Math.max(...$.map((x) => x.baseline)), M = Math.max(...$.map((x) => x.height - x.baseline)), S = v + M, A = y.length === 1 ? S : S + S * (y.length - 1) * pt, k = [];
|
|
894
|
+
for (let x = 0; x < y.length; x++) {
|
|
895
|
+
let F;
|
|
896
|
+
switch (m.type) {
|
|
847
897
|
case "custom":
|
|
848
|
-
Ht(
|
|
898
|
+
Ht(m.path), F = m.path;
|
|
849
899
|
break;
|
|
850
900
|
case "curved": {
|
|
851
|
-
const
|
|
901
|
+
const U = ct({
|
|
852
902
|
font: n,
|
|
853
903
|
text: yt(n),
|
|
854
|
-
fontSize:
|
|
855
|
-
spacing:
|
|
904
|
+
fontSize: w,
|
|
905
|
+
spacing: a
|
|
856
906
|
});
|
|
857
|
-
|
|
858
|
-
boxDimensions:
|
|
859
|
-
baseline:
|
|
860
|
-
textHeight:
|
|
907
|
+
F = mt({
|
|
908
|
+
boxDimensions: r,
|
|
909
|
+
baseline: U.baseline,
|
|
910
|
+
textHeight: U.height,
|
|
861
911
|
verticalAlignment: s
|
|
862
912
|
});
|
|
863
913
|
break;
|
|
864
914
|
}
|
|
865
915
|
case "flat":
|
|
866
|
-
|
|
867
|
-
boxDimensions:
|
|
868
|
-
totalTextHeight:
|
|
869
|
-
baseline:
|
|
916
|
+
F = zt({
|
|
917
|
+
boxDimensions: r,
|
|
918
|
+
totalTextHeight: A,
|
|
919
|
+
baseline: v,
|
|
870
920
|
lineHeight: S,
|
|
871
921
|
verticalAlignment: s,
|
|
872
|
-
lineNumber:
|
|
922
|
+
lineNumber: x
|
|
873
923
|
});
|
|
874
924
|
break;
|
|
875
925
|
}
|
|
876
|
-
const
|
|
926
|
+
const T = ue({
|
|
877
927
|
font: n,
|
|
878
|
-
baselinePath:
|
|
879
|
-
text:
|
|
880
|
-
fontSize:
|
|
881
|
-
spacing:
|
|
882
|
-
horizontalAlignment:
|
|
883
|
-
colourMap:
|
|
928
|
+
baselinePath: F,
|
|
929
|
+
text: y[x],
|
|
930
|
+
fontSize: w,
|
|
931
|
+
spacing: a,
|
|
932
|
+
horizontalAlignment: h,
|
|
933
|
+
colourMap: p
|
|
884
934
|
});
|
|
885
|
-
|
|
935
|
+
k.push(...T);
|
|
886
936
|
}
|
|
887
937
|
return pe({
|
|
888
|
-
boxDimensions:
|
|
889
|
-
paths:
|
|
890
|
-
spacing:
|
|
891
|
-
fontSize:
|
|
892
|
-
fillColour:
|
|
893
|
-
strokeColour:
|
|
938
|
+
boxDimensions: r,
|
|
939
|
+
paths: k,
|
|
940
|
+
spacing: a,
|
|
941
|
+
fontSize: w,
|
|
942
|
+
fillColour: i,
|
|
943
|
+
strokeColour: b
|
|
894
944
|
});
|
|
895
945
|
}, Se = async (e) => {
|
|
896
|
-
const { fontUrl: t, fontSizeFallback: n, ...o } = e,
|
|
946
|
+
const { fontUrl: t, fontSizeFallback: n, ...o } = e, l = !!o.colourMap, r = await Dt(t, l);
|
|
897
947
|
try {
|
|
898
|
-
return gt({ ...o, font:
|
|
899
|
-
} catch (
|
|
900
|
-
if (n != null &&
|
|
901
|
-
return gt({ ...o, font:
|
|
902
|
-
throw
|
|
948
|
+
return gt({ ...o, font: r });
|
|
949
|
+
} catch (a) {
|
|
950
|
+
if (n != null && a instanceof Error && a.message.startsWith("TOO_WIDE"))
|
|
951
|
+
return gt({ ...o, font: r, fontSize: n });
|
|
952
|
+
throw a;
|
|
903
953
|
}
|
|
904
954
|
};
|
|
905
955
|
export {
|
|
906
|
-
|
|
956
|
+
qt as DEFAULT_OUTLINE_FACTOR,
|
|
907
957
|
G as DEFAULT_SPACING,
|
|
908
958
|
pt as LINE_HEIGHT,
|
|
909
959
|
mt as generateCurvedBaseline,
|
|
@@ -913,8 +963,8 @@ export {
|
|
|
913
963
|
Rt as getFontSizeFromPhysicalSize,
|
|
914
964
|
Se as getRenderedText,
|
|
915
965
|
ct as getTextMetricsAtFontSize,
|
|
916
|
-
|
|
917
|
-
|
|
966
|
+
Dt as loadFont,
|
|
967
|
+
Vt as normaliseBaselineOption,
|
|
918
968
|
gt as renderText,
|
|
919
969
|
Ht as validateCustomBaselinePath
|
|
920
970
|
};
|