@pixldocs/canvas-renderer 0.5.19 → 0.5.20
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 +93 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +93 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -11863,6 +11863,83 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
11863
11863
|
});
|
|
11864
11864
|
}
|
|
11865
11865
|
}
|
|
11866
|
+
const TEXT_TYPES = /* @__PURE__ */ new Set(["textbox", "text", "i-text"]);
|
|
11867
|
+
function getTextLines(obj) {
|
|
11868
|
+
const lines = Array.isArray(obj.textLines) && obj.textLines.length ? obj.textLines : String(obj.text || "").split("\n");
|
|
11869
|
+
return lines.map((line) => Array.isArray(line) ? line.join("") : String(line ?? ""));
|
|
11870
|
+
}
|
|
11871
|
+
function measureLineWidth(obj, line) {
|
|
11872
|
+
if (typeof document === "undefined") return 0;
|
|
11873
|
+
const canvas = document.createElement("canvas");
|
|
11874
|
+
const ctx = canvas.getContext("2d");
|
|
11875
|
+
if (!ctx) return 0;
|
|
11876
|
+
const fontStyle = obj.fontStyle || "normal";
|
|
11877
|
+
const fontWeight = obj.fontWeight || 400;
|
|
11878
|
+
const fontSize = obj.fontSize || 16;
|
|
11879
|
+
const fontFamily = obj.fontFamily || "sans-serif";
|
|
11880
|
+
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
11881
|
+
const charSpacing = Number(obj.charSpacing || 0) / 1e3 * fontSize;
|
|
11882
|
+
return ctx.measureText(line).width + Math.max(0, line.length - 1) * charSpacing;
|
|
11883
|
+
}
|
|
11884
|
+
function getFabricCanvasFromContainer(container) {
|
|
11885
|
+
const registry2 = window.__fabricCanvasRegistry;
|
|
11886
|
+
if (registry2 instanceof Map) {
|
|
11887
|
+
for (const entry of registry2.values()) {
|
|
11888
|
+
const canvas = (entry == null ? void 0 : entry.canvas) || entry;
|
|
11889
|
+
if (!canvas || typeof canvas.toSVG !== "function") continue;
|
|
11890
|
+
const el = canvas.lowerCanvasEl || canvas.upperCanvasEl;
|
|
11891
|
+
if (el && container.contains(el)) return canvas;
|
|
11892
|
+
}
|
|
11893
|
+
}
|
|
11894
|
+
return null;
|
|
11895
|
+
}
|
|
11896
|
+
function stabilizeFabricTextObjects(fabricInstance) {
|
|
11897
|
+
var _a, _b, _c;
|
|
11898
|
+
if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;
|
|
11899
|
+
clearFabricCharCache();
|
|
11900
|
+
clearMeasurementCache();
|
|
11901
|
+
const walk = (obj) => {
|
|
11902
|
+
var _a2, _b2, _c2, _d;
|
|
11903
|
+
if (!obj) return;
|
|
11904
|
+
const children = Array.isArray(obj._objects) ? obj._objects : Array.isArray(obj.objects) ? obj.objects : [];
|
|
11905
|
+
if (children.length) children.forEach(walk);
|
|
11906
|
+
const isTextObject = typeof obj.text === "string" && typeof obj.initDimensions === "function" && (TEXT_TYPES.has(obj.type) || obj.isEditing !== void 0);
|
|
11907
|
+
if (!isTextObject) return;
|
|
11908
|
+
const saved = { width: obj.width, scaleX: obj.scaleX, scaleY: obj.scaleY };
|
|
11909
|
+
const reset = () => {
|
|
11910
|
+
var _a3;
|
|
11911
|
+
(_a3 = obj._clearCache) == null ? void 0 : _a3.call(obj);
|
|
11912
|
+
obj.__charBounds = [];
|
|
11913
|
+
obj.__lineWidths = [];
|
|
11914
|
+
obj.__lineHeights = [];
|
|
11915
|
+
obj.__graphemeLines = [];
|
|
11916
|
+
obj._textLines = [];
|
|
11917
|
+
obj.textLines = [];
|
|
11918
|
+
obj._styleMap = null;
|
|
11919
|
+
obj.styleMap = null;
|
|
11920
|
+
obj.dirty = true;
|
|
11921
|
+
};
|
|
11922
|
+
reset();
|
|
11923
|
+
obj.initDimensions();
|
|
11924
|
+
if (saved.width != null) {
|
|
11925
|
+
(_a2 = obj.set) == null ? void 0 : _a2.call(obj, { width: saved.width, scaleX: saved.scaleX, scaleY: saved.scaleY });
|
|
11926
|
+
reset();
|
|
11927
|
+
obj.initDimensions();
|
|
11928
|
+
(_b2 = obj.set) == null ? void 0 : _b2.call(obj, { width: saved.width, scaleX: saved.scaleX, scaleY: saved.scaleY });
|
|
11929
|
+
}
|
|
11930
|
+
if (obj.underline || obj.linethrough) {
|
|
11931
|
+
const lineWidths = Array.isArray(obj.__lineWidths) ? obj.__lineWidths : [];
|
|
11932
|
+
obj.__lineWidths = getTextLines(obj).map((line, index) => Math.max(lineWidths[index] || 0, measureLineWidth(obj, line)));
|
|
11933
|
+
}
|
|
11934
|
+
obj.dirty = true;
|
|
11935
|
+
(_c2 = obj._clearCache) == null ? void 0 : _c2.call(obj);
|
|
11936
|
+
(_d = obj.setCoords) == null ? void 0 : _d.call(obj);
|
|
11937
|
+
};
|
|
11938
|
+
fabricInstance.getObjects().forEach(walk);
|
|
11939
|
+
(_a = fabricInstance.calcOffset) == null ? void 0 : _a.call(fabricInstance);
|
|
11940
|
+
(_b = fabricInstance.renderAll) == null ? void 0 : _b.call(fabricInstance);
|
|
11941
|
+
(_c = fabricInstance.requestRenderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
11942
|
+
}
|
|
11866
11943
|
function PixldocsPreview(props) {
|
|
11867
11944
|
const {
|
|
11868
11945
|
pageIndex = 0,
|
|
@@ -11959,6 +12036,13 @@ function PixldocsPreview(props) {
|
|
|
11959
12036
|
() => `${pageIndex}-${fontsReadyVersion}-${stabilizationPass}`,
|
|
11960
12037
|
[pageIndex, fontsReadyVersion, stabilizationPass]
|
|
11961
12038
|
);
|
|
12039
|
+
const previewWrapRef = react.useCallback((node) => {
|
|
12040
|
+
if (!node || !config) return;
|
|
12041
|
+
requestAnimationFrame(() => {
|
|
12042
|
+
const fabricCanvas = getFabricCanvasFromContainer(node);
|
|
12043
|
+
if (fabricCanvas) stabilizeFabricTextObjects(fabricCanvas);
|
|
12044
|
+
});
|
|
12045
|
+
}, [config, previewKey]);
|
|
11962
12046
|
react.useEffect(() => {
|
|
11963
12047
|
if (isResolveMode) return;
|
|
11964
12048
|
if (!config) {
|
|
@@ -11989,7 +12073,7 @@ function PixldocsPreview(props) {
|
|
|
11989
12073
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
11990
12074
|
}
|
|
11991
12075
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...style, position: "relative" }, children: [
|
|
11992
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { visibility: canvasSettled ? "visible" : "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12076
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: previewWrapRef, style: { visibility: canvasSettled ? "visible" : "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11993
12077
|
PreviewCanvas,
|
|
11994
12078
|
{
|
|
11995
12079
|
config,
|
|
@@ -12721,16 +12805,7 @@ class PixldocsRenderer {
|
|
|
12721
12805
|
* using the global __fabricCanvasRegistry (set by PageCanvas).
|
|
12722
12806
|
*/
|
|
12723
12807
|
getFabricCanvasFromContainer(container) {
|
|
12724
|
-
|
|
12725
|
-
if (registry2 instanceof Map) {
|
|
12726
|
-
for (const entry of registry2.values()) {
|
|
12727
|
-
const canvas = (entry == null ? void 0 : entry.canvas) || entry;
|
|
12728
|
-
if (!canvas || typeof canvas.toSVG !== "function") continue;
|
|
12729
|
-
const el = canvas.lowerCanvasEl || canvas.upperCanvasEl;
|
|
12730
|
-
if (el && container.contains(el)) return canvas;
|
|
12731
|
-
}
|
|
12732
|
-
}
|
|
12733
|
-
return null;
|
|
12808
|
+
return getFabricCanvasFromContainer(container);
|
|
12734
12809
|
}
|
|
12735
12810
|
async waitForStableTextMetrics(container, config) {
|
|
12736
12811
|
if (typeof document !== "undefined") {
|
|
@@ -12744,59 +12819,7 @@ class PixldocsRenderer {
|
|
|
12744
12819
|
clearFabricCharCache();
|
|
12745
12820
|
clearMeasurementCache();
|
|
12746
12821
|
};
|
|
12747
|
-
const reflowTextboxes = () =>
|
|
12748
|
-
var _a, _b, _c;
|
|
12749
|
-
const walk = (obj) => {
|
|
12750
|
-
var _a2, _b2, _c2, _d;
|
|
12751
|
-
if (!obj) return;
|
|
12752
|
-
const children = Array.isArray(obj._objects) ? obj._objects : Array.isArray(obj.objects) ? obj.objects : [];
|
|
12753
|
-
if (children.length) children.forEach(walk);
|
|
12754
|
-
const isTextObject = typeof obj.text === "string" && typeof obj.initDimensions === "function" && (obj.type === "textbox" || obj.type === "text" || obj.type === "i-text" || obj.isEditing !== void 0);
|
|
12755
|
-
if (isTextObject) {
|
|
12756
|
-
const saved = {
|
|
12757
|
-
width: obj.width,
|
|
12758
|
-
scaleX: obj.scaleX,
|
|
12759
|
-
scaleY: obj.scaleY
|
|
12760
|
-
};
|
|
12761
|
-
const resetTextboxLayoutInternals = () => {
|
|
12762
|
-
var _a3;
|
|
12763
|
-
(_a3 = obj._clearCache) == null ? void 0 : _a3.call(obj);
|
|
12764
|
-
obj.__charBounds = [];
|
|
12765
|
-
obj.__lineWidths = [];
|
|
12766
|
-
obj.__lineHeights = [];
|
|
12767
|
-
obj.__graphemeLines = [];
|
|
12768
|
-
obj._textLines = [];
|
|
12769
|
-
obj.textLines = [];
|
|
12770
|
-
obj._styleMap = null;
|
|
12771
|
-
obj.styleMap = null;
|
|
12772
|
-
obj.dirty = true;
|
|
12773
|
-
};
|
|
12774
|
-
resetTextboxLayoutInternals();
|
|
12775
|
-
obj.initDimensions();
|
|
12776
|
-
if (saved.width != null) {
|
|
12777
|
-
(_a2 = obj.set) == null ? void 0 : _a2.call(obj, {
|
|
12778
|
-
width: saved.width,
|
|
12779
|
-
scaleX: saved.scaleX,
|
|
12780
|
-
scaleY: saved.scaleY
|
|
12781
|
-
});
|
|
12782
|
-
resetTextboxLayoutInternals();
|
|
12783
|
-
obj.initDimensions();
|
|
12784
|
-
}
|
|
12785
|
-
(_b2 = obj.set) == null ? void 0 : _b2.call(obj, {
|
|
12786
|
-
width: saved.width,
|
|
12787
|
-
scaleX: saved.scaleX,
|
|
12788
|
-
scaleY: saved.scaleY,
|
|
12789
|
-
dirty: true
|
|
12790
|
-
});
|
|
12791
|
-
(_c2 = obj._clearCache) == null ? void 0 : _c2.call(obj);
|
|
12792
|
-
(_d = obj.setCoords) == null ? void 0 : _d.call(obj);
|
|
12793
|
-
}
|
|
12794
|
-
};
|
|
12795
|
-
fabricInstance.getObjects().forEach(walk);
|
|
12796
|
-
(_a = fabricInstance.calcOffset) == null ? void 0 : _a.call(fabricInstance);
|
|
12797
|
-
(_b = fabricInstance.renderAll) == null ? void 0 : _b.call(fabricInstance);
|
|
12798
|
-
(_c = fabricInstance.requestRenderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
12799
|
-
};
|
|
12822
|
+
const reflowTextboxes = () => stabilizeFabricTextObjects(fabricInstance);
|
|
12800
12823
|
clearTextMetricCaches();
|
|
12801
12824
|
await waitForPaint();
|
|
12802
12825
|
reflowTextboxes();
|
|
@@ -14552,6 +14575,12 @@ function convertTextDecorationsToLines(svg) {
|
|
|
14552
14575
|
} else {
|
|
14553
14576
|
textWidth = content.length * fontSize * 0.6;
|
|
14554
14577
|
}
|
|
14578
|
+
if (typeof tspan.getComputedTextLength === "function") {
|
|
14579
|
+
try {
|
|
14580
|
+
textWidth = Math.max(textWidth, tspan.getComputedTextLength());
|
|
14581
|
+
} catch {
|
|
14582
|
+
}
|
|
14583
|
+
}
|
|
14555
14584
|
const underlineY = y + fontSize * 0.15;
|
|
14556
14585
|
const thickness = Math.max(0.5, fontSize * 0.066667);
|
|
14557
14586
|
const line = doc.createElementNS("http://www.w3.org/2000/svg", "line");
|