@pixldocs/canvas-renderer 0.5.68 → 0.5.70
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.cjs +107 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +107 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -87,6 +87,8 @@ export declare function collectImageUrls(config: TemplateConfig): string[];
|
|
|
87
87
|
*/
|
|
88
88
|
export declare function configHasAutoShrinkText(config: TemplateConfig | null | undefined): boolean;
|
|
89
89
|
|
|
90
|
+
export declare function dumpSvgTextDiagnostics(svgStr: string, pageIndex: number, tag: string, stage: string, maxItems?: number): void;
|
|
91
|
+
|
|
90
92
|
export declare interface DynamicField {
|
|
91
93
|
id: string;
|
|
92
94
|
label: string;
|
|
@@ -254,7 +256,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
|
|
|
254
256
|
* Package version banner. Bump alongside package.json so we can confirm
|
|
255
257
|
* (via browser:log) that the deployed bundle matches the expected build.
|
|
256
258
|
*/
|
|
257
|
-
export declare const PACKAGE_VERSION = "0.5.
|
|
259
|
+
export declare const PACKAGE_VERSION = "0.5.70";
|
|
258
260
|
|
|
259
261
|
export declare interface PageSettings {
|
|
260
262
|
backgroundColor?: string;
|
package/dist/index.js
CHANGED
|
@@ -12982,6 +12982,19 @@ function injectLocalFontFaces(rawFontFamily) {
|
|
|
12982
12982
|
document.head.appendChild(style);
|
|
12983
12983
|
return true;
|
|
12984
12984
|
}
|
|
12985
|
+
async function awaitLocalFontFace(rawFontFamily, timeoutMs = 1600) {
|
|
12986
|
+
if (typeof document === "undefined" || !document.fonts) return false;
|
|
12987
|
+
const fontFamily = normalizeFontFamily(rawFontFamily);
|
|
12988
|
+
if (!injectLocalFontFaces(fontFamily)) return false;
|
|
12989
|
+
const weights = [400, 700];
|
|
12990
|
+
const loads = Promise.all(
|
|
12991
|
+
weights.map((weight) => document.fonts.load(`${weight} 16px "${fontFamily}"`))
|
|
12992
|
+
).then(() => document.fonts.check(`400 16px "${fontFamily}"`));
|
|
12993
|
+
return await Promise.race([
|
|
12994
|
+
loads.catch(() => false),
|
|
12995
|
+
new Promise((resolve) => setTimeout(() => resolve(false), timeoutMs))
|
|
12996
|
+
]);
|
|
12997
|
+
}
|
|
12985
12998
|
function withTimeout(promise, timeoutMs = 4e3) {
|
|
12986
12999
|
let timeoutId;
|
|
12987
13000
|
return Promise.race([
|
|
@@ -13002,7 +13015,7 @@ async function loadGoogleFontCSS(rawFontFamily) {
|
|
|
13002
13015
|
if (existing) return existing;
|
|
13003
13016
|
const promise = (async () => {
|
|
13004
13017
|
try {
|
|
13005
|
-
if (
|
|
13018
|
+
if (await awaitLocalFontFace(fontFamily)) {
|
|
13006
13019
|
loadedFonts.add(fontFamily);
|
|
13007
13020
|
return;
|
|
13008
13021
|
}
|
|
@@ -13128,7 +13141,7 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
13128
13141
|
if (typeof document === "undefined") return;
|
|
13129
13142
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
13130
13143
|
const families = new Set(descriptors.map((d) => d.family));
|
|
13131
|
-
|
|
13144
|
+
await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 3500);
|
|
13132
13145
|
if (document.fonts) {
|
|
13133
13146
|
descriptors.forEach((d) => {
|
|
13134
13147
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
@@ -13157,7 +13170,7 @@ function configHasAutoShrinkText$1(config) {
|
|
|
13157
13170
|
}
|
|
13158
13171
|
async function awaitFontsForConfig(config, maxWaitMs) {
|
|
13159
13172
|
if (typeof document === "undefined" || !document.fonts) return;
|
|
13160
|
-
|
|
13173
|
+
await ensureFontsForResolvedConfig(config);
|
|
13161
13174
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
13162
13175
|
if (descriptors.length === 0) return;
|
|
13163
13176
|
const loads = Promise.all(
|
|
@@ -13399,7 +13412,7 @@ function PixldocsPreview(props) {
|
|
|
13399
13412
|
!canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
13400
13413
|
] });
|
|
13401
13414
|
}
|
|
13402
|
-
const PACKAGE_VERSION = "0.5.
|
|
13415
|
+
const PACKAGE_VERSION = "0.5.70";
|
|
13403
13416
|
let __underlineFixInstalled = false;
|
|
13404
13417
|
function installUnderlineFix(fab) {
|
|
13405
13418
|
var _a;
|
|
@@ -13889,7 +13902,7 @@ class PixldocsRenderer {
|
|
|
13889
13902
|
*/
|
|
13890
13903
|
async awaitFontsForConfig(config, maxWaitMs) {
|
|
13891
13904
|
if (typeof document === "undefined" || !document.fonts) return;
|
|
13892
|
-
|
|
13905
|
+
await ensureFontsForResolvedConfig(config);
|
|
13893
13906
|
await this.waitForRelevantFonts(config, maxWaitMs);
|
|
13894
13907
|
await Promise.race([
|
|
13895
13908
|
document.fonts.ready.catch(() => void 0).then(() => void 0),
|
|
@@ -14345,6 +14358,65 @@ class PixldocsRenderer {
|
|
|
14345
14358
|
await waitForPaint();
|
|
14346
14359
|
}
|
|
14347
14360
|
}
|
|
14361
|
+
function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
14362
|
+
try {
|
|
14363
|
+
if (typeof DOMParser === "undefined") return;
|
|
14364
|
+
const doc = new DOMParser().parseFromString(svgStr, "image/svg+xml");
|
|
14365
|
+
if (doc.querySelector("parsererror")) {
|
|
14366
|
+
console.warn(`${tag} page=${pageIndex} stage=${stage} parse-error`);
|
|
14367
|
+
return;
|
|
14368
|
+
}
|
|
14369
|
+
const root = doc.documentElement;
|
|
14370
|
+
const svgWidth = root == null ? void 0 : root.getAttribute("width");
|
|
14371
|
+
const svgHeight = root == null ? void 0 : root.getAttribute("height");
|
|
14372
|
+
const svgViewBox = root == null ? void 0 : root.getAttribute("viewBox");
|
|
14373
|
+
const texts = Array.from(doc.querySelectorAll("text"));
|
|
14374
|
+
const summary = {
|
|
14375
|
+
page: pageIndex,
|
|
14376
|
+
stage,
|
|
14377
|
+
svgLen: svgStr.length,
|
|
14378
|
+
svgWidth,
|
|
14379
|
+
svgHeight,
|
|
14380
|
+
svgViewBox,
|
|
14381
|
+
textCount: texts.length
|
|
14382
|
+
};
|
|
14383
|
+
console.log(`${tag} ${stage} page=${pageIndex} summary`, summary);
|
|
14384
|
+
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
14385
|
+
var _a, _b;
|
|
14386
|
+
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
14387
|
+
const tspanInfo = tspans.slice(0, 4).map((s) => ({
|
|
14388
|
+
x: s.getAttribute("x"),
|
|
14389
|
+
y: s.getAttribute("y"),
|
|
14390
|
+
text: (s.textContent || "").slice(0, 40)
|
|
14391
|
+
}));
|
|
14392
|
+
let containerWidth = null;
|
|
14393
|
+
let cursor = t.parentElement;
|
|
14394
|
+
while (cursor && !containerWidth) {
|
|
14395
|
+
containerWidth = (_a = cursor.getAttribute) == null ? void 0 : _a.call(cursor, "width");
|
|
14396
|
+
cursor = cursor.parentElement;
|
|
14397
|
+
if (cursor && ((_b = cursor.tagName) == null ? void 0 : _b.toLowerCase()) === "svg") break;
|
|
14398
|
+
}
|
|
14399
|
+
return {
|
|
14400
|
+
idx,
|
|
14401
|
+
x: t.getAttribute("x"),
|
|
14402
|
+
y: t.getAttribute("y"),
|
|
14403
|
+
fontSize: t.getAttribute("font-size"),
|
|
14404
|
+
fontFamily: t.getAttribute("font-family"),
|
|
14405
|
+
fontWeight: t.getAttribute("font-weight"),
|
|
14406
|
+
textAnchor: t.getAttribute("text-anchor"),
|
|
14407
|
+
transform: t.getAttribute("transform"),
|
|
14408
|
+
style: (t.getAttribute("style") || "").slice(0, 120),
|
|
14409
|
+
ancestorWidth: containerWidth,
|
|
14410
|
+
textContent: (t.textContent || "").slice(0, 60),
|
|
14411
|
+
tspanCount: tspans.length,
|
|
14412
|
+
tspanSample: tspanInfo
|
|
14413
|
+
};
|
|
14414
|
+
});
|
|
14415
|
+
console.log(`${tag} ${stage} page=${pageIndex} text-sample (first ${sample.length}/${texts.length})`, sample);
|
|
14416
|
+
} catch (err) {
|
|
14417
|
+
console.warn(`${tag} ${stage} page=${pageIndex} dump threw`, err);
|
|
14418
|
+
}
|
|
14419
|
+
}
|
|
14348
14420
|
const SVG_DRAWABLE_TAGS = /* @__PURE__ */ new Set([
|
|
14349
14421
|
"path",
|
|
14350
14422
|
"rect",
|
|
@@ -15640,6 +15712,15 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15640
15712
|
const { title, stripPageBackground } = options;
|
|
15641
15713
|
const firstPage = svgResults[0];
|
|
15642
15714
|
const orientation = firstPage.width > firstPage.height ? "landscape" : "portrait";
|
|
15715
|
+
const PARITY_TAG = "[canvas-renderer][parity-diag][pkg-pdf]";
|
|
15716
|
+
console.log(`${PARITY_TAG} pkg-version=0.5.70 pages=${svgResults.length}`);
|
|
15717
|
+
try {
|
|
15718
|
+
for (let pi = 0; pi < svgResults.length; pi++) {
|
|
15719
|
+
dumpSvgTextDiagnostics(svgResults[pi].svg, pi, PARITY_TAG, "STAGE-1-raw-toSVG");
|
|
15720
|
+
}
|
|
15721
|
+
} catch (e) {
|
|
15722
|
+
console.warn(`${PARITY_TAG} dump failed`, e);
|
|
15723
|
+
}
|
|
15643
15724
|
const pdf = new jsPDF({
|
|
15644
15725
|
orientation,
|
|
15645
15726
|
unit: "px",
|
|
@@ -15669,6 +15750,15 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15669
15750
|
stripPageBackground: shouldStripBg
|
|
15670
15751
|
});
|
|
15671
15752
|
if (processedSvg) {
|
|
15753
|
+
try {
|
|
15754
|
+
dumpSvgTextDiagnostics(
|
|
15755
|
+
new XMLSerializer().serializeToString(processedSvg),
|
|
15756
|
+
i,
|
|
15757
|
+
PARITY_TAG,
|
|
15758
|
+
"STAGE-2-after-prepareLiveCanvasSvgForPdf"
|
|
15759
|
+
);
|
|
15760
|
+
} catch {
|
|
15761
|
+
}
|
|
15672
15762
|
await convertTextDecorationsToLines(processedSvg);
|
|
15673
15763
|
if (shouldOutlineText) {
|
|
15674
15764
|
try {
|
|
@@ -15690,6 +15780,15 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15690
15780
|
const reParser = new DOMParser();
|
|
15691
15781
|
const reDoc = reParser.parseFromString(rewrittenSvg, "image/svg+xml");
|
|
15692
15782
|
processedSvg = reDoc.documentElement;
|
|
15783
|
+
try {
|
|
15784
|
+
dumpSvgTextDiagnostics(
|
|
15785
|
+
rewrittenSvg,
|
|
15786
|
+
i,
|
|
15787
|
+
PARITY_TAG,
|
|
15788
|
+
"STAGE-3-after-rewriteSvgFontsForJsPDF"
|
|
15789
|
+
);
|
|
15790
|
+
} catch {
|
|
15791
|
+
}
|
|
15693
15792
|
}
|
|
15694
15793
|
if (processedSvg) {
|
|
15695
15794
|
pdf.setFillColor(0, 0, 0);
|
|
@@ -15713,7 +15812,8 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
15713
15812
|
}
|
|
15714
15813
|
const pdfExport = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
15715
15814
|
__proto__: null,
|
|
15716
|
-
assemblePdfFromSvgs
|
|
15815
|
+
assemblePdfFromSvgs,
|
|
15816
|
+
dumpSvgTextDiagnostics
|
|
15717
15817
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
15718
15818
|
function collectImageUrls(config) {
|
|
15719
15819
|
const urls = [];
|
|
@@ -15817,6 +15917,7 @@ export {
|
|
|
15817
15917
|
collectFontsFromConfig,
|
|
15818
15918
|
collectImageUrls,
|
|
15819
15919
|
configHasAutoShrinkText$1 as configHasAutoShrinkText,
|
|
15920
|
+
dumpSvgTextDiagnostics,
|
|
15820
15921
|
embedFont,
|
|
15821
15922
|
embedFontsForConfig,
|
|
15822
15923
|
embedFontsInPdf,
|