@unmade/text-renderer 1.2.0 → 1.3.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/README.md +47 -0
- package/dist/fitting/index.d.ts +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +535 -408
- package/dist/layout/index.d.ts +77 -0
- package/dist/node/fitting/index.d.ts +3 -3
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +303 -174
- package/dist/node/layout/index.d.ts +77 -0
- package/dist/node/renderText.d.ts +3 -0
- package/dist/renderText.d.ts +3 -0
- package/dist/worker/fitting/index.d.ts +3 -3
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/index.js +1839 -1712
- package/dist/worker/layout/index.d.ts +77 -0
- package/dist/worker/renderText.d.ts +3 -0
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -305,7 +305,87 @@ var D = (e) => e === void 0 || e === "flat" ? { type: "flat" } : e === "curved"
|
|
|
305
305
|
verticalAlignment: r
|
|
306
306
|
}), c = new E(s, o), l = new E(i / 2, a), u = new E(i - s, o), d = i * .2, f = new E(d, a), p = new E(i - d, a);
|
|
307
307
|
return `${`M ${c.toSVGString()}`} ${`Q ${f.toSVGString()} ${l.toSVGString()}`} ${`Q ${p.toSVGString()} ${u.toSVGString()}`}`;
|
|
308
|
-
}, M =
|
|
308
|
+
}, M = class e {
|
|
309
|
+
constructor(e = 0, t = 0, n = 0, r = 1) {
|
|
310
|
+
this.x = e, this.y = t, this.z = n, this.w = r;
|
|
311
|
+
}
|
|
312
|
+
static fromPoint(t) {
|
|
313
|
+
return new e(t.x, t.y, t.z === void 0 ? 0 : t.z, t.w === void 0 ? 1 : t.w);
|
|
314
|
+
}
|
|
315
|
+
matrixTransform(t) {
|
|
316
|
+
return t.is2D && this.z === 0 && this.w === 1 ? new e(this.x * t.a + this.y * t.c + t.e, this.x * t.b + this.y * t.d + t.f, 0, 1) : new e(this.x * t.m11 + this.y * t.m21 + this.z * t.m31 + this.w * t.m41, this.x * t.m12 + this.y * t.m22 + this.z * t.m32 + this.w * t.m42, this.x * t.m13 + this.y * t.m23 + this.z * t.m33 + this.w * t.m43, this.x * t.m14 + this.y * t.m24 + this.z * t.m34 + this.w * t.m44);
|
|
317
|
+
}
|
|
318
|
+
toJSON() {
|
|
319
|
+
return {
|
|
320
|
+
x: this.x,
|
|
321
|
+
y: this.y,
|
|
322
|
+
z: this.z,
|
|
323
|
+
w: this.w
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}, N = s, te = o, P = new N().parseFromString("<svg></svg>", "image/svg+xml");
|
|
327
|
+
P.readyState = "complete";
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region src/helpers/bbox.ts
|
|
330
|
+
var F = class {
|
|
331
|
+
get x3() {
|
|
332
|
+
return this._x3 || this.x1;
|
|
333
|
+
}
|
|
334
|
+
get y3() {
|
|
335
|
+
return this._y3 || this.y2;
|
|
336
|
+
}
|
|
337
|
+
get x4() {
|
|
338
|
+
return this._x4 || this.x2;
|
|
339
|
+
}
|
|
340
|
+
get y4() {
|
|
341
|
+
return this._y4 || this.y1;
|
|
342
|
+
}
|
|
343
|
+
constructor(e, t, n, r, i, a, o, s) {
|
|
344
|
+
this.x1 = e, this.y1 = t, this.x2 = n, this.y2 = r, this._x3 = i, this._y3 = a, this._x4 = o, this._y4 = s, this.corners = [
|
|
345
|
+
new M(this.x1, this.y1),
|
|
346
|
+
new M(this.x2, this.y2),
|
|
347
|
+
new M(this.x3, this.y3),
|
|
348
|
+
new M(this.x4, this.y4)
|
|
349
|
+
];
|
|
350
|
+
}
|
|
351
|
+
transform(e) {
|
|
352
|
+
this.corners = this.corners.map((t) => t.matrixTransform(e)), this.x1 = this.corners[0].x, this.y1 = this.corners[0].y, this.x2 = this.corners[1].x, this.y2 = this.corners[1].y, this._x3 = this.corners[2].x, this._y3 = this.corners[2].y, this._x4 = this.corners[3].x, this._y4 = this.corners[3].y;
|
|
353
|
+
}
|
|
354
|
+
toPointsArray() {
|
|
355
|
+
return this.corners.map((e) => [e.x, e.y]);
|
|
356
|
+
}
|
|
357
|
+
getBBox() {
|
|
358
|
+
let e = Math.min(this.x1, this.x2, this.x3, this.x4), t = Math.min(this.y1, this.y2, this.y3, this.y4), n = Math.max(this.x1, this.x2, this.x3, this.x4) - e, r = Math.max(this.y1, this.y2, this.y3, this.y4) - t;
|
|
359
|
+
return new I(e, t, e + n, t + r);
|
|
360
|
+
}
|
|
361
|
+
}, I = class extends F {
|
|
362
|
+
get x() {
|
|
363
|
+
return this.x1;
|
|
364
|
+
}
|
|
365
|
+
get y() {
|
|
366
|
+
return this.y1;
|
|
367
|
+
}
|
|
368
|
+
get width() {
|
|
369
|
+
return this.x2 - this.x1;
|
|
370
|
+
}
|
|
371
|
+
get height() {
|
|
372
|
+
return this.y2 - this.y1;
|
|
373
|
+
}
|
|
374
|
+
add(e) {
|
|
375
|
+
this.x1 = Math.min(this.x1, e.x1, e.x2, e.x3, e.x4), this.y1 = Math.min(this.y1, e.y1, e.y2, e.y3, e.y4), this.x2 = Math.max(this.x2, e.x1, e.x2, e.x3, e.x4), this.y2 = Math.max(this.y2, e.y1, e.y2, e.y3, e.y4);
|
|
376
|
+
}
|
|
377
|
+
addPoint(e, t) {
|
|
378
|
+
this.x1 = Math.min(this.x1, e), this.y1 = Math.min(this.y1, t), this.x2 = Math.max(this.x2, e), this.y2 = Math.max(this.y2, t);
|
|
379
|
+
}
|
|
380
|
+
serialize() {
|
|
381
|
+
return {
|
|
382
|
+
x: this.x,
|
|
383
|
+
y: this.y,
|
|
384
|
+
width: this.width,
|
|
385
|
+
height: this.height
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
}, L = (e) => {
|
|
309
389
|
for (let t of [
|
|
310
390
|
"I",
|
|
311
391
|
"l",
|
|
@@ -315,28 +395,24 @@ var D = (e) => e === void 0 || e === "flat" ? { type: "flat" } : e === "curved"
|
|
|
315
395
|
if (n && n.name !== ".notdef") return t;
|
|
316
396
|
}
|
|
317
397
|
return console.error("No standard character found for fixed height calculation. Using \"I\" as default."), "I";
|
|
318
|
-
},
|
|
398
|
+
}, R = 100, z = ({ font: e, boxDimensions: t, physicalSize: n, spacing: r = T }) => {
|
|
319
399
|
let i = n;
|
|
320
400
|
if (i[1] !== t.physicalUnits) throw Error(`Mismatched units between physicalFontSize (${i[1]}) and boxDimensions (${t.physicalUnits})`);
|
|
321
|
-
let { outlineWidth: a } = r, o =
|
|
401
|
+
let { outlineWidth: a } = r, o = L(e), s = e.getPath(o, 0, 0, R).getBoundingBox(), c = s.y2 - s.y1;
|
|
322
402
|
if (a > 0) {
|
|
323
|
-
let e =
|
|
403
|
+
let e = R * a;
|
|
324
404
|
c += e * 2;
|
|
325
405
|
}
|
|
326
406
|
let l = c / t.height * t.physicalHeight;
|
|
327
|
-
return
|
|
328
|
-
},
|
|
407
|
+
return R * (i[0] / l);
|
|
408
|
+
}, B = ({ font: e, text: t, fontSize: n, spacing: r = T }) => {
|
|
329
409
|
let { outlineWidth: i, letterSpacing: a, letterSpacingOutline: o } = r, s = e.getPath(t, 0, 0, n).getBoundingBox(), c = i ? n * i * 2 : 0, l = i > 0 ? o : a, u = t.length > 1 ? l * n * (t.length - 1) : 0;
|
|
330
410
|
return {
|
|
331
411
|
width: s.x2 - s.x1 + c + u,
|
|
332
412
|
height: s.y2 - s.y1 + c,
|
|
333
413
|
baseline: s.y1 * -1 + c / 2
|
|
334
414
|
};
|
|
335
|
-
},
|
|
336
|
-
ne.readyState = "complete";
|
|
337
|
-
//#endregion
|
|
338
|
-
//#region ../svg-helpers/dist/colours/named-colours.mjs
|
|
339
|
-
var re = {
|
|
415
|
+
}, ne = {
|
|
340
416
|
aliceblue: "#f0f8ff",
|
|
341
417
|
antiquewhite: "#faebd7",
|
|
342
418
|
aqua: "#00ffff",
|
|
@@ -485,13 +561,13 @@ var re = {
|
|
|
485
561
|
whitesmoke: "#f5f5f5",
|
|
486
562
|
yellow: "#ffff00",
|
|
487
563
|
yellowgreen: "#9acd32"
|
|
488
|
-
},
|
|
564
|
+
}, re = (e) => {
|
|
489
565
|
let t = Array.from(e), n = !1;
|
|
490
566
|
return t[0] === "#" && (t.shift(), n = !0), t.length === 3 && (t = t.map((e) => `${e}${e}`)), `${n ? "#" : ""}${t.join("").toLowerCase()}`;
|
|
491
|
-
},
|
|
567
|
+
}, V = (e) => Math.max(0, Math.min(255, Math.round(typeof e == "string" ? Number.parseInt(e, 10) : e))).toString(16).padStart(2, "0"), H = (...e) => {
|
|
492
568
|
let [t, n, r] = Array.isArray(e[0]) ? e[0] : e;
|
|
493
|
-
return `#${
|
|
494
|
-
},
|
|
569
|
+
return `#${V(t)}${V(n)}${V(r)}`;
|
|
570
|
+
}, ie = (e, t, n) => {
|
|
495
571
|
if (t === 0) {
|
|
496
572
|
let e = Math.round(n * 255);
|
|
497
573
|
return [
|
|
@@ -506,22 +582,22 @@ var re = {
|
|
|
506
582
|
Math.round((c + o) * 255),
|
|
507
583
|
Math.round((l + o) * 255)
|
|
508
584
|
];
|
|
509
|
-
},
|
|
585
|
+
}, ae = (e) => /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.test(e), U = (e) => {
|
|
510
586
|
let t = e.trim().toLowerCase();
|
|
511
|
-
if (t.startsWith("#") || /^[0-9a-f]{3}([0-9a-f]{3})?$/.test(t)) return
|
|
587
|
+
if (t.startsWith("#") || /^[0-9a-f]{3}([0-9a-f]{3})?$/.test(t)) return ae(t) ? re(t) : void 0;
|
|
512
588
|
if (t.startsWith("rgb")) {
|
|
513
589
|
let e = t.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*[\d.]+\s*)?\)/);
|
|
514
|
-
return e ?
|
|
590
|
+
return e ? H(Number.parseInt(e[1], 10), Number.parseInt(e[2], 10), Number.parseInt(e[3], 10)) : void 0;
|
|
515
591
|
}
|
|
516
592
|
if (t.startsWith("hsl")) {
|
|
517
593
|
let e = t.match(/hsla?\(\s*(\d+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*(?:,\s*[\d.]+\s*)?\)/);
|
|
518
594
|
if (!e) return;
|
|
519
|
-
let [n, r, i] =
|
|
520
|
-
return
|
|
595
|
+
let [n, r, i] = ie(Number.parseInt(e[1], 10), Number.parseFloat(e[2]) / 100, Number.parseFloat(e[3]) / 100);
|
|
596
|
+
return H(n, r, i);
|
|
521
597
|
}
|
|
522
|
-
let n =
|
|
598
|
+
let n = ne[t];
|
|
523
599
|
if (n) return n;
|
|
524
|
-
},
|
|
600
|
+
}, W = {
|
|
525
601
|
svg: "svg",
|
|
526
602
|
circle: "circle",
|
|
527
603
|
desc: "desc",
|
|
@@ -532,98 +608,98 @@ var re = {
|
|
|
532
608
|
polygon: "polygon",
|
|
533
609
|
polyline: "polyline",
|
|
534
610
|
stop: "stop"
|
|
535
|
-
},
|
|
611
|
+
}, G = {
|
|
536
612
|
fill: "fill",
|
|
537
613
|
stroke: "stroke"
|
|
538
|
-
},
|
|
614
|
+
}, oe = {
|
|
539
615
|
tiling: [
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
`[${
|
|
549
|
-
`[${
|
|
616
|
+
W.circle,
|
|
617
|
+
W.ellipse,
|
|
618
|
+
W.rect,
|
|
619
|
+
W.line,
|
|
620
|
+
W.path,
|
|
621
|
+
W.polygon,
|
|
622
|
+
W.polyline,
|
|
623
|
+
W.stop,
|
|
624
|
+
`[${G.fill}]`,
|
|
625
|
+
`[${G.stroke}]`
|
|
550
626
|
],
|
|
551
627
|
nonTiling: [
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
`[${
|
|
562
|
-
`[${
|
|
628
|
+
W.circle,
|
|
629
|
+
W.desc,
|
|
630
|
+
W.ellipse,
|
|
631
|
+
W.rect,
|
|
632
|
+
W.line,
|
|
633
|
+
W.path,
|
|
634
|
+
W.polygon,
|
|
635
|
+
W.polyline,
|
|
636
|
+
W.stop,
|
|
637
|
+
`[${G.fill}]`,
|
|
638
|
+
`[${G.stroke}]`
|
|
563
639
|
]
|
|
564
|
-
},
|
|
565
|
-
let t = e.getAttribute(
|
|
640
|
+
}, se = (e) => Array.from(e.querySelectorAll(oe.tiling.map((e) => `*:not(clipPath) > ${e}`).join(", "))), ce = (e) => {
|
|
641
|
+
let t = e.getAttribute(G.stroke);
|
|
566
642
|
return t === "none" || !t ? !1 : t;
|
|
567
|
-
},
|
|
568
|
-
if (!(e === "none" || e === "transparent" || e.startsWith("url("))) return
|
|
569
|
-
},
|
|
570
|
-
let t =
|
|
571
|
-
let n = t.getAttribute("stop-color"), r = t.getAttribute(
|
|
643
|
+
}, K = (e) => {
|
|
644
|
+
if (!(e === "none" || e === "transparent" || e.startsWith("url("))) return U(e);
|
|
645
|
+
}, le = (e) => {
|
|
646
|
+
let t = se(e).reduce((e, t) => {
|
|
647
|
+
let n = t.getAttribute("stop-color"), r = t.getAttribute(G.fill) || "#000", i = ce(t);
|
|
572
648
|
if (r && !n) {
|
|
573
|
-
let t =
|
|
649
|
+
let t = K(r);
|
|
574
650
|
t && e.add(t);
|
|
575
651
|
}
|
|
576
652
|
if (n) {
|
|
577
|
-
let t =
|
|
653
|
+
let t = K(n);
|
|
578
654
|
t && e.add(t);
|
|
579
655
|
}
|
|
580
656
|
if (i) {
|
|
581
|
-
let t =
|
|
657
|
+
let t = K(i);
|
|
582
658
|
t && e.add(t);
|
|
583
659
|
}
|
|
584
660
|
return e;
|
|
585
661
|
}, /* @__PURE__ */ new Set());
|
|
586
662
|
return Array.from(t);
|
|
587
|
-
},
|
|
588
|
-
let t = new
|
|
589
|
-
return t ?
|
|
663
|
+
}, ue = (e) => {
|
|
664
|
+
let t = new N().parseFromString(e, "image/svg+xml").querySelector("svg");
|
|
665
|
+
return t ? le(t) : [];
|
|
590
666
|
};
|
|
591
667
|
//#endregion
|
|
592
668
|
//#region src/glyph/svg-glyph-converter.ts
|
|
593
|
-
function
|
|
669
|
+
function q(e) {
|
|
594
670
|
let t = e.trim(), n = t.startsWith("<svg") || t.startsWith("<?xml"), r = n ? t : `<svg>${t}</svg>`;
|
|
595
671
|
return {
|
|
596
|
-
doc: new
|
|
672
|
+
doc: new N().parseFromString(r, "image/svg+xml"),
|
|
597
673
|
wasWrapped: !n
|
|
598
674
|
};
|
|
599
675
|
}
|
|
600
|
-
function
|
|
676
|
+
function J(e, t) {
|
|
601
677
|
let n = e.querySelector("svg");
|
|
602
678
|
return n ? t ? n.innerHTML : n.outerHTML : "";
|
|
603
679
|
}
|
|
604
|
-
function
|
|
680
|
+
function de(e) {
|
|
605
681
|
let { svgGlyphs: t } = e;
|
|
606
682
|
if (!t || t.size === 0) return [];
|
|
607
683
|
let n = /* @__PURE__ */ new Set();
|
|
608
|
-
for (let [, e] of t) for (let t of
|
|
684
|
+
for (let [, e] of t) for (let t of ue(e.svg)) n.add(t);
|
|
609
685
|
return Array.from(n);
|
|
610
686
|
}
|
|
611
|
-
function
|
|
687
|
+
function fe(e) {
|
|
612
688
|
return !!e && e !== "none" && e !== "transparent" && !e.startsWith("url(");
|
|
613
689
|
}
|
|
614
|
-
function
|
|
615
|
-
let t = new
|
|
690
|
+
function pe(e) {
|
|
691
|
+
let t = new N().parseFromString(e, "image/svg+xml").querySelector("svg");
|
|
616
692
|
return t ? t.innerHTML.trim() : "";
|
|
617
693
|
}
|
|
618
|
-
var
|
|
694
|
+
var me = [
|
|
619
695
|
"fill",
|
|
620
696
|
"stroke",
|
|
621
697
|
"clip-path",
|
|
622
698
|
"mask",
|
|
623
699
|
"filter"
|
|
624
700
|
];
|
|
625
|
-
function
|
|
626
|
-
let { doc: n, wasWrapped: r } =
|
|
701
|
+
function he(e, t) {
|
|
702
|
+
let { doc: n, wasWrapped: r } = q(e), i = /* @__PURE__ */ new Map();
|
|
627
703
|
for (let e of n.querySelectorAll("[id]")) {
|
|
628
704
|
let n = e.getAttribute("id");
|
|
629
705
|
if (!n) continue;
|
|
@@ -631,7 +707,7 @@ function ge(e, t) {
|
|
|
631
707
|
i.set(n, r), e.setAttribute("id", r);
|
|
632
708
|
}
|
|
633
709
|
if (i.size === 0) return e;
|
|
634
|
-
for (let e of
|
|
710
|
+
for (let e of me) for (let t of n.querySelectorAll(`[${e}]`)) {
|
|
635
711
|
let n = t.getAttribute(e);
|
|
636
712
|
if (n) {
|
|
637
713
|
let r = n.replace(/url\(#([^)]+)\)/g, (e, t) => {
|
|
@@ -648,13 +724,13 @@ function ge(e, t) {
|
|
|
648
724
|
a && e.setAttribute(t, `#${a}`);
|
|
649
725
|
}
|
|
650
726
|
}
|
|
651
|
-
return
|
|
727
|
+
return J(n, r);
|
|
652
728
|
}
|
|
653
|
-
var
|
|
729
|
+
var ge = [
|
|
654
730
|
"fill",
|
|
655
731
|
"stroke",
|
|
656
732
|
"stop-color"
|
|
657
|
-
],
|
|
733
|
+
], _e = [
|
|
658
734
|
"path",
|
|
659
735
|
"rect",
|
|
660
736
|
"circle",
|
|
@@ -663,30 +739,30 @@ var _e = [
|
|
|
663
739
|
"polyline",
|
|
664
740
|
"text"
|
|
665
741
|
];
|
|
666
|
-
function
|
|
667
|
-
let { doc: n, wasWrapped: r } =
|
|
668
|
-
for (let [e, n] of Object.entries(t)) i[
|
|
669
|
-
for (let e of
|
|
742
|
+
function ve(e, t) {
|
|
743
|
+
let { doc: n, wasWrapped: r } = q(e), i = {};
|
|
744
|
+
for (let [e, n] of Object.entries(t)) i[U(e) ?? e.toLowerCase()] = n;
|
|
745
|
+
for (let e of ge) for (let t of n.querySelectorAll(`[${e}]`)) {
|
|
670
746
|
let n = t.getAttribute(e);
|
|
671
|
-
if (!n || !
|
|
672
|
-
let r =
|
|
747
|
+
if (!n || !fe(n)) continue;
|
|
748
|
+
let r = U(n), a = r ? i[r] : void 0;
|
|
673
749
|
a && t.setAttribute(e, a.hex);
|
|
674
750
|
}
|
|
675
751
|
let a = i["#000000"];
|
|
676
752
|
if (a) {
|
|
677
|
-
let e =
|
|
753
|
+
let e = _e.map((e) => `${e}:not([fill])`).join(", ");
|
|
678
754
|
for (let t of n.querySelectorAll(e)) t.setAttribute("fill", a.hex);
|
|
679
755
|
}
|
|
680
|
-
return
|
|
756
|
+
return J(n, r);
|
|
681
757
|
}
|
|
682
758
|
//#endregion
|
|
683
759
|
//#region src/helpers/xml.ts
|
|
684
|
-
function
|
|
760
|
+
function ye(e) {
|
|
685
761
|
return e.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
686
762
|
}
|
|
687
763
|
//#endregion
|
|
688
764
|
//#region src/rendering/index.ts
|
|
689
|
-
var
|
|
765
|
+
var Y = (e, t, n) => e / n * t, be = ({ font: e, baselinePath: t, text: n, fontSize: r, spacing: i = T, horizontalAlignment: a = "centre", colourMap: o }) => {
|
|
690
766
|
let { outlineWidth: s, letterSpacing: l, letterSpacingOutline: u } = i, d = new c(t), f = s ? r * s * 2 : 0, p = d.getTotalLength(), m = e.getPaths(n, 0, 0, r, { drawSVG: !1 }), h = e.getPath(n, 0, 0, r, { drawSVG: !1 }).getBoundingBox(), g = h.x1 - f / 2, _ = h.x2 + f / 2 - g, v = s > 0 ? u : l, y = v ? v * r : 0;
|
|
691
767
|
a === "distributed" && (y = n.length === 1 ? 0 : (p - _) / (n.length - 1));
|
|
692
768
|
let b = y * (n.length - 1), x = _ + b, S = 0 - g;
|
|
@@ -695,7 +771,7 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
695
771
|
for (let t = 0; t < m.length; t++) {
|
|
696
772
|
let i = m[t], a = i.getBoundingBox(), s = e.charToGlyph(n[t]), { advanceWidth: c } = s;
|
|
697
773
|
if (!c) throw Error(`No advance width for character: ${n[t]} in font ${e.names.fontFamily}`);
|
|
698
|
-
let { x1: l, x2: u } = s.getBoundingBox(), f =
|
|
774
|
+
let { x1: l, x2: u } = s.getBoundingBox(), f = Y(c, r, e.unitsPerEm), h = Y(u - l, r, e.unitsPerEm), g = S + a.x1;
|
|
699
775
|
if (t > 0 && (g += y * t), g + h > p) throw Error(`TOO_WIDE: character "${n[t]}" at index ${t} exceeds baseline path length (${Math.round(g + h)} > ${Math.round(p)})`);
|
|
700
776
|
let _ = g + f / 2, v = d.getTangentAtLength(_), b = Math.atan2(v.y, v.x) * 180 / Math.PI, x = d.getPointAtLength(g), w = x.x, T = x.y, D = a.x2 - a.x1, O = new E(a.x1 + D / 2, 0), k = ee(new E(a.x1, 0), b, O), A = w - k.X, j = T - k.Y, M = new te();
|
|
701
777
|
M = M.translate(A, j);
|
|
@@ -710,8 +786,8 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
710
786
|
if (e.svgGlyphs) {
|
|
711
787
|
let n = e.svgGlyphs.get(s.index);
|
|
712
788
|
if (n) {
|
|
713
|
-
let e =
|
|
714
|
-
e =
|
|
789
|
+
let e = pe(n.svg);
|
|
790
|
+
e = he(e, `g${s.index}-${t}`), o && (e = ve(e, o)), F = {
|
|
715
791
|
content: e,
|
|
716
792
|
viewBox: n.viewbox,
|
|
717
793
|
x: a.x1,
|
|
@@ -727,7 +803,7 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
727
803
|
matrix: M,
|
|
728
804
|
attributes: {
|
|
729
805
|
d: P,
|
|
730
|
-
"data-character":
|
|
806
|
+
"data-character": ye(n[t]),
|
|
731
807
|
transform: N
|
|
732
808
|
},
|
|
733
809
|
glyphData: {
|
|
@@ -738,93 +814,146 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
738
814
|
});
|
|
739
815
|
}
|
|
740
816
|
return C;
|
|
741
|
-
},
|
|
742
|
-
let n =
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
let e = r * c * 2;
|
|
751
|
-
u = `${t.filter((e) => !e.svgGlyph).map(({ attributes: t }) => `<path d="${t.d}" ${q("fill", a)} ${q("stroke", a)} stroke-width="${e}" stroke-linejoin="round" transform="${t.transform}" data-character="${t["data-character"]}"/>`).join("\n ")}\n ${t.map((e) => J(e, i)).join("\n ")}`;
|
|
752
|
-
} else u = t.map((e) => J(e, i)).join("\n ");
|
|
753
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${s}" viewBox="0 0 ${o} ${s}">${u ? `\n ${u}\n` : ""}</svg>`;
|
|
754
|
-
}, Y = (e) => {
|
|
755
|
-
let { text: t, font: n, physicalSize: r, fontSize: i, boxDimensions: a, spacing: o = T, verticalAlignment: s = "centre", baseline: c = "flat", horizontalAlignment: l = "left", fillColour: u = { hex: "#FFFFFF" }, strokeColour: d = { hex: "#FFFFFF" }, colourMap: f } = e, { width: p, height: m, physicalWidth: h, physicalHeight: g } = a;
|
|
756
|
-
if (p <= 0 || m <= 0) throw Error(`boxDimensions width and height must be positive (got ${p}x${m})`);
|
|
757
|
-
if (h <= 0 || g <= 0) throw Error(`boxDimensions physicalWidth and physicalHeight must be positive (got ${h}x${g})`);
|
|
758
|
-
if (r[0] <= 0) throw Error(`physicalSize height must be positive (got ${r[0]})`);
|
|
759
|
-
let _ = i ?? P({
|
|
760
|
-
font: n,
|
|
761
|
-
boxDimensions: a,
|
|
762
|
-
physicalSize: r,
|
|
817
|
+
}, X = (e) => {
|
|
818
|
+
let { font: t, text: n, boxDimensions: r, physicalSize: i, fontSize: a, spacing: o = T, baseline: s = "flat", horizontalAlignment: c = "left", verticalAlignment: l = "centre", colourMap: u } = e, { width: d, height: f, physicalWidth: p, physicalHeight: m } = r;
|
|
819
|
+
if (d <= 0 || f <= 0) throw Error(`boxDimensions width and height must be positive (got ${d}x${f})`);
|
|
820
|
+
if (p <= 0 || m <= 0) throw Error(`boxDimensions physicalWidth and physicalHeight must be positive (got ${p}x${m})`);
|
|
821
|
+
if (i[0] <= 0) throw Error(`physicalSize height must be positive (got ${i[0]})`);
|
|
822
|
+
let h = a ?? z({
|
|
823
|
+
font: t,
|
|
824
|
+
boxDimensions: r,
|
|
825
|
+
physicalSize: i,
|
|
763
826
|
spacing: o
|
|
764
|
-
}),
|
|
765
|
-
|
|
766
|
-
let
|
|
767
|
-
font:
|
|
827
|
+
}), g = D(s), _ = n.split("\n").filter((e) => e.length > 0);
|
|
828
|
+
_.length || (_ = [""]), (g.type === "curved" || g.type === "custom") && (_ = [_.join("")]);
|
|
829
|
+
let v = _.map((e) => B({
|
|
830
|
+
font: t,
|
|
768
831
|
text: e,
|
|
769
|
-
fontSize:
|
|
832
|
+
fontSize: h,
|
|
770
833
|
spacing: o
|
|
771
|
-
})),
|
|
772
|
-
for (let e = 0; e <
|
|
773
|
-
let
|
|
774
|
-
switch (
|
|
834
|
+
})), y = Math.max(...v.map((e) => e.baseline)), b = y + Math.max(...v.map((e) => e.height - e.baseline)), x = _.length === 1 ? b : b + b * (_.length - 1) * C, S = [];
|
|
835
|
+
for (let e = 0; e < _.length; e++) {
|
|
836
|
+
let n;
|
|
837
|
+
switch (g.type) {
|
|
775
838
|
case "custom":
|
|
776
|
-
O(
|
|
839
|
+
O(g.path), n = g.path;
|
|
777
840
|
break;
|
|
778
841
|
case "curved": {
|
|
779
|
-
let e =
|
|
780
|
-
font:
|
|
781
|
-
text:
|
|
782
|
-
fontSize:
|
|
842
|
+
let e = B({
|
|
843
|
+
font: t,
|
|
844
|
+
text: L(t),
|
|
845
|
+
fontSize: h,
|
|
783
846
|
spacing: o
|
|
784
847
|
});
|
|
785
|
-
|
|
786
|
-
boxDimensions:
|
|
848
|
+
n = j({
|
|
849
|
+
boxDimensions: r,
|
|
787
850
|
baseline: e.baseline,
|
|
788
851
|
textHeight: e.height,
|
|
789
|
-
verticalAlignment:
|
|
852
|
+
verticalAlignment: l
|
|
790
853
|
});
|
|
791
854
|
break;
|
|
792
855
|
}
|
|
793
|
-
case "flat":
|
|
794
|
-
boxDimensions:
|
|
795
|
-
totalTextHeight:
|
|
796
|
-
baseline:
|
|
797
|
-
lineHeight:
|
|
798
|
-
verticalAlignment:
|
|
856
|
+
case "flat": n = k({
|
|
857
|
+
boxDimensions: r,
|
|
858
|
+
totalTextHeight: x,
|
|
859
|
+
baseline: y,
|
|
860
|
+
lineHeight: b,
|
|
861
|
+
verticalAlignment: l,
|
|
799
862
|
lineNumber: e
|
|
800
863
|
});
|
|
801
864
|
}
|
|
802
|
-
|
|
803
|
-
font:
|
|
804
|
-
baselinePath:
|
|
805
|
-
text:
|
|
806
|
-
fontSize:
|
|
865
|
+
S.push(...be({
|
|
866
|
+
font: t,
|
|
867
|
+
baselinePath: n,
|
|
868
|
+
text: _[e],
|
|
869
|
+
fontSize: h,
|
|
807
870
|
spacing: o,
|
|
808
|
-
horizontalAlignment:
|
|
809
|
-
colourMap:
|
|
810
|
-
});
|
|
811
|
-
|
|
871
|
+
horizontalAlignment: c,
|
|
872
|
+
colourMap: u
|
|
873
|
+
}));
|
|
874
|
+
}
|
|
875
|
+
return {
|
|
876
|
+
fontSize: h,
|
|
877
|
+
lines: _,
|
|
878
|
+
paths: S,
|
|
879
|
+
spacing: o,
|
|
880
|
+
tallestHeight: b,
|
|
881
|
+
totalHeight: x,
|
|
882
|
+
maxBaseline: y
|
|
883
|
+
};
|
|
884
|
+
}, xe = (e) => {
|
|
885
|
+
let { font: t, boxDimensions: n, spacing: r = T } = e, { fontSize: i, paths: a, lines: o } = X(e), s = null;
|
|
886
|
+
for (let e of a) {
|
|
887
|
+
let { x1: t, y1: n, x2: r, y2: i } = e.glyphData.bbox, a = new I(t, n, r, i);
|
|
888
|
+
a.transform(e.matrix), s ? s.add(a) : s = a.getBBox();
|
|
812
889
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
890
|
+
if (s && r.outlineWidth > 0) {
|
|
891
|
+
let e = i * r.outlineWidth;
|
|
892
|
+
s = new I(s.x1 - e, s.y1 - e, s.x2 + e, s.y2 + e);
|
|
893
|
+
}
|
|
894
|
+
let c = s ?? new I(0, 0, 0, 0), l = (e) => e / n.width * n.physicalWidth, u = (e) => e / n.height * n.physicalHeight, d = B({
|
|
895
|
+
font: t,
|
|
896
|
+
text: L(t),
|
|
897
|
+
fontSize: i,
|
|
898
|
+
spacing: r
|
|
899
|
+
});
|
|
900
|
+
return {
|
|
901
|
+
fontSize: i,
|
|
902
|
+
bbox: {
|
|
903
|
+
x: c.x,
|
|
904
|
+
y: c.y,
|
|
905
|
+
width: c.width,
|
|
906
|
+
height: c.height
|
|
907
|
+
},
|
|
908
|
+
physicalWidth: l(c.width),
|
|
909
|
+
physicalHeight: u(c.height),
|
|
910
|
+
physicalUnits: n.physicalUnits,
|
|
911
|
+
physicalCapHeight: u(d.height),
|
|
912
|
+
lines: o.map((e) => {
|
|
913
|
+
let n = B({
|
|
914
|
+
font: t,
|
|
915
|
+
text: e,
|
|
916
|
+
fontSize: i,
|
|
917
|
+
spacing: r
|
|
918
|
+
});
|
|
919
|
+
return {
|
|
920
|
+
text: e,
|
|
921
|
+
width: n.width,
|
|
922
|
+
height: n.height,
|
|
923
|
+
baseline: n.baseline
|
|
924
|
+
};
|
|
925
|
+
})
|
|
926
|
+
};
|
|
927
|
+
}, Se = { hex: "#FFFFFF" }, Z = (e, t) => {
|
|
928
|
+
let n = `data-${e}-colour-url`, r = [`${e}="${t.hex}"`];
|
|
929
|
+
return t.reference && r.push(`${n}="${t.reference}"`), r.join(" ");
|
|
930
|
+
}, Ce = (e, t) => {
|
|
931
|
+
let { attributes: n, svgGlyph: r } = e;
|
|
932
|
+
return r ? `<g transform="${n.transform}" data-character="${n["data-character"]}"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="${r.viewBox}" width="${r.width}" height="${r.height}" x="${r.x}" y="${r.y}" data-glyph-index="${r.glyphIndex}">${r.content}</svg></g>` : `<path d="${n.d}" ${Z("fill", t)} transform="${n.transform}" data-character="${n["data-character"]}"/>`;
|
|
933
|
+
}, we = ({ boxDimensions: e, paths: t, spacing: n = T, fontSize: r = 0, fillColour: i = Se, strokeColour: a = Se }) => {
|
|
934
|
+
let { width: o, height: s } = e, { outlineWidth: c } = n, l = c > 0 && r > 0, u;
|
|
935
|
+
if (l) {
|
|
936
|
+
let e = r * c * 2;
|
|
937
|
+
u = `${t.filter((e) => !e.svgGlyph).map(({ attributes: t }) => `<path d="${t.d}" ${Z("fill", a)} ${Z("stroke", a)} stroke-width="${e}" stroke-linejoin="round" transform="${t.transform}" data-character="${t["data-character"]}"/>`).join("\n ")}\n ${t.map((e) => Ce(e, i)).join("\n ")}`;
|
|
938
|
+
} else u = t.map((e) => Ce(e, i)).join("\n ");
|
|
939
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${s}" viewBox="0 0 ${o} ${s}">${u ? `\n ${u}\n` : ""}</svg>`;
|
|
940
|
+
}, Q = (e) => {
|
|
941
|
+
let { boxDimensions: t, fillColour: n = { hex: "#FFFFFF" }, strokeColour: r = { hex: "#FFFFFF" } } = e, { fontSize: i, paths: a, spacing: o } = X(e);
|
|
942
|
+
return we({
|
|
943
|
+
boxDimensions: t,
|
|
944
|
+
paths: a,
|
|
816
945
|
spacing: o,
|
|
817
|
-
fontSize:
|
|
818
|
-
fillColour:
|
|
819
|
-
strokeColour:
|
|
946
|
+
fontSize: i,
|
|
947
|
+
fillColour: n,
|
|
948
|
+
strokeColour: r
|
|
820
949
|
});
|
|
821
|
-
},
|
|
950
|
+
}, Te = 100, Ee = (e) => {
|
|
822
951
|
let t = e.split("\n").filter((e) => e.length > 0);
|
|
823
952
|
return t.length ? t : [""];
|
|
824
|
-
},
|
|
825
|
-
let o =
|
|
953
|
+
}, De = (e) => e.split("\n").filter((e) => e.length > 0).join(""), Oe = (e, t, n, r, i, a) => {
|
|
954
|
+
let o = B({
|
|
826
955
|
font: e,
|
|
827
|
-
text:
|
|
956
|
+
text: L(e),
|
|
828
957
|
fontSize: n,
|
|
829
958
|
spacing: r
|
|
830
959
|
}), s = {
|
|
@@ -832,7 +961,7 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
832
961
|
baseline: o.baseline,
|
|
833
962
|
textHeight: o.height,
|
|
834
963
|
verticalAlignment: a
|
|
835
|
-
}, l = new c(j(s)).getTotalLength(), { curveTop: u, curveBottom: d } = A(s), f =
|
|
964
|
+
}, l = new c(j(s)).getTotalLength(), { curveTop: u, curveBottom: d } = A(s), f = B({
|
|
836
965
|
font: e,
|
|
837
966
|
text: t,
|
|
838
967
|
fontSize: n,
|
|
@@ -842,36 +971,36 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
842
971
|
width: f.width <= l,
|
|
843
972
|
height: p >= 0 && m <= i.height
|
|
844
973
|
};
|
|
845
|
-
},
|
|
846
|
-
let s =
|
|
974
|
+
}, $ = (e) => e.width && e.height, ke = (e) => e.width ? "height" : "width", Ae = .01, je = 60, Me = ({ font: e, text: t, boxDimensions: n, spacing: r, verticalAlignment: i, minFontSize: a, maxFontSize: o }) => {
|
|
975
|
+
let s = De(t);
|
|
847
976
|
if (!s.length) return {
|
|
848
977
|
fontSize: o,
|
|
849
978
|
fits: !0,
|
|
850
979
|
boundBy: "requestedSize"
|
|
851
980
|
};
|
|
852
|
-
let c = (t) =>
|
|
853
|
-
if (
|
|
981
|
+
let c = (t) => Oe(e, s, t, r, n, i), l = c(a);
|
|
982
|
+
if (!$(l)) return {
|
|
854
983
|
fontSize: a,
|
|
855
984
|
fits: !1,
|
|
856
|
-
boundBy:
|
|
985
|
+
boundBy: ke(l)
|
|
857
986
|
};
|
|
858
|
-
if (
|
|
987
|
+
if ($(c(o))) return {
|
|
859
988
|
fontSize: o,
|
|
860
989
|
fits: !0,
|
|
861
990
|
boundBy: "requestedSize"
|
|
862
991
|
};
|
|
863
992
|
let u = a, d = o, f = 0;
|
|
864
|
-
for (; d - u >
|
|
993
|
+
for (; d - u > Ae && f < je;) {
|
|
865
994
|
let e = (u + d) / 2;
|
|
866
|
-
|
|
995
|
+
$(c(e)) ? u = e : d = e, f++;
|
|
867
996
|
}
|
|
868
997
|
return {
|
|
869
998
|
fontSize: u,
|
|
870
999
|
fits: !0,
|
|
871
|
-
boundBy:
|
|
1000
|
+
boundBy: ke(c(d))
|
|
872
1001
|
};
|
|
873
|
-
},
|
|
874
|
-
let { font: t, text: n, boxDimensions: r, size: i, spacing: a = T, baseline: o = "flat", verticalAlignment: s = "centre" } = e, l = i.mode === "fitToBox" ? i.maxFontSize : i.mode === "fontSize" ? i.fontSize :
|
|
1002
|
+
}, Ne = (e) => {
|
|
1003
|
+
let { font: t, text: n, boxDimensions: r, size: i, spacing: a = T, baseline: o = "flat", verticalAlignment: s = "centre" } = e, l = i.mode === "fitToBox" ? i.maxFontSize : i.mode === "fontSize" ? i.fontSize : z({
|
|
875
1004
|
font: t,
|
|
876
1005
|
boxDimensions: r,
|
|
877
1006
|
physicalSize: i.physicalSize,
|
|
@@ -883,7 +1012,7 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
883
1012
|
boundBy: "requestedSize"
|
|
884
1013
|
};
|
|
885
1014
|
let u = D(o);
|
|
886
|
-
if (u.type === "curved") return
|
|
1015
|
+
if (u.type === "curved") return Me({
|
|
887
1016
|
font: t,
|
|
888
1017
|
text: n,
|
|
889
1018
|
boxDimensions: r,
|
|
@@ -892,14 +1021,14 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
892
1021
|
minFontSize: i.mode === "fitToBox" ? i.minFontSize : l,
|
|
893
1022
|
maxFontSize: l
|
|
894
1023
|
});
|
|
895
|
-
let d =
|
|
1024
|
+
let d = Ee(n);
|
|
896
1025
|
u.type === "custom" && (d = [d.join("")]);
|
|
897
|
-
let f = d.map((e) =>
|
|
1026
|
+
let f = d.map((e) => B({
|
|
898
1027
|
font: t,
|
|
899
1028
|
text: e,
|
|
900
|
-
fontSize:
|
|
1029
|
+
fontSize: Te,
|
|
901
1030
|
spacing: a
|
|
902
|
-
})), p = Math.max(...f.map((e) => e.baseline)) + Math.max(...f.map((e) => e.height - e.baseline)), m = d.length === 1 ? p : p + p * (d.length - 1) * C, h = Math.max(...f.map((e) => e.width)), g = (u.type === "custom" ? new c(u.path).getTotalLength() : r.width) / h, _ = r.height / m, v = g <= _ ? "width" : "height", y =
|
|
1031
|
+
})), p = Math.max(...f.map((e) => e.baseline)) + Math.max(...f.map((e) => e.height - e.baseline)), m = d.length === 1 ? p : p + p * (d.length - 1) * C, h = Math.max(...f.map((e) => e.width)), g = (u.type === "custom" ? new c(u.path).getTotalLength() : r.width) / h, _ = r.height / m, v = g <= _ ? "width" : "height", y = Te * Math.min(g, _);
|
|
903
1032
|
return i.mode === "fitToBox" ? y < i.minFontSize ? {
|
|
904
1033
|
fontSize: i.minFontSize,
|
|
905
1034
|
fits: !1,
|
|
@@ -921,10 +1050,10 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
921
1050
|
fits: !1,
|
|
922
1051
|
boundBy: v
|
|
923
1052
|
};
|
|
924
|
-
},
|
|
1053
|
+
}, Pe = (e) => {
|
|
925
1054
|
let t = e.text, n = t, r = 0, i = 0;
|
|
926
1055
|
for (;;) {
|
|
927
|
-
let a =
|
|
1056
|
+
let a = Ne({
|
|
928
1057
|
...e,
|
|
929
1058
|
text: n
|
|
930
1059
|
});
|
|
@@ -942,15 +1071,15 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
942
1071
|
i += n.length - e.length, n = e;
|
|
943
1072
|
}
|
|
944
1073
|
}
|
|
945
|
-
},
|
|
1074
|
+
}, Fe = async (e) => {
|
|
946
1075
|
let { fontUrl: t, fontSizeFallback: n, ...r } = e, i = await x(t, !!r.colourMap);
|
|
947
1076
|
try {
|
|
948
|
-
return
|
|
1077
|
+
return Q({
|
|
949
1078
|
...r,
|
|
950
1079
|
font: i
|
|
951
1080
|
});
|
|
952
1081
|
} catch (e) {
|
|
953
|
-
if (n != null && e instanceof Error && e.message.startsWith("TOO_WIDE")) return
|
|
1082
|
+
if (n != null && e instanceof Error && e.message.startsWith("TOO_WIDE")) return Q({
|
|
954
1083
|
...r,
|
|
955
1084
|
font: i,
|
|
956
1085
|
fontSize: n
|
|
@@ -959,4 +1088,4 @@ var G = (e, t, n) => e / n * t, xe = ({ font: e, baselinePath: t, text: n, fontS
|
|
|
959
1088
|
}
|
|
960
1089
|
};
|
|
961
1090
|
//#endregion
|
|
962
|
-
export { S as DEFAULT_OUTLINE_FACTOR, T as DEFAULT_SPACING, C as LINE_HEIGHT,
|
|
1091
|
+
export { S as DEFAULT_OUTLINE_FACTOR, T as DEFAULT_SPACING, C as LINE_HEIGHT, Pe as fitAndTruncateTextToBox, j as generateCurvedBaseline, k as generateFlatBaseline, p as getFontCache, de as getFontColours, z as getFontSizeFromPhysicalSize, Ne as getFontSizeToFitBox, Fe as getRenderedText, B as getTextMetricsAtFontSize, X as layoutText, x as loadFont, xe as measureText, D as normaliseBaselineOption, Q as renderText, O as validateCustomBaselinePath };
|