@effing/canvas 0.18.5 → 0.18.6
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 +222 -59
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -74,8 +74,28 @@ function getScratchCtx() {
|
|
|
74
74
|
}
|
|
75
75
|
return scratchCtx;
|
|
76
76
|
}
|
|
77
|
+
var GENERIC_FAMILIES = /* @__PURE__ */ new Set([
|
|
78
|
+
"serif",
|
|
79
|
+
"sans-serif",
|
|
80
|
+
"monospace",
|
|
81
|
+
"cursive",
|
|
82
|
+
"fantasy",
|
|
83
|
+
"system-ui",
|
|
84
|
+
"ui-serif",
|
|
85
|
+
"ui-sans-serif",
|
|
86
|
+
"ui-monospace",
|
|
87
|
+
"ui-rounded",
|
|
88
|
+
"math",
|
|
89
|
+
"emoji",
|
|
90
|
+
"fangsong"
|
|
91
|
+
]);
|
|
92
|
+
function quoteFontFamily(family) {
|
|
93
|
+
if (!family || GENERIC_FAMILIES.has(family)) return family;
|
|
94
|
+
return `"${family}"`;
|
|
95
|
+
}
|
|
77
96
|
function setFont(ctx, fontSize, fontFamily, fontWeight = 400, fontStyle = "normal") {
|
|
78
|
-
|
|
97
|
+
const quoted = fontFamily.split(",").map((f) => quoteFontFamily(f.trim())).join(", ");
|
|
98
|
+
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${quoted}`;
|
|
79
99
|
}
|
|
80
100
|
function measureText(text, fontSize, fontFamily, fontWeight = 400, fontStyle = "normal", ctx) {
|
|
81
101
|
const c = ctx ?? getScratchCtx();
|
|
@@ -678,10 +698,7 @@ function drawRect(ctx, x, y, width, height, style) {
|
|
|
678
698
|
drawBorders(ctx, x, y, width, height, style, borderRadius);
|
|
679
699
|
}
|
|
680
700
|
function resolveRadius(v, width, height) {
|
|
681
|
-
if (typeof v === "string"
|
|
682
|
-
const pct = parseFloat(v) / 100;
|
|
683
|
-
return pct * Math.min(width, height);
|
|
684
|
-
}
|
|
701
|
+
if (typeof v === "string") return parseCSSLength(v, Math.min(width, height));
|
|
685
702
|
return toNumber(v);
|
|
686
703
|
}
|
|
687
704
|
function getBorderRadius(style, width, height) {
|
|
@@ -793,12 +810,6 @@ function drawBoxShadow(ctx, x, y, width, height, boxShadow, borderRadius) {
|
|
|
793
810
|
ctx.fill();
|
|
794
811
|
ctx.restore();
|
|
795
812
|
}
|
|
796
|
-
function toNumber(v) {
|
|
797
|
-
if (typeof v === "number") return v;
|
|
798
|
-
if (v === void 0 || v === null) return 0;
|
|
799
|
-
const n = parseFloat(String(v));
|
|
800
|
-
return isNaN(n) ? 0 : n;
|
|
801
|
-
}
|
|
802
813
|
|
|
803
814
|
// src/jsx/draw/svg.ts
|
|
804
815
|
import { Path2D } from "@napi-rs/canvas";
|
|
@@ -811,6 +822,97 @@ function mergeStyleIntoProps(props) {
|
|
|
811
822
|
if (!style) return props;
|
|
812
823
|
return { ...props, ...style };
|
|
813
824
|
}
|
|
825
|
+
function collectDefs(children) {
|
|
826
|
+
const defs = /* @__PURE__ */ new Map();
|
|
827
|
+
for (const child of children) {
|
|
828
|
+
if (child.type !== "defs") continue;
|
|
829
|
+
const defsChildren = normalizeChildren(child);
|
|
830
|
+
for (const def of defsChildren) {
|
|
831
|
+
if (def.type === "clipPath") {
|
|
832
|
+
const id = def.props.id;
|
|
833
|
+
if (id) {
|
|
834
|
+
defs.set(id, normalizeChildren(def));
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return defs;
|
|
840
|
+
}
|
|
841
|
+
function parseUrlRef(value) {
|
|
842
|
+
if (typeof value !== "string") return void 0;
|
|
843
|
+
const m = value.match(/^url\(#(.+)\)$/);
|
|
844
|
+
return m?.[1];
|
|
845
|
+
}
|
|
846
|
+
function normalizeChildren(node) {
|
|
847
|
+
const raw = node.children ?? node.props.children;
|
|
848
|
+
if (raw == null) return [];
|
|
849
|
+
return Array.isArray(raw) ? raw : [raw];
|
|
850
|
+
}
|
|
851
|
+
function buildPath(child) {
|
|
852
|
+
const props = mergeStyleIntoProps(child.props);
|
|
853
|
+
switch (child.type) {
|
|
854
|
+
case "path": {
|
|
855
|
+
const d = props.d;
|
|
856
|
+
if (!d) return void 0;
|
|
857
|
+
return new Path2D(d);
|
|
858
|
+
}
|
|
859
|
+
case "circle": {
|
|
860
|
+
const cx = Number(props.cx ?? 0);
|
|
861
|
+
const cy = Number(props.cy ?? 0);
|
|
862
|
+
const r = Number(props.r ?? 0);
|
|
863
|
+
if (r <= 0) return void 0;
|
|
864
|
+
const p = new Path2D();
|
|
865
|
+
p.arc(cx, cy, r, 0, Math.PI * 2);
|
|
866
|
+
return p;
|
|
867
|
+
}
|
|
868
|
+
case "rect": {
|
|
869
|
+
const rx = Number(props.x ?? 0);
|
|
870
|
+
const ry = Number(props.y ?? 0);
|
|
871
|
+
const w = Number(props.width ?? 0);
|
|
872
|
+
const h = Number(props.height ?? 0);
|
|
873
|
+
if (w <= 0 || h <= 0) return void 0;
|
|
874
|
+
const p = new Path2D();
|
|
875
|
+
p.rect(rx, ry, w, h);
|
|
876
|
+
return p;
|
|
877
|
+
}
|
|
878
|
+
case "ellipse": {
|
|
879
|
+
const cx = Number(props.cx ?? 0);
|
|
880
|
+
const cy = Number(props.cy ?? 0);
|
|
881
|
+
const rx = Number(props.rx ?? 0);
|
|
882
|
+
const ry = Number(props.ry ?? 0);
|
|
883
|
+
if (rx <= 0 || ry <= 0) return void 0;
|
|
884
|
+
const p = new Path2D();
|
|
885
|
+
p.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
|
|
886
|
+
return p;
|
|
887
|
+
}
|
|
888
|
+
case "polygon": {
|
|
889
|
+
const points = parsePoints(props.points);
|
|
890
|
+
if (points.length < 2) return void 0;
|
|
891
|
+
const p = new Path2D();
|
|
892
|
+
p.moveTo(points[0][0], points[0][1]);
|
|
893
|
+
for (let i = 1; i < points.length; i++) {
|
|
894
|
+
p.lineTo(points[i][0], points[i][1]);
|
|
895
|
+
}
|
|
896
|
+
p.closePath();
|
|
897
|
+
return p;
|
|
898
|
+
}
|
|
899
|
+
default:
|
|
900
|
+
return void 0;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function buildClipPath(shapes) {
|
|
904
|
+
let combined;
|
|
905
|
+
for (const shape of shapes) {
|
|
906
|
+
const p = buildPath(shape);
|
|
907
|
+
if (!p) continue;
|
|
908
|
+
if (!combined) {
|
|
909
|
+
combined = p;
|
|
910
|
+
} else {
|
|
911
|
+
combined.addPath(p);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return combined;
|
|
915
|
+
}
|
|
814
916
|
function drawSvgContainer(ctx, node, x, y, width, height) {
|
|
815
917
|
ctx.save();
|
|
816
918
|
ctx.translate(x, y);
|
|
@@ -831,17 +933,25 @@ function drawSvgContainer(ctx, node, x, y, width, height) {
|
|
|
831
933
|
const children = node.props.children;
|
|
832
934
|
if (children != null) {
|
|
833
935
|
const childArray = Array.isArray(children) ? children : [children];
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
936
|
+
const svgChildren = childArray.filter(
|
|
937
|
+
(c) => c != null && typeof c === "object"
|
|
938
|
+
);
|
|
939
|
+
const defs = collectDefs(svgChildren);
|
|
940
|
+
for (const child of svgChildren) {
|
|
941
|
+
drawSvgChild(ctx, child, inheritedFill, color, defs);
|
|
838
942
|
}
|
|
839
943
|
}
|
|
840
944
|
ctx.restore();
|
|
841
945
|
}
|
|
842
|
-
function drawSvgChild(ctx, child, inheritedFill, color) {
|
|
946
|
+
function drawSvgChild(ctx, child, inheritedFill, color, defs = /* @__PURE__ */ new Map()) {
|
|
843
947
|
const { type } = child;
|
|
844
948
|
const props = mergeStyleIntoProps(child.props);
|
|
949
|
+
if (type === "defs" || type === "clipPath") return;
|
|
950
|
+
const clipRef = parseUrlRef(props.clipPath ?? props["clip-path"]);
|
|
951
|
+
const clipShapes = clipRef ? defs.get(clipRef) : void 0;
|
|
952
|
+
const clipPath = clipShapes ? buildClipPath(clipShapes) : void 0;
|
|
953
|
+
if (clipPath) ctx.save();
|
|
954
|
+
if (clipPath) ctx.clip(clipPath);
|
|
845
955
|
switch (type) {
|
|
846
956
|
case "path":
|
|
847
957
|
drawPath(ctx, props, inheritedFill, color);
|
|
@@ -865,9 +975,10 @@ function drawSvgChild(ctx, child, inheritedFill, color) {
|
|
|
865
975
|
drawPolyline(ctx, props, inheritedFill, color);
|
|
866
976
|
break;
|
|
867
977
|
case "g":
|
|
868
|
-
drawGroup(ctx, child, inheritedFill, color);
|
|
978
|
+
drawGroup(ctx, child, inheritedFill, color, defs);
|
|
869
979
|
break;
|
|
870
980
|
}
|
|
981
|
+
if (clipPath) ctx.restore();
|
|
871
982
|
}
|
|
872
983
|
function drawPath(ctx, props, inheritedFill, color) {
|
|
873
984
|
const d = props.d;
|
|
@@ -935,15 +1046,14 @@ function drawPolyline(ctx, props, inheritedFill, color) {
|
|
|
935
1046
|
}
|
|
936
1047
|
applyFillAndStroke(ctx, props, path, inheritedFill, color);
|
|
937
1048
|
}
|
|
938
|
-
function drawGroup(ctx, node, inheritedFill, color) {
|
|
939
|
-
const children = node
|
|
940
|
-
if (children
|
|
1049
|
+
function drawGroup(ctx, node, inheritedFill, color, defs = /* @__PURE__ */ new Map()) {
|
|
1050
|
+
const children = normalizeChildren(node);
|
|
1051
|
+
if (children.length === 0) return;
|
|
941
1052
|
const merged = mergeStyleIntoProps(node.props);
|
|
942
1053
|
const groupFill = resolveCurrentColor(merged.fill, color) ?? inheritedFill;
|
|
943
|
-
const
|
|
944
|
-
for (const child of childArray) {
|
|
1054
|
+
for (const child of children) {
|
|
945
1055
|
if (child != null && typeof child === "object") {
|
|
946
|
-
drawSvgChild(ctx, child, groupFill, color);
|
|
1056
|
+
drawSvgChild(ctx, child, groupFill, color, defs);
|
|
947
1057
|
}
|
|
948
1058
|
}
|
|
949
1059
|
}
|
|
@@ -1419,12 +1529,12 @@ async function drawNode(ctx, node, parentX, parentY, debug, emojiStyle) {
|
|
|
1419
1529
|
ctx.strokeRect(x, y, width, height);
|
|
1420
1530
|
}
|
|
1421
1531
|
if (node.textContent !== void 0 && node.textContent !== "") {
|
|
1422
|
-
const paddingTop =
|
|
1423
|
-
const paddingLeft =
|
|
1424
|
-
const paddingRight =
|
|
1425
|
-
const borderTopW =
|
|
1426
|
-
const borderLeftW =
|
|
1427
|
-
const borderRightW =
|
|
1532
|
+
const paddingTop = toNumber(style.paddingTop);
|
|
1533
|
+
const paddingLeft = toNumber(style.paddingLeft);
|
|
1534
|
+
const paddingRight = toNumber(style.paddingRight);
|
|
1535
|
+
const borderTopW = toNumber(style.borderTopWidth);
|
|
1536
|
+
const borderLeftW = toNumber(style.borderLeftWidth);
|
|
1537
|
+
const borderRightW = toNumber(style.borderRightWidth);
|
|
1428
1538
|
const contentX = x + paddingLeft + borderLeftW;
|
|
1429
1539
|
const contentY = y + paddingTop + borderTopW;
|
|
1430
1540
|
const contentWidth = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
|
|
@@ -1445,10 +1555,10 @@ async function drawNode(ctx, node, parentX, parentY, debug, emojiStyle) {
|
|
|
1445
1555
|
);
|
|
1446
1556
|
}
|
|
1447
1557
|
if (node.type === "img" && node.props.src) {
|
|
1448
|
-
const paddingTop =
|
|
1449
|
-
const paddingLeft =
|
|
1450
|
-
const paddingRight =
|
|
1451
|
-
const paddingBottom =
|
|
1558
|
+
const paddingTop = toNumber(style.paddingTop);
|
|
1559
|
+
const paddingLeft = toNumber(style.paddingLeft);
|
|
1560
|
+
const paddingRight = toNumber(style.paddingRight);
|
|
1561
|
+
const paddingBottom = toNumber(style.paddingBottom);
|
|
1452
1562
|
const imgX = x + paddingLeft;
|
|
1453
1563
|
const imgY = y + paddingTop;
|
|
1454
1564
|
const imgW = width - paddingLeft - paddingRight;
|
|
@@ -1614,12 +1724,12 @@ async function drawNodeInner(ctx, node, parentX, parentY, offsetX, offsetY, debu
|
|
|
1614
1724
|
ctx.strokeRect(x, y, width, height);
|
|
1615
1725
|
}
|
|
1616
1726
|
if (node.textContent !== void 0 && node.textContent !== "") {
|
|
1617
|
-
const paddingTop =
|
|
1618
|
-
const paddingLeft =
|
|
1619
|
-
const paddingRight =
|
|
1620
|
-
const borderTopW =
|
|
1621
|
-
const borderLeftW =
|
|
1622
|
-
const borderRightW =
|
|
1727
|
+
const paddingTop = toNumber(style.paddingTop);
|
|
1728
|
+
const paddingLeft = toNumber(style.paddingLeft);
|
|
1729
|
+
const paddingRight = toNumber(style.paddingRight);
|
|
1730
|
+
const borderTopW = toNumber(style.borderTopWidth);
|
|
1731
|
+
const borderLeftW = toNumber(style.borderLeftWidth);
|
|
1732
|
+
const borderRightW = toNumber(style.borderRightWidth);
|
|
1623
1733
|
const contentX = x + paddingLeft + borderLeftW;
|
|
1624
1734
|
const contentY = y + paddingTop + borderTopW;
|
|
1625
1735
|
const contentWidth = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
|
|
@@ -1640,10 +1750,10 @@ async function drawNodeInner(ctx, node, parentX, parentY, offsetX, offsetY, debu
|
|
|
1640
1750
|
);
|
|
1641
1751
|
}
|
|
1642
1752
|
if (node.type === "img" && node.props.src) {
|
|
1643
|
-
const paddingTop =
|
|
1644
|
-
const paddingLeft =
|
|
1645
|
-
const paddingRight =
|
|
1646
|
-
const paddingBottom =
|
|
1753
|
+
const paddingTop = toNumber(style.paddingTop);
|
|
1754
|
+
const paddingLeft = toNumber(style.paddingLeft);
|
|
1755
|
+
const paddingRight = toNumber(style.paddingRight);
|
|
1756
|
+
const paddingBottom = toNumber(style.paddingBottom);
|
|
1647
1757
|
const imgX = x + paddingLeft;
|
|
1648
1758
|
const imgY = y + paddingTop;
|
|
1649
1759
|
const imgW = width - paddingLeft - paddingRight;
|
|
@@ -1674,6 +1784,10 @@ async function drawNodeInner(ctx, node, parentX, parentY, offsetX, offsetY, debu
|
|
|
1674
1784
|
}
|
|
1675
1785
|
ctx.restore();
|
|
1676
1786
|
}
|
|
1787
|
+
function parseCSSLength(value, referenceSize) {
|
|
1788
|
+
if (value.endsWith("%")) return parseFloat(value) / 100 * referenceSize;
|
|
1789
|
+
return parseFloat(value);
|
|
1790
|
+
}
|
|
1677
1791
|
function applyTransform(ctx, transform, x, y, width, height, transformOrigin) {
|
|
1678
1792
|
let ox = x + width / 2;
|
|
1679
1793
|
let oy = y + height / 2;
|
|
@@ -1690,8 +1804,11 @@ function applyTransform(ctx, transform, x, y, width, height, transformOrigin) {
|
|
|
1690
1804
|
case "translate":
|
|
1691
1805
|
case "translateX":
|
|
1692
1806
|
case "translateY": {
|
|
1693
|
-
const tx = name === "translateY" ? 0 :
|
|
1694
|
-
const ty = name === "translateX" ? 0 :
|
|
1807
|
+
const tx = name === "translateY" ? 0 : parseCSSLength(values[0], width);
|
|
1808
|
+
const ty = name === "translateX" ? 0 : parseCSSLength(
|
|
1809
|
+
values[name === "translate" ? 1 : 0] ?? "0",
|
|
1810
|
+
height
|
|
1811
|
+
);
|
|
1695
1812
|
ctx.translate(tx, ty);
|
|
1696
1813
|
break;
|
|
1697
1814
|
}
|
|
@@ -1727,8 +1844,7 @@ function resolveOrigin(value, base, size) {
|
|
|
1727
1844
|
if (value === "left" || value === "top") return base;
|
|
1728
1845
|
if (value === "right" || value === "bottom") return base + size;
|
|
1729
1846
|
if (value === "center") return base + size / 2;
|
|
1730
|
-
|
|
1731
|
-
return base + parseFloat(value);
|
|
1847
|
+
return base + parseCSSLength(value, size);
|
|
1732
1848
|
}
|
|
1733
1849
|
function parseAngle(value) {
|
|
1734
1850
|
if (value.endsWith("deg")) return parseFloat(value) * Math.PI / 180;
|
|
@@ -1736,7 +1852,7 @@ function parseAngle(value) {
|
|
|
1736
1852
|
if (value.endsWith("turn")) return parseFloat(value) * 2 * Math.PI;
|
|
1737
1853
|
return parseFloat(value);
|
|
1738
1854
|
}
|
|
1739
|
-
function
|
|
1855
|
+
function toNumber(v) {
|
|
1740
1856
|
if (typeof v === "number") return v;
|
|
1741
1857
|
if (v === void 0 || v === null) return 0;
|
|
1742
1858
|
const n = parseFloat(String(v));
|
|
@@ -1791,7 +1907,7 @@ function parseValue(v) {
|
|
|
1791
1907
|
if (s !== "" && !isNaN(n)) return n;
|
|
1792
1908
|
return s;
|
|
1793
1909
|
}
|
|
1794
|
-
function expandStyle(raw) {
|
|
1910
|
+
function expandStyle(raw, fontFamilies) {
|
|
1795
1911
|
const style = { ...raw };
|
|
1796
1912
|
if (style.margin !== void 0) {
|
|
1797
1913
|
const sides = parseSides(String(style.margin));
|
|
@@ -1904,7 +2020,14 @@ function expandStyle(raw) {
|
|
|
1904
2020
|
if (style.overflowY === void 0) style.overflowY = style.overflow;
|
|
1905
2021
|
}
|
|
1906
2022
|
if (typeof style.fontFamily === "string") {
|
|
1907
|
-
|
|
2023
|
+
const families = style.fontFamily.split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter(Boolean);
|
|
2024
|
+
if (fontFamilies) {
|
|
2025
|
+
const present = new Set(families);
|
|
2026
|
+
for (const name of fontFamilies) {
|
|
2027
|
+
if (!present.has(name)) families.push(name);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
style.fontFamily = families.join(", ");
|
|
1908
2031
|
}
|
|
1909
2032
|
return style;
|
|
1910
2033
|
}
|
|
@@ -2075,8 +2198,41 @@ function resolveUnits(style, viewportWidth, viewportHeight, rootFontSize = DEFAU
|
|
|
2075
2198
|
style[prop] = resolved;
|
|
2076
2199
|
}
|
|
2077
2200
|
}
|
|
2201
|
+
if (style.transform) {
|
|
2202
|
+
style.transform = resolveTransformUnits(
|
|
2203
|
+
style.transform,
|
|
2204
|
+
viewportWidth,
|
|
2205
|
+
viewportHeight,
|
|
2206
|
+
fontSize,
|
|
2207
|
+
rootFontSize
|
|
2208
|
+
);
|
|
2209
|
+
}
|
|
2210
|
+
if (style.transformOrigin) {
|
|
2211
|
+
style.transformOrigin = resolveTransformUnits(
|
|
2212
|
+
style.transformOrigin,
|
|
2213
|
+
viewportWidth,
|
|
2214
|
+
viewportHeight,
|
|
2215
|
+
fontSize,
|
|
2216
|
+
rootFontSize
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2078
2219
|
return style;
|
|
2079
2220
|
}
|
|
2221
|
+
function resolveTransformUnits(transform, viewportWidth, viewportHeight, fontSize, rootFontSize) {
|
|
2222
|
+
return transform.replace(
|
|
2223
|
+
/(-?\d*\.?\d+)(vw|vh|vmin|vmax|em|rem|px|pt|pc|in|cm|mm)\b/g,
|
|
2224
|
+
(match) => {
|
|
2225
|
+
const resolved = resolveUnit(
|
|
2226
|
+
match,
|
|
2227
|
+
viewportWidth,
|
|
2228
|
+
viewportHeight,
|
|
2229
|
+
fontSize,
|
|
2230
|
+
rootFontSize
|
|
2231
|
+
);
|
|
2232
|
+
return typeof resolved === "number" ? String(resolved) : match;
|
|
2233
|
+
}
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2080
2236
|
|
|
2081
2237
|
// src/jsx/yoga.ts
|
|
2082
2238
|
import Yoga, {
|
|
@@ -2265,16 +2421,18 @@ function applyEdgeValue(node, setter, edge, value) {
|
|
|
2265
2421
|
}
|
|
2266
2422
|
|
|
2267
2423
|
// src/jsx/layout.ts
|
|
2268
|
-
async function buildLayoutTree(element, containerWidth, containerHeight, ctx, emojiEnabled) {
|
|
2424
|
+
async function buildLayoutTree(element, containerWidth, containerHeight, ctx, emojiEnabled, fontFamilies) {
|
|
2269
2425
|
const rootYogaNode = createYogaNode();
|
|
2426
|
+
const rootStyle = fontFamilies?.length ? { ...DEFAULT_STYLE, fontFamily: fontFamilies.join(", ") } : DEFAULT_STYLE;
|
|
2270
2427
|
const rootNode = await buildNode(
|
|
2271
2428
|
element,
|
|
2272
|
-
|
|
2429
|
+
rootStyle,
|
|
2273
2430
|
rootYogaNode,
|
|
2274
2431
|
containerWidth,
|
|
2275
2432
|
containerHeight,
|
|
2276
2433
|
ctx,
|
|
2277
|
-
emojiEnabled
|
|
2434
|
+
emojiEnabled,
|
|
2435
|
+
fontFamilies
|
|
2278
2436
|
);
|
|
2279
2437
|
rootYogaNode.setWidth(containerWidth);
|
|
2280
2438
|
rootYogaNode.setHeight(containerHeight);
|
|
@@ -2283,7 +2441,7 @@ async function buildLayoutTree(element, containerWidth, containerHeight, ctx, em
|
|
|
2283
2441
|
freeYogaNode(rootYogaNode);
|
|
2284
2442
|
return layoutTree;
|
|
2285
2443
|
}
|
|
2286
|
-
async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewportHeight, ctx, emojiEnabled) {
|
|
2444
|
+
async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewportHeight, ctx, emojiEnabled, fontFamilies) {
|
|
2287
2445
|
if (element === null || element === void 0 || typeof element === "boolean") {
|
|
2288
2446
|
return {
|
|
2289
2447
|
type: "empty",
|
|
@@ -2324,7 +2482,8 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
2324
2482
|
viewportWidth,
|
|
2325
2483
|
viewportHeight,
|
|
2326
2484
|
ctx,
|
|
2327
|
-
emojiEnabled
|
|
2485
|
+
emojiEnabled,
|
|
2486
|
+
fontFamilies
|
|
2328
2487
|
)
|
|
2329
2488
|
);
|
|
2330
2489
|
}
|
|
@@ -2349,12 +2508,13 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
2349
2508
|
viewportWidth,
|
|
2350
2509
|
viewportHeight,
|
|
2351
2510
|
ctx,
|
|
2352
|
-
emojiEnabled
|
|
2511
|
+
emojiEnabled,
|
|
2512
|
+
fontFamilies
|
|
2353
2513
|
);
|
|
2354
2514
|
}
|
|
2355
2515
|
const props = el.props ?? {};
|
|
2356
2516
|
const rawStyle = props.style ?? {};
|
|
2357
|
-
const expanded = expandStyle(rawStyle);
|
|
2517
|
+
const expanded = expandStyle(rawStyle, fontFamilies);
|
|
2358
2518
|
const style = resolveStyle(expanded, parentStyle);
|
|
2359
2519
|
resolveUnits(style, viewportWidth, viewportHeight);
|
|
2360
2520
|
const tagName = String(type);
|
|
@@ -2472,7 +2632,8 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
2472
2632
|
viewportWidth,
|
|
2473
2633
|
viewportHeight,
|
|
2474
2634
|
ctx,
|
|
2475
|
-
emojiEnabled
|
|
2635
|
+
emojiEnabled,
|
|
2636
|
+
fontFamilies
|
|
2476
2637
|
)
|
|
2477
2638
|
);
|
|
2478
2639
|
}
|
|
@@ -2540,12 +2701,14 @@ async function renderReactElement(ctx, element, options) {
|
|
|
2540
2701
|
const width = ctx.canvas.width;
|
|
2541
2702
|
const height = ctx.canvas.height;
|
|
2542
2703
|
const emojiStyle = options.emoji === "none" ? void 0 : options.emoji ?? "twemoji";
|
|
2704
|
+
const fontFamilies = [...new Set(options.fonts.map((f) => f.name))];
|
|
2543
2705
|
const layoutTree = await buildLayoutTree(
|
|
2544
2706
|
element,
|
|
2545
2707
|
width,
|
|
2546
2708
|
height,
|
|
2547
2709
|
ctx,
|
|
2548
|
-
!!emojiStyle
|
|
2710
|
+
!!emojiStyle,
|
|
2711
|
+
fontFamilies
|
|
2549
2712
|
);
|
|
2550
2713
|
await drawNode(ctx, layoutTree, 0, 0, options.debug ?? false, emojiStyle);
|
|
2551
2714
|
}
|