modern-text 0.2.20 → 0.2.22
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.cjs +82 -64
- package/dist/index.d.cts +14 -6
- package/dist/index.d.mts +14 -6
- package/dist/index.d.ts +14 -6
- package/dist/index.js +2 -2
- package/dist/index.mjs +83 -66
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoundingBox, Path2D, Matrix3, Vector2,
|
|
1
|
+
import { BoundingBox, Path2D, Matrix3, Vector2, parseSvg, parseSvgToDom } from 'modern-path2d';
|
|
2
2
|
import { fonts, Woff, Ttf } from 'modern-font';
|
|
3
3
|
export * from 'modern-font';
|
|
4
4
|
|
|
@@ -67,7 +67,7 @@ function drawPath(options) {
|
|
|
67
67
|
shadowColor: options.shadowColor
|
|
68
68
|
};
|
|
69
69
|
if (clipRect) {
|
|
70
|
-
ctx.rect(clipRect.
|
|
70
|
+
ctx.rect(clipRect.left, clipRect.top, clipRect.width, clipRect.height);
|
|
71
71
|
ctx.clip();
|
|
72
72
|
ctx.beginPath();
|
|
73
73
|
}
|
|
@@ -187,8 +187,8 @@ class Character {
|
|
|
187
187
|
return this;
|
|
188
188
|
}
|
|
189
189
|
const { unitsPerEm, ascender, descender, os2, post } = font;
|
|
190
|
-
const { content, computedStyle, boundingBox
|
|
191
|
-
const {
|
|
190
|
+
const { content, computedStyle, boundingBox } = this;
|
|
191
|
+
const { height } = boundingBox;
|
|
192
192
|
const { fontSize } = computedStyle;
|
|
193
193
|
const rate = unitsPerEm / fontSize;
|
|
194
194
|
const glyphWidth = font.getAdvanceWidth(content, fontSize);
|
|
@@ -206,8 +206,6 @@ class Character {
|
|
|
206
206
|
this.yStrikeoutSize = yStrikeoutSize;
|
|
207
207
|
this.baseline = baseline;
|
|
208
208
|
this.centerDiviation = 0.5 * height - baseline;
|
|
209
|
-
this.glyphBox = isVertical ? new BoundingBox(left, top, glyphHeight, glyphWidth) : new BoundingBox(left, top, glyphWidth, glyphHeight);
|
|
210
|
-
this.centerPoint = this.glyphBox.getCenterPoint();
|
|
211
209
|
return this;
|
|
212
210
|
}
|
|
213
211
|
updatePath() {
|
|
@@ -289,6 +287,8 @@ class Character {
|
|
|
289
287
|
strokeWidth: computedStyle.textStrokeWidth ? computedStyle.textStrokeWidth * fontSize * 0.03 : 0
|
|
290
288
|
};
|
|
291
289
|
this.path = path;
|
|
290
|
+
this.glyphBox = this.getGlyphBoundingBox();
|
|
291
|
+
this.center = this.glyphBox.getCenterPoint();
|
|
292
292
|
return this;
|
|
293
293
|
}
|
|
294
294
|
update() {
|
|
@@ -377,11 +377,11 @@ class Character {
|
|
|
377
377
|
return cmd;
|
|
378
378
|
});
|
|
379
379
|
}
|
|
380
|
-
|
|
380
|
+
getGlyphMinMax(min, max) {
|
|
381
381
|
return this.path.getMinMax(min, max);
|
|
382
382
|
}
|
|
383
|
-
|
|
384
|
-
return this.path.getBoundingBox();
|
|
383
|
+
getGlyphBoundingBox(withStyle) {
|
|
384
|
+
return this.path.getBoundingBox(withStyle);
|
|
385
385
|
}
|
|
386
386
|
drawTo(ctx, config = {}) {
|
|
387
387
|
drawPath({
|
|
@@ -501,7 +501,7 @@ class Effector extends Feature {
|
|
|
501
501
|
const boxes = [];
|
|
502
502
|
characters.forEach((character) => {
|
|
503
503
|
effects?.forEach((style) => {
|
|
504
|
-
const aabb = character.
|
|
504
|
+
const aabb = character.glyphBox.clone();
|
|
505
505
|
const m = this.getTransform2D(style);
|
|
506
506
|
tempV1.set(aabb.left, aabb.top);
|
|
507
507
|
tempV1.applyMatrix3(m);
|
|
@@ -548,11 +548,27 @@ var __publicField$1 = (obj, key, value) => {
|
|
|
548
548
|
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
549
549
|
return value;
|
|
550
550
|
};
|
|
551
|
-
|
|
551
|
+
const defaultHighlightRefer = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MiIgaGVpZ2h0PSI3MiIgdmlld0JveD0iMCAwIDcyIDcyIiBmaWxsPSJub25lIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMyLjQwMjkgMjhIMzUuMTU5NFYzMy4xNzcxQzM1Ljk4MjEgMzIuMzExNSAzNi45NzEgMzEuODczNyAzOC4wOTQ4IDMxLjg3MzdDMzkuNjY3NiAzMS44NzM3IDQwLjkxNjYgMzIuNDI5NSA0MS44MzkgMzMuNTQzN0w0MS44NDAzIDMzLjU0NTNDNDIuNjcxNyAzNC41NzA1IDQzLjA5MTUgMzUuODU1OSA0My4wOTE1IDM3LjM4NzdDNDMuMDkxNSAzOC45NzYxIDQyLjY3MjkgNDAuMzAyOCA0MS44MTgzIDQxLjMzMDRMNDEuODE3MSA0MS4zMzE4QzQwLjg3MzEgNDIuNDQ2MSAzOS41ODMyIDQzIDM3Ljk3MjEgNDNDMzYuNzQ3NyA0MyAzNS43NDg4IDQyLjY1OTkgMzQuOTk1OCA0MS45NjkzVjQyLjcyNDdIMzIuNDAyOVYyOFpNMzcuNTQyOCAzNC4wOTI0QzM2Ljg1NDkgMzQuMDkyNCAzNi4zMDE0IDM0LjM1NjEgMzUuODQ4NyAzNC45MDA0TDM1Ljg0NTIgMzQuOTA0NkMzNS4zMzU4IDM1LjQ4NTMgMzUuMDc3NiAzNi4yOTc2IDM1LjA3NzYgMzcuMzQ4NFYzNy41MDU3QzM1LjA3NzYgMzguNDY0IDM1LjI3NzIgMzkuMjQ0MyAzNS42OTQzIDM5LjgyNzlDMzYuMTQ0MSA0MC40NTg3IDM2Ljc3MjYgNDAuNzgxMyAzNy42MjQ1IDQwLjc4MTNDMzguNTg3NCA0MC43ODEzIDM5LjI3MDcgNDAuNDUyNyAzOS43MTUyIDM5LjgxMjdDNDAuMDcyOCAzOS4yNjg0IDQwLjI3MzcgMzguNDY3MyA0MC4yNzM3IDM3LjM4NzdDNDAuMjczNyAzNi4zMTA1IDQwLjA1MzMgMzUuNTMxMyAzOS42NzgzIDM1LjAwNzdDMzkuMjM3MSAzNC40MDcxIDM4LjUzNDIgMzQuMDkyNCAzNy41NDI4IDM0LjA5MjRaIiBmaWxsPSIjMjIyNTI5Ii8+PHBhdGggZD0iTTQ5Ljg2MTQgMzEuODczN0M0OC4xNTM1IDMxLjg3MzcgNDYuODAxNiAzMi40MjM5IDQ1LjgzNDggMzMuNTM5MkM0NC45MzcgMzQuNTQ3MiA0NC40OTY2IDM1Ljg1NiA0NC40OTY2IDM3LjQyN0M0NC40OTY2IDM5LjAzNjggNDQuOTM2NyA0MC4zNjU5IDQ1Ljg1NTkgNDEuMzk0M0M0Ni44MDMxIDQyLjQ3MDYgNDguMTM0OCA0MyA0OS44MjA1IDQzQzUxLjIyNiA0MyA1Mi4zODI2IDQyLjY1NjMgNTMuMjQ3OSA0MS45Njk3QzU0LjEzNTkgNDEuMjYxNCA1NC43MDYxIDQwLjE4ODcgNTQuOTU3MyAzOC43NzkxTDU1IDM4LjUzOTdINTIuMjQ4NEw1Mi4yMjU5IDM4LjcyMDFDNTIuMTM3OSAzOS40MjUxIDUxLjg5MjUgMzkuOTI3OCA1MS41MTA5IDQwLjI1NThDNTEuMTI5NSA0MC41ODM1IDUwLjU4MzEgNDAuNzYxNiA0OS44NDA5IDQwLjc2MTZDNDkuMDAwMSA0MC43NjE2IDQ4LjM5NDkgNDAuNDcxNSA0Ny45OTA3IDM5LjkyMzdMNDcuOTg3NCAzOS45MTk0QzQ3LjUzNTYgMzkuMzQwMSA0Ny4zMTQ0IDM4LjUwNjIgNDcuMzE0NCAzNy40MDc0QzQ3LjMxNDQgMzYuMzMyMiA0Ny41NTQ0IDM1LjUxNzcgNDguMDA1OCAzNC45NTY4TDQ4LjAwNzggMzQuOTU0M0M0OC40NTM3IDM0LjM4MjUgNDkuMDYxOCAzNC4xMTIxIDQ5Ljg2MTQgMzQuMTEyMUM1MC41MjMgMzQuMTEyMSA1MS4wNDUxIDM0LjI2MTUgNTEuNDI3MiAzNC41NDA3QzUxLjc4ODQgMzQuODE5NCA1Mi4wNTMgMzUuMjQ0NyA1Mi4xODgxIDM1Ljg1NzFMNTIuMjIzOSAzNi4wMTk0SDU0Ljk1NDhMNTQuOTE3IDM1Ljc4MzVDNTQuNzA2MyAzNC40NjYgNTQuMTUzNiAzMy40NzAxIDUzLjI2MzQgMzIuODAxOUw1My4yNjAyIDMyLjc5OTVDNTIuMzk1MSAzMi4xNzU1IDUxLjI2MjEgMzEuODczNyA0OS44NjE0IDMxLjg3MzdaIiBmaWxsPSIjMjIyNTI5Ii8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNS43NTYxIDI4LjI3NTNIMjIuNzQ0TDE3IDQyLjcyNDdIMjAuMDE0MUwyMS4zNDI5IDM5LjIwNDlIMjcuMTU3MkwyOC40ODYgNDIuNzI0N0gzMS41MDAxTDI1Ljc1NjEgMjguMjc1M1pNMjIuMjEyNSAzNi45MDc2TDI0LjI1OTYgMzEuNDUzOUwyNi4yODg1IDM2LjkwNzZIMjIuMjEyNVoiIGZpbGw9IiMyMjI1MjkiLz48L3N2Zz4=";
|
|
552
|
+
const _Highlighter = class _Highlighter extends Feature {
|
|
552
553
|
constructor() {
|
|
553
554
|
super(...arguments);
|
|
554
555
|
__publicField$1(this, "paths", []);
|
|
555
556
|
}
|
|
557
|
+
static get refer() {
|
|
558
|
+
return this._refer;
|
|
559
|
+
}
|
|
560
|
+
static set refer(refer) {
|
|
561
|
+
this._refer = refer;
|
|
562
|
+
this.parsedRefer = parseSvg(refer);
|
|
563
|
+
}
|
|
564
|
+
getReferBoundingBox() {
|
|
565
|
+
const max = Vector2.MIN;
|
|
566
|
+
const min = Vector2.MAX;
|
|
567
|
+
_Highlighter.parsedRefer.forEach((path) => {
|
|
568
|
+
path.getMinMax(min, max);
|
|
569
|
+
});
|
|
570
|
+
return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
|
|
571
|
+
}
|
|
556
572
|
getBoundingBox() {
|
|
557
573
|
if (!this.paths.length) {
|
|
558
574
|
return void 0;
|
|
@@ -570,7 +586,7 @@ class Highlighter extends Feature {
|
|
|
570
586
|
characters.forEach((character) => {
|
|
571
587
|
const highlight = character.parent.highlight;
|
|
572
588
|
if (highlight?.url) {
|
|
573
|
-
if (prevHighlight?.url === highlight.url &&
|
|
589
|
+
if (prevHighlight?.url === highlight.url && prevHighlight?.strokeWidth === highlight.strokeWidth && prevHighlight?.repeatXByFontsize === highlight.repeatXByFontsize && prevHighlight?.overflowXHidden === highlight.overflowXHidden && group.length && group[0].boundingBox.top === character.boundingBox.top && group[0].fontSize === character.fontSize) {
|
|
574
590
|
group.push(character);
|
|
575
591
|
} else {
|
|
576
592
|
group = [];
|
|
@@ -582,8 +598,8 @@ class Highlighter extends Feature {
|
|
|
582
598
|
});
|
|
583
599
|
this.paths = groups.filter((characters2) => characters2.length).map((characters2) => {
|
|
584
600
|
return {
|
|
585
|
-
|
|
586
|
-
box: BoundingBox.from(...characters2.map((c) => c.
|
|
601
|
+
highlight: characters2[0].parent.highlight,
|
|
602
|
+
box: BoundingBox.from(...characters2.map((c) => c.glyphBox)),
|
|
587
603
|
baseline: Math.max(...characters2.map((c) => c.baseline)),
|
|
588
604
|
fontSize: characters2[0].fontSize
|
|
589
605
|
};
|
|
@@ -597,60 +613,57 @@ class Highlighter extends Feature {
|
|
|
597
613
|
paths.forEach((path) => path.getMinMax(min, max));
|
|
598
614
|
return {
|
|
599
615
|
paths,
|
|
600
|
-
box: new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y)
|
|
601
|
-
viewBox: new BoundingBox(...svg.getAttribute("viewBox").split(" ").map(Number))
|
|
616
|
+
box: new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y)
|
|
602
617
|
};
|
|
603
618
|
}
|
|
604
619
|
_parseGroup(group) {
|
|
605
|
-
const {
|
|
606
|
-
const {
|
|
607
|
-
|
|
620
|
+
const { highlight, box: groupBox, fontSize } = group;
|
|
621
|
+
const {
|
|
622
|
+
strokeWidth = 1,
|
|
623
|
+
repeatXByFontsize = 0,
|
|
624
|
+
overflowXHidden = Boolean(repeatXByFontsize)
|
|
625
|
+
} = highlight;
|
|
626
|
+
const { box, paths } = this._parseSvg(highlight.url);
|
|
608
627
|
const result = [];
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
if (type === 0) {
|
|
625
|
-
const offset = {
|
|
626
|
-
x: groupBox.left - fontSize * 0.2,
|
|
627
|
-
y: groupBox.top
|
|
628
|
-
};
|
|
629
|
-
const scaleX = (groupBox.width + fontSize * 0.2 * 2) / box.width;
|
|
630
|
-
const scaleY = groupBox.height / box.height;
|
|
631
|
-
const m = new Matrix3().translate(-box.x, -box.y).scale(scaleX, scaleY).translate(offset.x, offset.y);
|
|
628
|
+
const referBoundingBox = this.getReferBoundingBox();
|
|
629
|
+
const scale = {
|
|
630
|
+
x: repeatXByFontsize ? fontSize * repeatXByFontsize * (box.width / referBoundingBox.width) / box.width : groupBox.width * (box.width / referBoundingBox.width) / box.width,
|
|
631
|
+
y: groupBox.height * (box.height / referBoundingBox.height) / box.height
|
|
632
|
+
};
|
|
633
|
+
const styleScale = fontSize / box.width * 2;
|
|
634
|
+
const unitWidth = box.width * scale.x;
|
|
635
|
+
const total = Math.ceil(groupBox.width / unitWidth);
|
|
636
|
+
const offset = {
|
|
637
|
+
x: (box.left - referBoundingBox.left) * scale.x,
|
|
638
|
+
y: (box.top - referBoundingBox.top) * scale.y
|
|
639
|
+
};
|
|
640
|
+
const transform = new Matrix3().translate(-box.left, -box.top).scale(scale.x, scale.y).translate(groupBox.left, groupBox.top).translate(offset.x, offset.y);
|
|
641
|
+
for (let i = 0; i < total; i++) {
|
|
642
|
+
const _transform = transform.clone().translate(i * unitWidth, 0);
|
|
632
643
|
paths.forEach((original) => {
|
|
633
|
-
const path = original.clone().transform(
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
644
|
+
const path = original.clone().transform(_transform);
|
|
645
|
+
if (path.style.strokeWidth) {
|
|
646
|
+
path.style.strokeWidth *= styleScale * strokeWidth;
|
|
647
|
+
}
|
|
648
|
+
if (path.style.strokeMiterlimit) {
|
|
649
|
+
path.style.strokeMiterlimit *= styleScale;
|
|
650
|
+
}
|
|
651
|
+
if (path.style.strokeDashoffset) {
|
|
652
|
+
path.style.strokeDashoffset *= styleScale;
|
|
653
|
+
}
|
|
654
|
+
if (path.style.strokeDasharray) {
|
|
655
|
+
path.style.strokeDasharray = path.style.strokeDasharray.map((v) => v * styleScale);
|
|
656
|
+
}
|
|
657
|
+
result.push({
|
|
658
|
+
clipRect: overflowXHidden ? new BoundingBox(
|
|
659
|
+
groupBox.left + offset.x * 2,
|
|
660
|
+
groupBox.top - groupBox.height,
|
|
661
|
+
groupBox.width - offset.x * 2,
|
|
662
|
+
groupBox.height * 3
|
|
663
|
+
) : void 0,
|
|
664
|
+
path
|
|
652
665
|
});
|
|
653
|
-
}
|
|
666
|
+
});
|
|
654
667
|
}
|
|
655
668
|
return result;
|
|
656
669
|
}
|
|
@@ -665,7 +678,10 @@ class Highlighter extends Feature {
|
|
|
665
678
|
});
|
|
666
679
|
return this;
|
|
667
680
|
}
|
|
668
|
-
}
|
|
681
|
+
};
|
|
682
|
+
__publicField$1(_Highlighter, "_refer", defaultHighlightRefer);
|
|
683
|
+
__publicField$1(_Highlighter, "parsedRefer", parseSvg(_Highlighter._refer));
|
|
684
|
+
let Highlighter = _Highlighter;
|
|
669
685
|
|
|
670
686
|
class Measurer extends Feature {
|
|
671
687
|
_styleToDomStyle(style) {
|
|
@@ -1076,13 +1092,14 @@ class Text {
|
|
|
1076
1092
|
this.boundingBox = boundingBox;
|
|
1077
1093
|
const characters = this.characters;
|
|
1078
1094
|
characters.forEach((c) => c.update());
|
|
1079
|
-
this.highlighter.highlight();
|
|
1080
1095
|
if (this.deformation) {
|
|
1081
1096
|
this.deformer.deform();
|
|
1097
|
+
} else {
|
|
1098
|
+
this.highlighter.highlight();
|
|
1082
1099
|
}
|
|
1083
1100
|
const min = Vector2.MAX;
|
|
1084
1101
|
const max = Vector2.MIN;
|
|
1085
|
-
characters.forEach((c) => c.
|
|
1102
|
+
characters.forEach((c) => c.getGlyphMinMax(min, max));
|
|
1086
1103
|
this.renderBoundingBox = new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
|
|
1087
1104
|
return this;
|
|
1088
1105
|
}
|
|
@@ -1119,4 +1136,4 @@ class Text {
|
|
|
1119
1136
|
}
|
|
1120
1137
|
}
|
|
1121
1138
|
|
|
1122
|
-
export { Character, Deformer, Effector, Fragment, Highlighter, Measurer, Paragraph, Parser, Reflector, Renderer2D, Text, defaultTextStyles, drawPath, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
|
|
1139
|
+
export { Character, Deformer, Effector, Fragment, Highlighter, Measurer, Paragraph, Parser, Reflector, Renderer2D, Text, defaultHighlightRefer, defaultTextStyles, drawPath, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
|