@pixldocs/canvas-renderer 0.5.200 → 0.5.202
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-oOW9gtoq.js → index-BVNRSs-v.js} +12 -8
- package/dist/{index-oOW9gtoq.js.map → index-BVNRSs-v.js.map} +1 -1
- package/dist/{index-B0b3u83I.cjs → index-BfMO-VrX.cjs} +12 -8
- package/dist/{index-B0b3u83I.cjs.map → index-BfMO-VrX.cjs.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CV6GxECJ.cjs → vectorPdfExport-DCyVRj7e.cjs} +128 -4
- package/dist/vectorPdfExport-DCyVRj7e.cjs.map +1 -0
- package/dist/{vectorPdfExport-BLeFZX_c.js → vectorPdfExport-Gj3lwAgo.js} +128 -4
- package/dist/vectorPdfExport-Gj3lwAgo.js.map +1 -0
- package/package.json +1 -1
- package/dist/vectorPdfExport-BLeFZX_c.js.map +0 -1
- package/dist/vectorPdfExport-CV6GxECJ.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-BfMO-VrX.cjs");
|
|
4
4
|
exports.DEPLOYMENT_VERSION_MARKER = index.DEPLOYMENT_VERSION_MARKER;
|
|
5
5
|
exports.FONT_FALLBACK_DEVANAGARI = index.FONT_FALLBACK_DEVANAGARI;
|
|
6
6
|
exports.FONT_FALLBACK_MATH = index.FONT_FALLBACK_MATH;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D, F, o, q, s, P, t, u, v, w, x, y, z, B, C, E, G, H, I, J, K, L, M, b, N, O, Q, R, S, U, V, W, X, Y, Z, _, $, a0, a1, a2, a3, a4, a5 } from "./index-
|
|
1
|
+
import { D, F, o, q, s, P, t, u, v, w, x, y, z, B, C, E, G, H, I, J, K, L, M, b, N, O, Q, R, S, U, V, W, X, Y, Z, _, $, a0, a1, a2, a3, a4, a5 } from "./index-BVNRSs-v.js";
|
|
2
2
|
export {
|
|
3
3
|
D as DEPLOYMENT_VERSION_MARKER,
|
|
4
4
|
F as FONT_FALLBACK_DEVANAGARI,
|
|
@@ -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-
|
|
6
|
+
const index = require("./index-BfMO-VrX.cjs");
|
|
7
7
|
const pdfFonts = require("./pdfFonts-BTj2f465.cjs");
|
|
8
8
|
function _interopNamespaceDefault(e) {
|
|
9
9
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -486,6 +486,129 @@ async function svg2pdfWithDomMount(svg, pdf, opts, options) {
|
|
|
486
486
|
function getSvgImageHref(image) {
|
|
487
487
|
return image.getAttribute("href") || image.getAttribute("xlink:href") || "";
|
|
488
488
|
}
|
|
489
|
+
function isSafariLikeForInlineJpegSvgPdf() {
|
|
490
|
+
try {
|
|
491
|
+
if (typeof navigator === "undefined") return false;
|
|
492
|
+
const ua = navigator.userAgent || "";
|
|
493
|
+
const vendor = navigator.vendor || "";
|
|
494
|
+
const isIOS = /iPad|iPhone|iPod/.test(ua) || /Macintosh/.test(ua) && Number(navigator.maxTouchPoints || 0) > 1;
|
|
495
|
+
const isSafariDesktop = /Safari/.test(ua) && /Apple/.test(vendor) && !/Chrome|CriOS|Chromium|Edg|FxiOS/.test(ua);
|
|
496
|
+
return isIOS || isSafariDesktop;
|
|
497
|
+
} catch {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function estimateDataUrlBytesForPdf(dataUrl) {
|
|
502
|
+
const comma = dataUrl.indexOf(",");
|
|
503
|
+
const payload = comma >= 0 ? dataUrl.slice(comma + 1) : dataUrl;
|
|
504
|
+
return Math.floor(payload.length * 0.75);
|
|
505
|
+
}
|
|
506
|
+
function parseSvgNumber(value) {
|
|
507
|
+
if (!value) return null;
|
|
508
|
+
const match = value.trim().match(/^-?\d+(?:\.\d+)?/);
|
|
509
|
+
if (!match) return null;
|
|
510
|
+
const n = Number(match[0]);
|
|
511
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
512
|
+
}
|
|
513
|
+
function getApproxSvgTransformScale(image) {
|
|
514
|
+
let sx = 1;
|
|
515
|
+
let sy = 1;
|
|
516
|
+
let cur = image;
|
|
517
|
+
while (cur && cur.tagName.toLowerCase() !== "svg") {
|
|
518
|
+
const transform = cur.getAttribute("transform") || "";
|
|
519
|
+
const matrix = transform.match(/matrix\(([^)]+)\)/i);
|
|
520
|
+
if (matrix) {
|
|
521
|
+
const parts = matrix[1].split(/[\s,]+/).map(Number).filter(Number.isFinite);
|
|
522
|
+
if (parts.length >= 4) {
|
|
523
|
+
sx *= Math.hypot(parts[0], parts[1]) || 1;
|
|
524
|
+
sy *= Math.hypot(parts[2], parts[3]) || 1;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const scale = transform.match(/scale\(([^)]+)\)/i);
|
|
528
|
+
if (scale) {
|
|
529
|
+
const parts = scale[1].split(/[\s,]+/).map(Number).filter(Number.isFinite);
|
|
530
|
+
if (parts.length >= 1) {
|
|
531
|
+
sx *= parts[0] || 1;
|
|
532
|
+
sy *= (parts.length >= 2 ? parts[1] : parts[0]) || 1;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
cur = cur.parentElement;
|
|
536
|
+
}
|
|
537
|
+
return { x: Math.max(0.01, Math.abs(sx)), y: Math.max(0.01, Math.abs(sy)) };
|
|
538
|
+
}
|
|
539
|
+
async function rewriteSafariInlineJpegImagesToPng(svg) {
|
|
540
|
+
if (!isSafariLikeForInlineJpegSvgPdf() || typeof document === "undefined") return;
|
|
541
|
+
const jpegImages = Array.from(svg.querySelectorAll("image")).filter((image) => /^data:image\/jpe?g[;,]/i.test(getSvgImageHref(image)));
|
|
542
|
+
if (jpegImages.length === 0) return;
|
|
543
|
+
let rewritten = 0;
|
|
544
|
+
for (const image of jpegImages) {
|
|
545
|
+
const href = getSvgImageHref(image);
|
|
546
|
+
const decodeImage = (src) => new Promise((resolve) => {
|
|
547
|
+
const img = new Image();
|
|
548
|
+
img.onload = async () => {
|
|
549
|
+
try {
|
|
550
|
+
if (typeof img.decode === "function") await img.decode();
|
|
551
|
+
} catch {
|
|
552
|
+
}
|
|
553
|
+
resolve(img.naturalWidth > 0 && img.naturalHeight > 0 ? img : null);
|
|
554
|
+
};
|
|
555
|
+
img.onerror = () => resolve(null);
|
|
556
|
+
try {
|
|
557
|
+
img.src = src;
|
|
558
|
+
} catch {
|
|
559
|
+
resolve(null);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
let loaded = await decodeImage(href);
|
|
563
|
+
let blobUrl = null;
|
|
564
|
+
if (!loaded) {
|
|
565
|
+
try {
|
|
566
|
+
const blob = await (await fetch(href)).blob();
|
|
567
|
+
blobUrl = URL.createObjectURL(blob);
|
|
568
|
+
loaded = await decodeImage(blobUrl);
|
|
569
|
+
} catch {
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (!loaded) {
|
|
573
|
+
if (blobUrl) URL.revokeObjectURL(blobUrl);
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const attrW = parseSvgNumber(image.getAttribute("width")) || loaded.naturalWidth || loaded.width;
|
|
577
|
+
const attrH = parseSvgNumber(image.getAttribute("height")) || loaded.naturalHeight || loaded.height;
|
|
578
|
+
const transformScale = getApproxSvgTransformScale(image);
|
|
579
|
+
const renderedW = attrW * transformScale.x;
|
|
580
|
+
const renderedH = attrH * transformScale.y;
|
|
581
|
+
const density = 2;
|
|
582
|
+
const maxEdge = 1800;
|
|
583
|
+
let targetW = Math.max(1, Math.round(Math.min(attrW, renderedW * density || attrW)));
|
|
584
|
+
let targetH = Math.max(1, Math.round(Math.min(attrH, renderedH * density || attrH)));
|
|
585
|
+
const longest = Math.max(targetW, targetH);
|
|
586
|
+
if (longest > maxEdge) {
|
|
587
|
+
const scale = maxEdge / longest;
|
|
588
|
+
targetW = Math.max(1, Math.round(targetW * scale));
|
|
589
|
+
targetH = Math.max(1, Math.round(targetH * scale));
|
|
590
|
+
}
|
|
591
|
+
let pngDataUrl = null;
|
|
592
|
+
for (const shrink of [1, 0.82, 0.68, 0.55]) {
|
|
593
|
+
const canvas = document.createElement("canvas");
|
|
594
|
+
canvas.width = Math.max(1, Math.round(targetW * shrink));
|
|
595
|
+
canvas.height = Math.max(1, Math.round(targetH * shrink));
|
|
596
|
+
const ctx = canvas.getContext("2d");
|
|
597
|
+
if (!ctx) break;
|
|
598
|
+
ctx.fillStyle = "#ffffff";
|
|
599
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
600
|
+
ctx.drawImage(loaded, 0, 0, canvas.width, canvas.height);
|
|
601
|
+
pngDataUrl = canvas.toDataURL("image/png");
|
|
602
|
+
if (estimateDataUrlBytesForPdf(pngDataUrl) <= 4e6 || shrink === 0.55) break;
|
|
603
|
+
}
|
|
604
|
+
if (blobUrl) URL.revokeObjectURL(blobUrl);
|
|
605
|
+
if (!pngDataUrl) continue;
|
|
606
|
+
image.setAttribute("href", pngDataUrl);
|
|
607
|
+
if (image.hasAttribute("xlink:href")) image.setAttribute("xlink:href", pngDataUrl);
|
|
608
|
+
rewritten++;
|
|
609
|
+
}
|
|
610
|
+
if (rewritten > 0) console.log(`[client-pdf-export] Safari-safe inline JPEG rewrite: ${rewritten} image(s) converted to PNG inside live SVG`);
|
|
611
|
+
}
|
|
489
612
|
async function preloadSvgImagesForPdf(svg, options) {
|
|
490
613
|
const images = Array.from(svg.querySelectorAll("image"));
|
|
491
614
|
if (!images.length) return;
|
|
@@ -1950,6 +2073,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
1950
2073
|
stripRootPageBackgroundFromSvg(svgToDraw);
|
|
1951
2074
|
}
|
|
1952
2075
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
2076
|
+
await rewriteSafariInlineJpegImagesToPng(svgToDraw);
|
|
1953
2077
|
try {
|
|
1954
2078
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
1955
2079
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
@@ -2573,7 +2697,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
|
|
|
2573
2697
|
async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
|
|
2574
2698
|
if (!colorMap || Object.keys(colorMap).length === 0) return null;
|
|
2575
2699
|
try {
|
|
2576
|
-
const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-
|
|
2700
|
+
const { getNormalizedSvgUrl } = await Promise.resolve().then(() => require("./index-BfMO-VrX.cjs")).then((n) => n.canvasImageLoader);
|
|
2577
2701
|
return await getNormalizedSvgUrl(imageUrl, colorMap);
|
|
2578
2702
|
} catch {
|
|
2579
2703
|
return null;
|
|
@@ -3364,7 +3488,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
|
|
|
3364
3488
|
}
|
|
3365
3489
|
let fetchUrl = imageUrl;
|
|
3366
3490
|
if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
|
|
3367
|
-
const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-
|
|
3491
|
+
const { isPrivateUrl } = await Promise.resolve().then(() => require("./index-BfMO-VrX.cjs")).then((n) => n.canvasImageLoader);
|
|
3368
3492
|
if (isPrivateUrl(imageUrl)) return null;
|
|
3369
3493
|
const proxyUrl = new URL(`${index.API_URL}/image-proxy`);
|
|
3370
3494
|
proxyUrl.searchParams.set("url", imageUrl);
|
|
@@ -5371,4 +5495,4 @@ exports.exportMultiPagePdf = exportMultiPagePdf;
|
|
|
5371
5495
|
exports.logTextMeasurementDiagnostic = logTextMeasurementDiagnostic;
|
|
5372
5496
|
exports.preparePagesForExport = preparePagesForExport;
|
|
5373
5497
|
exports.rewriteSvgFontsForJsPDFWithSourceMeta = rewriteSvgFontsForJsPDFWithSourceMeta;
|
|
5374
|
-
//# sourceMappingURL=vectorPdfExport-
|
|
5498
|
+
//# sourceMappingURL=vectorPdfExport-DCyVRj7e.cjs.map
|