@pixldocs/canvas-renderer 0.5.147 → 0.5.149

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.
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jspdf = require("jspdf");
4
4
  const svg2pdf_js = require("svg2pdf.js");
5
5
  const fabric = require("fabric");
6
- const index = require("./index-D78ekQx5.cjs");
6
+ const index = require("./index-C6IaOn7u.cjs");
7
7
  const pdfFonts = require("./pdfFonts-BTEVnYX8.cjs");
8
8
  function _interopNamespaceDefault(e) {
9
9
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -1199,6 +1199,44 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1199
1199
  tempContainer.appendChild(clone);
1200
1200
  document.body.appendChild(tempContainer);
1201
1201
  let baked = 0;
1202
+ const _measureCanvas = typeof document !== "undefined" ? document.createElement("canvas") : null;
1203
+ const _mctx = (_measureCanvas == null ? void 0 : _measureCanvas.getContext("2d")) || null;
1204
+ const _resolveFontSize = (node) => {
1205
+ let cur = node;
1206
+ while (cur) {
1207
+ const fs = cur.getAttribute("font-size");
1208
+ if (fs) {
1209
+ const n = parseFloat(fs);
1210
+ if (Number.isFinite(n) && n > 0) return n;
1211
+ }
1212
+ cur = cur.parentElement;
1213
+ }
1214
+ return 16;
1215
+ };
1216
+ const _resolveFontAttr = (node, attr, fallback) => {
1217
+ let cur = node;
1218
+ while (cur) {
1219
+ const v = cur.getAttribute(`data-source-${attr}`) || cur.getAttribute(attr);
1220
+ if (v) return v;
1221
+ cur = cur.parentElement;
1222
+ }
1223
+ return fallback;
1224
+ };
1225
+ const _measureWidthCanvas = (srcNode, content) => {
1226
+ if (!_mctx || !content) return null;
1227
+ const family = _resolveFontAttr(srcNode, "font-family", "").replace(/['"]/g, "").trim();
1228
+ const weight = _resolveFontAttr(srcNode, "font-weight", "400");
1229
+ const style = _resolveFontAttr(srcNode, "font-style", "normal");
1230
+ const size = _resolveFontSize(srcNode);
1231
+ if (!family) return null;
1232
+ try {
1233
+ _mctx.font = `${style} ${weight} ${size}px "${family}"`;
1234
+ const w = _mctx.measureText(content).width;
1235
+ return Number.isFinite(w) && w > 0 ? w : null;
1236
+ } catch {
1237
+ return null;
1238
+ }
1239
+ };
1202
1240
  try {
1203
1241
  const srcTexts = Array.from(svg.querySelectorAll("text"));
1204
1242
  const liveTexts = Array.from(clone.querySelectorAll("text"));
@@ -1215,9 +1253,37 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1215
1253
  if (cleaned) node.setAttribute("style", cleaned);
1216
1254
  else node.removeAttribute("style");
1217
1255
  };
1218
- const bakeNode = (srcNode, liveNode, anchorOverride) => {
1256
+ const readInheritedX = (node) => {
1257
+ let cur = node;
1258
+ while (cur) {
1259
+ const v = cur.getAttribute("x");
1260
+ if (v) {
1261
+ const parsed = parseFloat(v.split(/[\s,]+/)[0]);
1262
+ return Number.isFinite(parsed) ? parsed : NaN;
1263
+ }
1264
+ cur = cur.parentElement;
1265
+ }
1266
+ return NaN;
1267
+ };
1268
+ const bakeNode = (srcNode, liveNode, anchorOverride, refXOverride) => {
1219
1269
  const anchor = (anchorOverride || _resolveAnchor(srcNode)).trim().toLowerCase();
1220
1270
  if (anchor !== "middle" && anchor !== "end") return;
1271
+ try {
1272
+ const content = srcNode.textContent || "";
1273
+ if (content.length > 0) {
1274
+ const width = _measureWidthCanvas(srcNode, content);
1275
+ const refX = Number.isFinite(refXOverride) ? refXOverride : readInheritedX(srcNode);
1276
+ if (width !== null && Number.isFinite(refX)) {
1277
+ const newX = anchor === "middle" ? refX - width / 2 : refX - width;
1278
+ srcNode.setAttribute("x", String(newX));
1279
+ srcNode.setAttribute("text-anchor", "start");
1280
+ stripTextAnchorStyle(srcNode);
1281
+ baked++;
1282
+ return;
1283
+ }
1284
+ }
1285
+ } catch {
1286
+ }
1221
1287
  try {
1222
1288
  const n = typeof liveNode.getNumberOfChars === "function" ? liveNode.getNumberOfChars() : 0;
1223
1289
  if (!n) return;
@@ -1233,9 +1299,15 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
1233
1299
  if (srcTspans.length > 0) {
1234
1300
  const parentAnchor = _resolveAnchor(srcText);
1235
1301
  const tspanAnchors = srcTspans.map((tspan) => _resolveAnchor(tspan));
1236
- bakeNode(srcText, liveText, parentAnchor);
1302
+ const parentRefX = readInheritedX(srcText);
1303
+ const tspanRefXs = srcTspans.map((tspan) => readInheritedX(tspan));
1237
1304
  for (let j = 0; j < srcTspans.length; j++) {
1238
- if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j]);
1305
+ const refX = Number.isFinite(tspanRefXs[j]) ? tspanRefXs[j] : parentRefX;
1306
+ if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j] || parentAnchor, refX);
1307
+ }
1308
+ if (parentAnchor === "middle" || parentAnchor === "end") {
1309
+ srcText.setAttribute("text-anchor", "start");
1310
+ stripTextAnchorStyle(srcText);
1239
1311
  }
1240
1312
  } else {
1241
1313
  bakeNode(srcText, liveText);
@@ -2405,7 +2477,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
2405
2477
  async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
2406
2478
  if (!colorMap || Object.keys(colorMap).length === 0) return null;
2407
2479
  try {
2408
- const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-D78ekQx5.cjs")).then((n) => n.canvasImageLoader);
2480
+ const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-C6IaOn7u.cjs")).then((n) => n.canvasImageLoader);
2409
2481
  return await getNormalizedSvgUrl(imageUrl, colorMap);
2410
2482
  } catch {
2411
2483
  return null;
@@ -3186,7 +3258,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
3186
3258
  }
3187
3259
  let fetchUrl = imageUrl;
3188
3260
  if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
3189
- const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-D78ekQx5.cjs")).then((n) => n.canvasImageLoader);
3261
+ const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-C6IaOn7u.cjs")).then((n) => n.canvasImageLoader);
3190
3262
  if (isPrivateUrl(imageUrl)) return null;
3191
3263
  const proxyUrl = new URL(`${index.API_URL}/image-proxy`);
3192
3264
  proxyUrl.searchParams.set("url", imageUrl);
@@ -5168,4 +5240,4 @@ exports.exportMultiPagePdf = exportMultiPagePdf;
5168
5240
  exports.logTextMeasurementDiagnostic = logTextMeasurementDiagnostic;
5169
5241
  exports.preparePagesForExport = preparePagesForExport;
5170
5242
  exports.rewriteSvgFontsForJsPDFWithSourceMeta = rewriteSvgFontsForJsPDFWithSourceMeta;
5171
- //# sourceMappingURL=vectorPdfExport-DmFmkPUr.cjs.map
5243
+ //# sourceMappingURL=vectorPdfExport-FwEcQIPB.cjs.map