@pixldocs/canvas-renderer 0.5.199 → 0.5.201
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-CyCjpD2N.js → index-CABGgEg5.js} +6 -6
- package/dist/{index-CyCjpD2N.js.map → index-CABGgEg5.js.map} +1 -1
- package/dist/{index-CEUoSPy-.cjs → index-RcI43b-V.cjs} +6 -6
- package/dist/{index-CEUoSPy-.cjs.map → index-RcI43b-V.cjs.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-D57BlzeZ.js → vectorPdfExport-CVpaZO9N.js} +128 -4
- package/dist/vectorPdfExport-CVpaZO9N.js.map +1 -0
- package/dist/{vectorPdfExport-Dq4rWmf6.cjs → vectorPdfExport-DQjvPb1v.cjs} +128 -4
- package/dist/vectorPdfExport-DQjvPb1v.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/vectorPdfExport-D57BlzeZ.js.map +0 -1
- package/dist/vectorPdfExport-Dq4rWmf6.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-RcI43b-V.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-CABGgEg5.js";
|
|
2
2
|
export {
|
|
3
3
|
D as DEPLOYMENT_VERSION_MARKER,
|
|
4
4
|
F as FONT_FALLBACK_DEVANAGARI,
|
|
@@ -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-CABGgEg5.js";
|
|
5
5
|
import { resetPdfFontRegistry, FONT_FALLBACK_SYMBOLS, FONT_FALLBACK_MATH, FONT_FALLBACK_DEVANAGARI, embedFontWithGoogleFallback, getEmbeddedVariantsList, isFontAvailable, isFamilyEmbedded, resolveBestRegisteredVariant, getEmbeddedJsPDFFontName, resolveFontWeight, doesVariantSupportChar } from "./pdfFonts-DhEaMTZl.js";
|
|
6
6
|
async function embedFontsForSvg(pdf, svgStr) {
|
|
7
7
|
var _a;
|
|
@@ -467,6 +467,129 @@ async function svg2pdfWithDomMount(svg, pdf, opts, options) {
|
|
|
467
467
|
function getSvgImageHref(image) {
|
|
468
468
|
return image.getAttribute("href") || image.getAttribute("xlink:href") || "";
|
|
469
469
|
}
|
|
470
|
+
function isSafariLikeForInlineJpegSvgPdf() {
|
|
471
|
+
try {
|
|
472
|
+
if (typeof navigator === "undefined") return false;
|
|
473
|
+
const ua = navigator.userAgent || "";
|
|
474
|
+
const vendor = navigator.vendor || "";
|
|
475
|
+
const isIOS = /iPad|iPhone|iPod/.test(ua) || /Macintosh/.test(ua) && Number(navigator.maxTouchPoints || 0) > 1;
|
|
476
|
+
const isSafariDesktop = /Safari/.test(ua) && /Apple/.test(vendor) && !/Chrome|CriOS|Chromium|Edg|FxiOS/.test(ua);
|
|
477
|
+
return isIOS || isSafariDesktop;
|
|
478
|
+
} catch {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function estimateDataUrlBytesForPdf(dataUrl) {
|
|
483
|
+
const comma = dataUrl.indexOf(",");
|
|
484
|
+
const payload = comma >= 0 ? dataUrl.slice(comma + 1) : dataUrl;
|
|
485
|
+
return Math.floor(payload.length * 0.75);
|
|
486
|
+
}
|
|
487
|
+
function parseSvgNumber(value) {
|
|
488
|
+
if (!value) return null;
|
|
489
|
+
const match = value.trim().match(/^-?\d+(?:\.\d+)?/);
|
|
490
|
+
if (!match) return null;
|
|
491
|
+
const n = Number(match[0]);
|
|
492
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
493
|
+
}
|
|
494
|
+
function getApproxSvgTransformScale(image) {
|
|
495
|
+
let sx = 1;
|
|
496
|
+
let sy = 1;
|
|
497
|
+
let cur = image;
|
|
498
|
+
while (cur && cur.tagName.toLowerCase() !== "svg") {
|
|
499
|
+
const transform = cur.getAttribute("transform") || "";
|
|
500
|
+
const matrix = transform.match(/matrix\(([^)]+)\)/i);
|
|
501
|
+
if (matrix) {
|
|
502
|
+
const parts = matrix[1].split(/[\s,]+/).map(Number).filter(Number.isFinite);
|
|
503
|
+
if (parts.length >= 4) {
|
|
504
|
+
sx *= Math.hypot(parts[0], parts[1]) || 1;
|
|
505
|
+
sy *= Math.hypot(parts[2], parts[3]) || 1;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
const scale = transform.match(/scale\(([^)]+)\)/i);
|
|
509
|
+
if (scale) {
|
|
510
|
+
const parts = scale[1].split(/[\s,]+/).map(Number).filter(Number.isFinite);
|
|
511
|
+
if (parts.length >= 1) {
|
|
512
|
+
sx *= parts[0] || 1;
|
|
513
|
+
sy *= (parts.length >= 2 ? parts[1] : parts[0]) || 1;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
cur = cur.parentElement;
|
|
517
|
+
}
|
|
518
|
+
return { x: Math.max(0.01, Math.abs(sx)), y: Math.max(0.01, Math.abs(sy)) };
|
|
519
|
+
}
|
|
520
|
+
async function rewriteSafariInlineJpegImagesToPng(svg) {
|
|
521
|
+
if (!isSafariLikeForInlineJpegSvgPdf() || typeof document === "undefined") return;
|
|
522
|
+
const jpegImages = Array.from(svg.querySelectorAll("image")).filter((image) => /^data:image\/jpe?g[;,]/i.test(getSvgImageHref(image)));
|
|
523
|
+
if (jpegImages.length === 0) return;
|
|
524
|
+
let rewritten = 0;
|
|
525
|
+
for (const image of jpegImages) {
|
|
526
|
+
const href = getSvgImageHref(image);
|
|
527
|
+
const decodeImage = (src) => new Promise((resolve) => {
|
|
528
|
+
const img = new Image();
|
|
529
|
+
img.onload = async () => {
|
|
530
|
+
try {
|
|
531
|
+
if (typeof img.decode === "function") await img.decode();
|
|
532
|
+
} catch {
|
|
533
|
+
}
|
|
534
|
+
resolve(img.naturalWidth > 0 && img.naturalHeight > 0 ? img : null);
|
|
535
|
+
};
|
|
536
|
+
img.onerror = () => resolve(null);
|
|
537
|
+
try {
|
|
538
|
+
img.src = src;
|
|
539
|
+
} catch {
|
|
540
|
+
resolve(null);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
let loaded = await decodeImage(href);
|
|
544
|
+
let blobUrl = null;
|
|
545
|
+
if (!loaded) {
|
|
546
|
+
try {
|
|
547
|
+
const blob = await (await fetch(href)).blob();
|
|
548
|
+
blobUrl = URL.createObjectURL(blob);
|
|
549
|
+
loaded = await decodeImage(blobUrl);
|
|
550
|
+
} catch {
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
if (!loaded) {
|
|
554
|
+
if (blobUrl) URL.revokeObjectURL(blobUrl);
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
const attrW = parseSvgNumber(image.getAttribute("width")) || loaded.naturalWidth || loaded.width;
|
|
558
|
+
const attrH = parseSvgNumber(image.getAttribute("height")) || loaded.naturalHeight || loaded.height;
|
|
559
|
+
const transformScale = getApproxSvgTransformScale(image);
|
|
560
|
+
const renderedW = attrW * transformScale.x;
|
|
561
|
+
const renderedH = attrH * transformScale.y;
|
|
562
|
+
const density = 2;
|
|
563
|
+
const maxEdge = 1800;
|
|
564
|
+
let targetW = Math.max(1, Math.round(Math.min(attrW, renderedW * density || attrW)));
|
|
565
|
+
let targetH = Math.max(1, Math.round(Math.min(attrH, renderedH * density || attrH)));
|
|
566
|
+
const longest = Math.max(targetW, targetH);
|
|
567
|
+
if (longest > maxEdge) {
|
|
568
|
+
const scale = maxEdge / longest;
|
|
569
|
+
targetW = Math.max(1, Math.round(targetW * scale));
|
|
570
|
+
targetH = Math.max(1, Math.round(targetH * scale));
|
|
571
|
+
}
|
|
572
|
+
let pngDataUrl = null;
|
|
573
|
+
for (const shrink of [1, 0.82, 0.68, 0.55]) {
|
|
574
|
+
const canvas = document.createElement("canvas");
|
|
575
|
+
canvas.width = Math.max(1, Math.round(targetW * shrink));
|
|
576
|
+
canvas.height = Math.max(1, Math.round(targetH * shrink));
|
|
577
|
+
const ctx = canvas.getContext("2d");
|
|
578
|
+
if (!ctx) break;
|
|
579
|
+
ctx.fillStyle = "#ffffff";
|
|
580
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
581
|
+
ctx.drawImage(loaded, 0, 0, canvas.width, canvas.height);
|
|
582
|
+
pngDataUrl = canvas.toDataURL("image/png");
|
|
583
|
+
if (estimateDataUrlBytesForPdf(pngDataUrl) <= 4e6 || shrink === 0.55) break;
|
|
584
|
+
}
|
|
585
|
+
if (blobUrl) URL.revokeObjectURL(blobUrl);
|
|
586
|
+
if (!pngDataUrl) continue;
|
|
587
|
+
image.setAttribute("href", pngDataUrl);
|
|
588
|
+
if (image.hasAttribute("xlink:href")) image.setAttribute("xlink:href", pngDataUrl);
|
|
589
|
+
rewritten++;
|
|
590
|
+
}
|
|
591
|
+
if (rewritten > 0) console.log(`[client-pdf-export] Safari-safe inline JPEG rewrite: ${rewritten} image(s) converted to PNG inside live SVG`);
|
|
592
|
+
}
|
|
470
593
|
async function preloadSvgImagesForPdf(svg, options) {
|
|
471
594
|
const images = Array.from(svg.querySelectorAll("image"));
|
|
472
595
|
if (!images.length) return;
|
|
@@ -1931,6 +2054,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
1931
2054
|
stripRootPageBackgroundFromSvg(svgToDraw);
|
|
1932
2055
|
}
|
|
1933
2056
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
2057
|
+
await rewriteSafariInlineJpegImagesToPng(svgToDraw);
|
|
1934
2058
|
try {
|
|
1935
2059
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
1936
2060
|
await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);
|
|
@@ -2554,7 +2678,7 @@ async function fetchSvgAsElement(imageUrl, colorMap) {
|
|
|
2554
2678
|
async function getRecoloredSvgDataUrl(imageUrl, colorMap) {
|
|
2555
2679
|
if (!colorMap || Object.keys(colorMap).length === 0) return null;
|
|
2556
2680
|
try {
|
|
2557
|
-
const { getNormalizedSvgUrl } = await import("./index-
|
|
2681
|
+
const { getNormalizedSvgUrl } = await import("./index-CABGgEg5.js").then((n) => n.a6);
|
|
2558
2682
|
return await getNormalizedSvgUrl(imageUrl, colorMap);
|
|
2559
2683
|
} catch {
|
|
2560
2684
|
return null;
|
|
@@ -3345,7 +3469,7 @@ async function fetchImageAsBase64(imageUrl, opts = {}) {
|
|
|
3345
3469
|
}
|
|
3346
3470
|
let fetchUrl = imageUrl;
|
|
3347
3471
|
if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
|
|
3348
|
-
const { isPrivateUrl } = await import("./index-
|
|
3472
|
+
const { isPrivateUrl } = await import("./index-CABGgEg5.js").then((n) => n.a6);
|
|
3349
3473
|
if (isPrivateUrl(imageUrl)) return null;
|
|
3350
3474
|
const proxyUrl = new URL(`${API_URL}/image-proxy`);
|
|
3351
3475
|
proxyUrl.searchParams.set("url", imageUrl);
|
|
@@ -5354,4 +5478,4 @@ export {
|
|
|
5354
5478
|
preparePagesForExport,
|
|
5355
5479
|
rewriteSvgFontsForJsPDFWithSourceMeta
|
|
5356
5480
|
};
|
|
5357
|
-
//# sourceMappingURL=vectorPdfExport-
|
|
5481
|
+
//# sourceMappingURL=vectorPdfExport-CVpaZO9N.js.map
|