@pixldocs/canvas-renderer 0.5.143 → 0.5.146
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-r5VzSOHa.cjs → index-DoPXmxDJ.cjs} +10 -6
- package/dist/index-DoPXmxDJ.cjs.map +1 -0
- package/dist/{index-CUpy7HO9.js → index-oR6VOGAL.js} +10 -6
- package/dist/index-oR6VOGAL.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-GvaizFte.js → vectorPdfExport-DI7k8pt7.js} +147 -8
- package/dist/vectorPdfExport-DI7k8pt7.js.map +1 -0
- package/dist/{vectorPdfExport-JVEe_tSQ.cjs → vectorPdfExport-SMvSP0el.cjs} +147 -8
- package/dist/vectorPdfExport-SMvSP0el.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/index-CUpy7HO9.js.map +0 -1
- package/dist/index-r5VzSOHa.cjs.map +0 -1
- package/dist/vectorPdfExport-GvaizFte.js.map +0 -1
- package/dist/vectorPdfExport-JVEe_tSQ.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index = require("./index-
|
|
3
|
+
const index = require("./index-DoPXmxDJ.cjs");
|
|
4
4
|
exports.FONT_FALLBACK_DEVANAGARI = index.FONT_FALLBACK_DEVANAGARI;
|
|
5
5
|
exports.FONT_FALLBACK_MATH = index.FONT_FALLBACK_MATH;
|
|
6
6
|
exports.FONT_FALLBACK_SYMBOLS = index.FONT_FALLBACK_SYMBOLS;
|
package/dist/index.d.ts
CHANGED
|
@@ -259,7 +259,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
|
|
|
259
259
|
* Package version banner. Bump alongside package.json so we can confirm
|
|
260
260
|
* (via browser:log) that the deployed bundle matches the expected build.
|
|
261
261
|
*/
|
|
262
|
-
export declare const PACKAGE_VERSION = "0.5.
|
|
262
|
+
export declare const PACKAGE_VERSION = "0.5.145";
|
|
263
263
|
|
|
264
264
|
export declare interface PageSettings {
|
|
265
265
|
backgroundColor?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F, o, q, s, P, t, u, v, w, x, y, z, B, C, D, E, G, H, I, J, K, b, L, M, N, O, Q, R, S, U, V, W, X, Y, Z } from "./index-
|
|
1
|
+
import { F, o, q, s, P, t, u, v, w, x, y, z, B, C, D, E, G, H, I, J, K, b, L, M, N, O, Q, R, S, U, V, W, X, Y, Z } from "./index-oR6VOGAL.js";
|
|
2
2
|
export {
|
|
3
3
|
F as FONT_FALLBACK_DEVANAGARI,
|
|
4
4
|
o as FONT_FALLBACK_MATH,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsPDF, ShadingPattern } from "jspdf";
|
|
2
2
|
import { svg2pdf } from "svg2pdf.js";
|
|
3
3
|
import * as fabric from "fabric";
|
|
4
|
-
import { g as getCanvasForPage, c as captureFabricCanvasSvgForPdf, f as findNodeById, a as getAbsoluteBounds, p as parseTextMarkdown, r as renderSmartElementToSvg, n as normalizeShapeType, h as hasEdgeFade, b as getProxiedImageUrl, d as bakeEdgeFade, i as isElement, e as isGroup, j as buildRoundedTrianglePath, A as API_URL, k as getImageProxyFetchOptions, l as getRoundedRectRadii, T as TRIANGLE_STROKE_MITER_LIMIT, m as getTrianglePoints } from "./index-
|
|
4
|
+
import { g as getCanvasForPage, c as captureFabricCanvasSvgForPdf, f as findNodeById, a as getAbsoluteBounds, p as parseTextMarkdown, r as renderSmartElementToSvg, n as normalizeShapeType, h as hasEdgeFade, b as getProxiedImageUrl, d as bakeEdgeFade, i as isElement, e as isGroup, j as buildRoundedTrianglePath, A as API_URL, k as getImageProxyFetchOptions, l as getRoundedRectRadii, T as TRIANGLE_STROKE_MITER_LIMIT, m as getTrianglePoints } from "./index-oR6VOGAL.js";
|
|
5
5
|
import { resetPdfFontRegistry, FONT_FALLBACK_SYMBOLS, FONT_FALLBACK_MATH, FONT_FALLBACK_DEVANAGARI, embedFontWithGoogleFallback, getEmbeddedVariantsList, isFontAvailable, isFamilyEmbedded, resolveBestRegisteredVariant, getEmbeddedJsPDFFontName, resolveFontWeight, doesVariantSupportChar } from "./pdfFonts-b3_bv7F0.js";
|
|
6
6
|
async function embedFontsForSvg(pdf, svgStr) {
|
|
7
7
|
var _a;
|
|
@@ -123,6 +123,33 @@ const yieldToUI = () => new Promise((resolve) => {
|
|
|
123
123
|
requestAnimationFrame(() => setTimeout(resolve, 0));
|
|
124
124
|
});
|
|
125
125
|
const SHADOW_RASTER_ALPHA_COMPENSATION = 0.84;
|
|
126
|
+
function collectFontSpecsFromShadowMarkup(markup) {
|
|
127
|
+
const specs = /* @__PURE__ */ new Set();
|
|
128
|
+
const re = /<(?:text|tspan)\b[^>]*>/gi;
|
|
129
|
+
let match;
|
|
130
|
+
while ((match = re.exec(markup)) !== null) {
|
|
131
|
+
const tag = match[0];
|
|
132
|
+
const get = (attr) => {
|
|
133
|
+
const m = tag.match(new RegExp(`\\s${attr}\\s*=\\s*"([^"]*)"`, "i"));
|
|
134
|
+
if (m) return m[1];
|
|
135
|
+
const styleM = tag.match(/\sstyle\s*=\s*"([^"]*)"/i);
|
|
136
|
+
if (styleM) {
|
|
137
|
+
const sm = styleM[1].match(new RegExp(`${attr}\\s*:\\s*([^;]+)`, "i"));
|
|
138
|
+
if (sm) return sm[1].trim();
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
};
|
|
142
|
+
const family = (get("font-family") || "").split(",")[0].replace(/['"]/g, "").trim();
|
|
143
|
+
if (!family) continue;
|
|
144
|
+
const weight = get("font-weight") || "400";
|
|
145
|
+
const style = get("font-style") || "normal";
|
|
146
|
+
const size = get("font-size") || "16px";
|
|
147
|
+
const sizePx = /[a-z%]/i.test(size) ? size : `${size}px`;
|
|
148
|
+
const famSpec = /\s/.test(family) ? `"${family}"` : family;
|
|
149
|
+
specs.add(`${style} ${weight} ${sizePx} ${famSpec}`);
|
|
150
|
+
}
|
|
151
|
+
return Array.from(specs);
|
|
152
|
+
}
|
|
126
153
|
let debugSvgDrawSequence = 0;
|
|
127
154
|
function debugLog(...args) {
|
|
128
155
|
}
|
|
@@ -1208,6 +1235,105 @@ async function bakeTextAnchorPositionsFromLiveSvg(svg) {
|
|
|
1208
1235
|
}
|
|
1209
1236
|
}
|
|
1210
1237
|
}
|
|
1238
|
+
async function logTextMeasurementDiagnostic(svg) {
|
|
1239
|
+
var _a, _b, _c, _d, _e;
|
|
1240
|
+
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
1241
|
+
try {
|
|
1242
|
+
const params = new URLSearchParams(((_a = window.location) == null ? void 0 : _a.search) || "");
|
|
1243
|
+
if (params.get("pdfdiag") !== "1") return;
|
|
1244
|
+
} catch {
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
if (!svg) return;
|
|
1248
|
+
const tempContainer = document.createElement("div");
|
|
1249
|
+
tempContainer.style.cssText = "position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;";
|
|
1250
|
+
const clone = svg.cloneNode(true);
|
|
1251
|
+
for (const tn of clone.querySelectorAll("text, tspan, textPath")) {
|
|
1252
|
+
const sf = tn.getAttribute("data-source-font-family");
|
|
1253
|
+
const sw = tn.getAttribute("data-source-font-weight");
|
|
1254
|
+
const ss = tn.getAttribute("data-source-font-style");
|
|
1255
|
+
if (sf) tn.setAttribute("font-family", sf);
|
|
1256
|
+
if (sw) tn.setAttribute("font-weight", sw);
|
|
1257
|
+
if (ss) tn.setAttribute("font-style", ss);
|
|
1258
|
+
}
|
|
1259
|
+
tempContainer.appendChild(clone);
|
|
1260
|
+
document.body.appendChild(tempContainer);
|
|
1261
|
+
const measureCanvas = document.createElement("canvas");
|
|
1262
|
+
const mctx = measureCanvas.getContext("2d");
|
|
1263
|
+
try {
|
|
1264
|
+
const liveTexts = Array.from(clone.querySelectorAll("text"));
|
|
1265
|
+
const srcTexts = Array.from(svg.querySelectorAll("text"));
|
|
1266
|
+
const rows = [];
|
|
1267
|
+
for (let i = 0; i < liveTexts.length; i++) {
|
|
1268
|
+
const live = liveTexts[i];
|
|
1269
|
+
const src = srcTexts[i];
|
|
1270
|
+
if (!live || !src) continue;
|
|
1271
|
+
const liveTspans = Array.from(live.querySelectorAll("tspan"));
|
|
1272
|
+
const srcTspans = Array.from(src.querySelectorAll("tspan"));
|
|
1273
|
+
const tspans = liveTspans.length ? liveTspans : [live];
|
|
1274
|
+
const srcs = srcTspans.length ? srcTspans : [src];
|
|
1275
|
+
for (let j = 0; j < tspans.length; j++) {
|
|
1276
|
+
const ln = tspans[j];
|
|
1277
|
+
const sn = srcs[j];
|
|
1278
|
+
const text = ln.textContent || "";
|
|
1279
|
+
const fam = (ln.getAttribute("font-family") || "").replace(/['"]/g, "").trim();
|
|
1280
|
+
const wt = ln.getAttribute("font-weight") || "400";
|
|
1281
|
+
const sty = ln.getAttribute("font-style") || "normal";
|
|
1282
|
+
const sz = parseFloat(ln.getAttribute("font-size") || src.getAttribute("font-size") || "16") || 16;
|
|
1283
|
+
let domX = null;
|
|
1284
|
+
let bboxW = null;
|
|
1285
|
+
try {
|
|
1286
|
+
if (ln.getNumberOfChars && ln.getNumberOfChars() > 0) {
|
|
1287
|
+
domX = ln.getStartPositionOfChar(0).x;
|
|
1288
|
+
}
|
|
1289
|
+
} catch {
|
|
1290
|
+
}
|
|
1291
|
+
try {
|
|
1292
|
+
bboxW = ((_b = ln.getBBox) == null ? void 0 : _b.call(ln).width) ?? null;
|
|
1293
|
+
} catch {
|
|
1294
|
+
}
|
|
1295
|
+
let canvasW = null;
|
|
1296
|
+
if (mctx) {
|
|
1297
|
+
mctx.font = `${sty} ${wt} ${sz}px "${fam}"`;
|
|
1298
|
+
try {
|
|
1299
|
+
canvasW = mctx.measureText(text).width;
|
|
1300
|
+
} catch {
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
rows.push({
|
|
1304
|
+
line: text.length > 40 ? text.slice(0, 37) + "..." : text,
|
|
1305
|
+
font: `${fam} ${wt} ${sty}`,
|
|
1306
|
+
size: sz,
|
|
1307
|
+
srcAnchor: sn.getAttribute("text-anchor") || ((_c = sn.parentElement) == null ? void 0 : _c.getAttribute("text-anchor")) || "",
|
|
1308
|
+
srcX: sn.getAttribute("x") || ((_d = sn.parentElement) == null ? void 0 : _d.getAttribute("x")) || "",
|
|
1309
|
+
domX: domX !== null ? +domX.toFixed(2) : null,
|
|
1310
|
+
bboxW: bboxW !== null ? +bboxW.toFixed(2) : null,
|
|
1311
|
+
measureCtxW: canvasW !== null ? +canvasW.toFixed(2) : null
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
if (rows.length > 0) {
|
|
1316
|
+
console.log("[PDF-DIAG] ===== text measurement diagnostic =====");
|
|
1317
|
+
console.log(
|
|
1318
|
+
"[PDF-DIAG] env=",
|
|
1319
|
+
typeof navigator !== "undefined" ? navigator.userAgent.slice(0, 80) : "n/a",
|
|
1320
|
+
"dpr=",
|
|
1321
|
+
window.devicePixelRatio,
|
|
1322
|
+
"fontsReady=",
|
|
1323
|
+
!!((_e = document.fonts) == null ? void 0 : _e.ready)
|
|
1324
|
+
);
|
|
1325
|
+
for (const r of rows) {
|
|
1326
|
+
console.log("[PDF-DIAG]", JSON.stringify(r));
|
|
1327
|
+
}
|
|
1328
|
+
console.log("[PDF-DIAG] ===== end =====");
|
|
1329
|
+
}
|
|
1330
|
+
} finally {
|
|
1331
|
+
try {
|
|
1332
|
+
document.body.removeChild(tempContainer);
|
|
1333
|
+
} catch {
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1211
1337
|
async function _convertTextDecorationsToLines_impl(svg) {
|
|
1212
1338
|
const doc = svg.ownerDocument;
|
|
1213
1339
|
if (!doc) return;
|
|
@@ -1404,7 +1530,7 @@ async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
|
1404
1530
|
}
|
|
1405
1531
|
}
|
|
1406
1532
|
async function rasterizeShadowMarkers(svg) {
|
|
1407
|
-
var _a, _b, _c, _d, _e;
|
|
1533
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1408
1534
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
1409
1535
|
const markers = Array.from(svg.querySelectorAll("g.__pdShadowRaster"));
|
|
1410
1536
|
if (markers.length === 0) return;
|
|
@@ -1431,6 +1557,17 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
1431
1557
|
const innerXml = restoreSourceFontsForShadowRaster(
|
|
1432
1558
|
Array.from(marker.childNodes).map((n) => n instanceof Element ? new XMLSerializer().serializeToString(n) : "").join("")
|
|
1433
1559
|
);
|
|
1560
|
+
try {
|
|
1561
|
+
const fontSpecs = collectFontSpecsFromShadowMarkup(innerXml);
|
|
1562
|
+
if (fontSpecs.length > 0 && ((_c = document.fonts) == null ? void 0 : _c.load)) {
|
|
1563
|
+
await Promise.all(
|
|
1564
|
+
fontSpecs.map(
|
|
1565
|
+
(spec) => document.fonts.load(spec).catch(() => void 0)
|
|
1566
|
+
)
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
} catch {
|
|
1570
|
+
}
|
|
1434
1571
|
const scale = 2;
|
|
1435
1572
|
const pxW = Math.min(4096, Math.max(8, Math.ceil(bw * scale)));
|
|
1436
1573
|
const pxH = Math.min(4096, Math.max(8, Math.ceil(bh * scale)));
|
|
@@ -1440,7 +1577,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
1440
1577
|
const miniSvg = `<svg xmlns="${SVG_NS}" xmlns:xlink="${XLINK_NS}" width="${pxW}" height="${pxH}" viewBox="${bx} ${by} ${bw} ${bh}">${styleBlock}<defs><filter id="${filterId}" filterUnits="userSpaceOnUse" x="${bx}" y="${by}" width="${bw}" height="${bh}" color-interpolation-filters="sRGB"><feOffset dx="${ox}" dy="${oy}" result="offsetShadow" /><feGaussianBlur in="offsetShadow" stdDeviation="${stdDev}" /></filter></defs><g filter="url(#${filterId})">${innerXml}</g></svg>`;
|
|
1441
1578
|
const dataUrl = await rasterSvgToPngDataUrl(miniSvg, pxW, pxH);
|
|
1442
1579
|
if (!dataUrl) {
|
|
1443
|
-
(
|
|
1580
|
+
(_d = marker.parentNode) == null ? void 0 : _d.removeChild(marker);
|
|
1444
1581
|
continue;
|
|
1445
1582
|
}
|
|
1446
1583
|
const img = svg.ownerDocument.createElementNS(SVG_NS, "image");
|
|
@@ -1452,11 +1589,11 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
1452
1589
|
img.setAttribute("preserveAspectRatio", "none");
|
|
1453
1590
|
img.setAttributeNS(XLINK_NS, "xlink:href", dataUrl);
|
|
1454
1591
|
img.setAttribute("href", dataUrl);
|
|
1455
|
-
(
|
|
1592
|
+
(_e = marker.parentNode) == null ? void 0 : _e.replaceChild(img, marker);
|
|
1456
1593
|
} catch (error) {
|
|
1457
1594
|
console.warn("[Vector PDF] text shadow rasterization failed for one marker:", error);
|
|
1458
1595
|
try {
|
|
1459
|
-
(
|
|
1596
|
+
(_f = marker.parentNode) == null ? void 0 : _f.removeChild(marker);
|
|
1460
1597
|
} catch {
|
|
1461
1598
|
}
|
|
1462
1599
|
}
|
|
@@ -1658,6 +1795,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
1658
1795
|
}
|
|
1659
1796
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
1660
1797
|
try {
|
|
1798
|
+
await logTextMeasurementDiagnostic(svgToDraw);
|
|
1661
1799
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
1662
1800
|
} catch (e) {
|
|
1663
1801
|
console.warn("[Vector PDF] anchor-bake pass failed (continuing):", e);
|
|
@@ -2248,7 +2386,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
|
|
|
2248
2386
|
async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
|
|
2249
2387
|
if (!colorMap || Object.keys(colorMap).length === 0) return null;
|
|
2250
2388
|
try {
|
|
2251
|
-
const { getNormalizedSvgUrl } = await import("./index-
|
|
2389
|
+
const { getNormalizedSvgUrl } = await import("./index-oR6VOGAL.js").then((n) => n._);
|
|
2252
2390
|
return await getNormalizedSvgUrl(imageUrl, colorMap);
|
|
2253
2391
|
} catch {
|
|
2254
2392
|
return null;
|
|
@@ -3029,7 +3167,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
|
|
|
3029
3167
|
}
|
|
3030
3168
|
let fetchUrl = imageUrl;
|
|
3031
3169
|
if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
|
|
3032
|
-
const { isPrivateUrl } = await import("./index-
|
|
3170
|
+
const { isPrivateUrl } = await import("./index-oR6VOGAL.js").then((n) => n._);
|
|
3033
3171
|
if (isPrivateUrl(imageUrl)) return null;
|
|
3034
3172
|
const proxyUrl = new URL(`${API_URL}/image-proxy`);
|
|
3035
3173
|
proxyUrl.searchParams.set("url", imageUrl);
|
|
@@ -5009,7 +5147,8 @@ export {
|
|
|
5009
5147
|
embedFontsForSvg,
|
|
5010
5148
|
exportFabricCanvasToVectorPdf,
|
|
5011
5149
|
exportMultiPagePdf,
|
|
5150
|
+
logTextMeasurementDiagnostic,
|
|
5012
5151
|
preparePagesForExport,
|
|
5013
5152
|
rewriteSvgFontsForJsPDFWithSourceMeta
|
|
5014
5153
|
};
|
|
5015
|
-
//# sourceMappingURL=vectorPdfExport-
|
|
5154
|
+
//# sourceMappingURL=vectorPdfExport-DI7k8pt7.js.map
|