@pixldocs/canvas-renderer 0.5.158 → 0.5.160
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-D0AWrDab.js → index-CmhkyT2o.js} +134 -8
- package/dist/index-CmhkyT2o.js.map +1 -0
- package/dist/{index-B1f4qE6u.cjs → index-CtUEIsYl.cjs} +134 -8
- package/dist/index-CtUEIsYl.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-DwZylzI2.js → vectorPdfExport-2NNilLNC.js} +4 -4
- package/dist/{vectorPdfExport-DwZylzI2.js.map → vectorPdfExport-2NNilLNC.js.map} +1 -1
- package/dist/{vectorPdfExport-vZ8VHnu6.cjs → vectorPdfExport-DEMJeh_t.cjs} +4 -4
- package/dist/{vectorPdfExport-vZ8VHnu6.cjs.map → vectorPdfExport-DEMJeh_t.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-B1f4qE6u.cjs.map +0 -1
- package/dist/index-D0AWrDab.js.map +0 -1
|
@@ -5804,12 +5804,16 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
|
|
|
5804
5804
|
if (canUseAlignmentAnchor && Number.isFinite(lineW) && lineW > 0) {
|
|
5805
5805
|
lineAnchors.push({
|
|
5806
5806
|
x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
|
|
5807
|
-
anchor: alignmentAnchor
|
|
5807
|
+
anchor: alignmentAnchor,
|
|
5808
|
+
lineWidth: lineW,
|
|
5809
|
+
lineStart: baseStart
|
|
5808
5810
|
});
|
|
5809
5811
|
} else {
|
|
5810
5812
|
lineAnchors.push({
|
|
5811
5813
|
x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
|
|
5812
|
-
anchor: "start"
|
|
5814
|
+
anchor: "start",
|
|
5815
|
+
lineWidth: Number.isFinite(lineW) ? lineW : 0,
|
|
5816
|
+
lineStart: baseStart
|
|
5813
5817
|
});
|
|
5814
5818
|
}
|
|
5815
5819
|
}
|
|
@@ -5847,7 +5851,7 @@ function bakeTextSvgToFabricLineStarts(svg, obj, w) {
|
|
|
5847
5851
|
if (!lineAnchor || typeof lineAnchor.x !== "number" || !Number.isFinite(lineAnchor.x)) return _m;
|
|
5848
5852
|
const cleanPre = stripAnchorAttrs(pre);
|
|
5849
5853
|
const cleanPost = stripAnchorAttrs(post);
|
|
5850
|
-
return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1"${cleanPost}>`;
|
|
5854
|
+
return `<tspan${cleanPre} x="${lineAnchor.x.toFixed(3)}" text-anchor="${lineAnchor.anchor}" data-pd-line-anchor="1" data-pd-line-width="${lineAnchor.lineWidth.toFixed(3)}" data-pd-line-start="${lineAnchor.lineStart.toFixed(3)}"${cleanPost}>`;
|
|
5851
5855
|
}
|
|
5852
5856
|
);
|
|
5853
5857
|
return newSvg;
|
|
@@ -15955,6 +15959,121 @@ function PixldocsPreview(props) {
|
|
|
15955
15959
|
!canvasSettled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
15956
15960
|
] });
|
|
15957
15961
|
}
|
|
15962
|
+
function isFabricTextLike(obj) {
|
|
15963
|
+
return !!obj && (obj.type === "textbox" || obj.type === "i-text" || obj.type === "text" || Array.isArray(obj._textLines) && typeof obj.getLineWidth === "function");
|
|
15964
|
+
}
|
|
15965
|
+
function bakeSelectableTextSvgToFabricLineAnchors(svg, obj) {
|
|
15966
|
+
try {
|
|
15967
|
+
if (/\bdata-pd-line-anchor\s*=\s*"1"/i.test(svg)) return svg;
|
|
15968
|
+
const rawAlign = String((obj == null ? void 0 : obj.textAlign) || "left").toLowerCase();
|
|
15969
|
+
if (!/center|right|end/.test(rawAlign)) return svg;
|
|
15970
|
+
const lines = (obj == null ? void 0 : obj._textLines) ?? [];
|
|
15971
|
+
const width = Number((obj == null ? void 0 : obj.width) ?? 0);
|
|
15972
|
+
if (!Array.isArray(lines) || lines.length === 0 || !Number.isFinite(width) || width <= 0) return svg;
|
|
15973
|
+
const alignmentAnchor = /right|end/.test(rawAlign) ? "end" : "middle";
|
|
15974
|
+
const hasStyledChars = (() => {
|
|
15975
|
+
const styles = obj == null ? void 0 : obj.styles;
|
|
15976
|
+
if (!styles || typeof styles !== "object") return false;
|
|
15977
|
+
return Object.values(styles).some((line2) => line2 && typeof line2 === "object" && Object.keys(line2).length > 0);
|
|
15978
|
+
})();
|
|
15979
|
+
const canUseLineAnchor = !hasStyledChars && !(obj == null ? void 0 : obj.path) && !Number((obj == null ? void 0 : obj.charSpacing) ?? 0);
|
|
15980
|
+
const halfW = width / 2;
|
|
15981
|
+
const lineAnchors = lines.map((_line, i) => {
|
|
15982
|
+
var _a, _b, _c, _d;
|
|
15983
|
+
let lineLeft = 0;
|
|
15984
|
+
let lineW = 0;
|
|
15985
|
+
let firstGlyphAdjust = 0;
|
|
15986
|
+
try {
|
|
15987
|
+
lineLeft = Number(((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0);
|
|
15988
|
+
} catch {
|
|
15989
|
+
lineLeft = 0;
|
|
15990
|
+
}
|
|
15991
|
+
try {
|
|
15992
|
+
lineW = Number(((_b = obj.getLineWidth) == null ? void 0 : _b.call(obj, i)) ?? 0);
|
|
15993
|
+
} catch {
|
|
15994
|
+
lineW = 0;
|
|
15995
|
+
}
|
|
15996
|
+
try {
|
|
15997
|
+
const firstBox = (_d = (_c = obj.__charBounds) == null ? void 0 : _c[i]) == null ? void 0 : _d[0];
|
|
15998
|
+
const kerned = Number(firstBox == null ? void 0 : firstBox.kernedWidth);
|
|
15999
|
+
const glyphW = Number(firstBox == null ? void 0 : firstBox.width);
|
|
16000
|
+
if (Number.isFinite(kerned) && Number.isFinite(glyphW)) firstGlyphAdjust = kerned - glyphW;
|
|
16001
|
+
} catch {
|
|
16002
|
+
firstGlyphAdjust = 0;
|
|
16003
|
+
}
|
|
16004
|
+
const baseStart = -halfW + (Number.isFinite(lineLeft) ? lineLeft : 0);
|
|
16005
|
+
if (canUseLineAnchor && Number.isFinite(lineW) && lineW > 0) {
|
|
16006
|
+
return {
|
|
16007
|
+
x: alignmentAnchor === "end" ? baseStart + lineW : baseStart + lineW / 2,
|
|
16008
|
+
anchor: alignmentAnchor,
|
|
16009
|
+
lineWidth: lineW,
|
|
16010
|
+
lineStart: baseStart
|
|
16011
|
+
};
|
|
16012
|
+
}
|
|
16013
|
+
return {
|
|
16014
|
+
x: baseStart + (Number.isFinite(firstGlyphAdjust) ? firstGlyphAdjust : 0),
|
|
16015
|
+
anchor: "start",
|
|
16016
|
+
lineWidth: Number.isFinite(lineW) ? lineW : 0,
|
|
16017
|
+
lineStart: baseStart
|
|
16018
|
+
};
|
|
16019
|
+
});
|
|
16020
|
+
const stripAnchorAttrs = (attrs) => attrs.replace(/\s+text-anchor\s*=\s*"[^"]*"/gi, "").replace(/\s+data-pd-line-anchor\s*=\s*"[^"]*"/gi, "").replace(/(\sstyle=")([^"]*)(")/i, (_m, pre, val, post) => {
|
|
16021
|
+
const cleaned = val.replace(/text-anchor\s*:\s*[^;"']+;?/gi, "").replace(/text-align\s*:\s*[^;"']+;?/gi, "").trim();
|
|
16022
|
+
return cleaned ? `${pre}${cleaned}${post}` : "";
|
|
16023
|
+
});
|
|
16024
|
+
const textOpenMatch = svg.match(/<text\b([^>]*)>/i);
|
|
16025
|
+
if (!textOpenMatch) return svg;
|
|
16026
|
+
const textAttrs = stripAnchorAttrs(textOpenMatch[1]);
|
|
16027
|
+
let lineIdx = 0;
|
|
16028
|
+
let lastY = "";
|
|
16029
|
+
let replacedLine = false;
|
|
16030
|
+
const patched = svg.replace(textOpenMatch[0], `<text text-anchor="start"${textAttrs}>`).replace(
|
|
16031
|
+
/<tspan\b([^>]*?)\sx="([^"]*)"([^>]*)>/gi,
|
|
16032
|
+
(match, pre, _oldX, post) => {
|
|
16033
|
+
const attrs = `${pre} ${post}`;
|
|
16034
|
+
const yMatch = attrs.match(/\sy\s*=\s*"([^"]*)"/i);
|
|
16035
|
+
const y = (yMatch == null ? void 0 : yMatch[1]) ?? "";
|
|
16036
|
+
const isLineStart = y !== "" ? y !== lastY : lineIdx < lineAnchors.length;
|
|
16037
|
+
if (!isLineStart) return match;
|
|
16038
|
+
if (y !== "") lastY = y;
|
|
16039
|
+
const line2 = lineAnchors[lineIdx++];
|
|
16040
|
+
if (!line2 || !Number.isFinite(line2.x)) return match;
|
|
16041
|
+
replacedLine = true;
|
|
16042
|
+
return `<tspan${stripAnchorAttrs(pre)} x="${line2.x.toFixed(3)}" text-anchor="${line2.anchor}" data-pd-line-anchor="1" data-pd-line-width="${line2.lineWidth.toFixed(3)}" data-pd-line-start="${line2.lineStart.toFixed(3)}"${stripAnchorAttrs(post)}>`;
|
|
16043
|
+
}
|
|
16044
|
+
);
|
|
16045
|
+
if (replacedLine) return patched;
|
|
16046
|
+
const line = lineAnchors[0];
|
|
16047
|
+
if (!line || !Number.isFinite(line.x)) return patched;
|
|
16048
|
+
return patched.replace(/<text\b([^>]*)>/i, (_m, attrs) => {
|
|
16049
|
+
const clean = stripAnchorAttrs(attrs).replace(/\s+x\s*=\s*"[^"]*"/i, "");
|
|
16050
|
+
return `<text x="${line.x.toFixed(3)}" text-anchor="${line.anchor}" data-pd-line-anchor="1" data-pd-line-width="${line.lineWidth.toFixed(3)}" data-pd-line-start="${line.lineStart.toFixed(3)}"${clean}>`;
|
|
16051
|
+
});
|
|
16052
|
+
} catch {
|
|
16053
|
+
return svg;
|
|
16054
|
+
}
|
|
16055
|
+
}
|
|
16056
|
+
function patchTextObjectsForSelectableSvg(fabricInstance) {
|
|
16057
|
+
var _a;
|
|
16058
|
+
const records = [];
|
|
16059
|
+
const visit = (obj) => {
|
|
16060
|
+
if (!obj || typeof obj !== "object") return;
|
|
16061
|
+
if (isFabricTextLike(obj) && typeof obj.toSVG === "function") {
|
|
16062
|
+
const original = obj.toSVG;
|
|
16063
|
+
obj.toSVG = function patchedSelectableTextToSVG(reviver) {
|
|
16064
|
+
return bakeSelectableTextSvgToFabricLineAnchors(original.call(this, reviver), this);
|
|
16065
|
+
};
|
|
16066
|
+
records.push({ obj, toSVG: original });
|
|
16067
|
+
}
|
|
16068
|
+
const children = typeof obj.getObjects === "function" ? obj.getObjects() : obj._objects;
|
|
16069
|
+
if (Array.isArray(children)) children.forEach(visit);
|
|
16070
|
+
};
|
|
16071
|
+
try {
|
|
16072
|
+
(_a = fabricInstance == null ? void 0 : fabricInstance.getObjects) == null ? void 0 : _a.call(fabricInstance).forEach(visit);
|
|
16073
|
+
} catch {
|
|
16074
|
+
}
|
|
16075
|
+
return records;
|
|
16076
|
+
}
|
|
15958
16077
|
function normalizeSvgDimensions(svg, targetWidth, targetHeight) {
|
|
15959
16078
|
let normalized = svg;
|
|
15960
16079
|
if (/\bwidth="[^"]*"/i.test(normalized)) {
|
|
@@ -16008,6 +16127,7 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16008
16127
|
} catch {
|
|
16009
16128
|
}
|
|
16010
16129
|
const fadeBakeRecords = [];
|
|
16130
|
+
const textSvgPatchRecords = patchTextObjectsForSelectableSvg(fabricInstance);
|
|
16011
16131
|
try {
|
|
16012
16132
|
const objs = fabricInstance.getObjects().slice();
|
|
16013
16133
|
for (const obj of objs) {
|
|
@@ -16056,6 +16176,12 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16056
16176
|
const raw = fabricInstance.toSVG();
|
|
16057
16177
|
svgString = normalizeSvgDimensions(raw, canvasWidth, canvasHeight);
|
|
16058
16178
|
} finally {
|
|
16179
|
+
for (const rec of textSvgPatchRecords) {
|
|
16180
|
+
try {
|
|
16181
|
+
rec.obj.toSVG = rec.toSVG;
|
|
16182
|
+
} catch {
|
|
16183
|
+
}
|
|
16184
|
+
}
|
|
16059
16185
|
for (const rec of fadeBakeRecords) {
|
|
16060
16186
|
try {
|
|
16061
16187
|
fabricInstance.remove(rec.replacement);
|
|
@@ -16076,9 +16202,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16076
16202
|
}
|
|
16077
16203
|
return svgString;
|
|
16078
16204
|
}
|
|
16079
|
-
const resolvedPackageVersion = "0.5.
|
|
16205
|
+
const resolvedPackageVersion = "0.5.160";
|
|
16080
16206
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
16081
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
16207
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.160";
|
|
16082
16208
|
const roundParityValue = (value) => {
|
|
16083
16209
|
if (typeof value !== "number") return value;
|
|
16084
16210
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16513,7 +16639,7 @@ class PixldocsRenderer {
|
|
|
16513
16639
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16514
16640
|
}
|
|
16515
16641
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16516
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
16642
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DEMJeh_t.cjs"));
|
|
16517
16643
|
const prepared = preparePagesForExport(
|
|
16518
16644
|
cloned.pages,
|
|
16519
16645
|
canvasWidth,
|
|
@@ -18615,7 +18741,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
18615
18741
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
18616
18742
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
18617
18743
|
try {
|
|
18618
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
18744
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DEMJeh_t.cjs"));
|
|
18619
18745
|
try {
|
|
18620
18746
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
18621
18747
|
} catch {
|
|
@@ -18962,4 +19088,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
18962
19088
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
18963
19089
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
18964
19090
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
18965
|
-
//# sourceMappingURL=index-
|
|
19091
|
+
//# sourceMappingURL=index-CtUEIsYl.cjs.map
|