@pixldocs/canvas-renderer 0.5.113 → 0.5.114
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 +99 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +99 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.114";
|
|
263
263
|
|
|
264
264
|
export declare interface PageSettings {
|
|
265
265
|
backgroundColor?: string;
|
package/dist/index.js
CHANGED
|
@@ -13998,7 +13998,7 @@ function PixldocsPreview(props) {
|
|
|
13998
13998
|
!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..." }) })
|
|
13999
13999
|
] });
|
|
14000
14000
|
}
|
|
14001
|
-
const PACKAGE_VERSION = "0.5.
|
|
14001
|
+
const PACKAGE_VERSION = "0.5.114";
|
|
14002
14002
|
const roundParityValue = (value) => {
|
|
14003
14003
|
if (typeof value !== "number") return value;
|
|
14004
14004
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -15716,6 +15716,9 @@ const remoteVariantKey = (family, weight, isItalic) => `${family}|${resolveFontW
|
|
|
15716
15716
|
const registeredVariants = /* @__PURE__ */ new Set();
|
|
15717
15717
|
const registeredVariantCoverage = /* @__PURE__ */ new Map();
|
|
15718
15718
|
const variantKey = (family, weight, italic) => `${family}|${resolveFontWeight(weight)}|${italic ? "i" : "n"}`;
|
|
15719
|
+
function isVariantEmbedded(family, weight, italic) {
|
|
15720
|
+
return registeredVariants.has(variantKey(family, weight, italic));
|
|
15721
|
+
}
|
|
15719
15722
|
const resolveBestRegisteredVariant = (family, weight, italic) => {
|
|
15720
15723
|
const want = resolveFontWeight(weight);
|
|
15721
15724
|
const weights = [300, 400, 500, 600, 700];
|
|
@@ -16203,6 +16206,88 @@ function extractFontFamiliesFromSvgs(svgs) {
|
|
|
16203
16206
|
}
|
|
16204
16207
|
return families;
|
|
16205
16208
|
}
|
|
16209
|
+
async function embedFontVariantsFromSvg(pdf, svgStr, fontBaseUrl) {
|
|
16210
|
+
var _a;
|
|
16211
|
+
const parser = new DOMParser();
|
|
16212
|
+
const doc = parser.parseFromString(svgStr, "image/svg+xml");
|
|
16213
|
+
const textEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
|
|
16214
|
+
const readStyleToken = (style, prop) => {
|
|
16215
|
+
var _a2;
|
|
16216
|
+
const m = style.match(new RegExp(`${prop}\\s*:\\s*([^;]+)`, "i"));
|
|
16217
|
+
return ((_a2 = m == null ? void 0 : m[1]) == null ? void 0 : _a2.trim()) || null;
|
|
16218
|
+
};
|
|
16219
|
+
const resolveInherited = (el, attr, styleProp = attr) => {
|
|
16220
|
+
var _a2;
|
|
16221
|
+
let cur = el;
|
|
16222
|
+
while (cur) {
|
|
16223
|
+
const a = (_a2 = cur.getAttribute(attr)) == null ? void 0 : _a2.trim();
|
|
16224
|
+
if (a) return a;
|
|
16225
|
+
const s = readStyleToken(cur.getAttribute("style") || "", styleProp);
|
|
16226
|
+
if (s) return s;
|
|
16227
|
+
cur = cur.parentElement;
|
|
16228
|
+
}
|
|
16229
|
+
return null;
|
|
16230
|
+
};
|
|
16231
|
+
const parseWeight = (raw) => {
|
|
16232
|
+
const n = Number.parseInt(raw, 10);
|
|
16233
|
+
if (Number.isFinite(n)) return n;
|
|
16234
|
+
const s = raw.toLowerCase();
|
|
16235
|
+
if (/bold/.test(s)) return 700;
|
|
16236
|
+
if (/semi|demi/.test(s)) return 600;
|
|
16237
|
+
if (/medium/.test(s)) return 500;
|
|
16238
|
+
if (/light|thin/.test(s)) return 300;
|
|
16239
|
+
return 400;
|
|
16240
|
+
};
|
|
16241
|
+
const needed = /* @__PURE__ */ new Map();
|
|
16242
|
+
for (const el of textEls) {
|
|
16243
|
+
const rawFf = resolveInherited(el, "font-family");
|
|
16244
|
+
if (!rawFf) continue;
|
|
16245
|
+
const family = (_a = rawFf.split(",")[0]) == null ? void 0 : _a.replace(/['"]/g, "").trim();
|
|
16246
|
+
if (!family) continue;
|
|
16247
|
+
const weight = resolveFontWeight(parseWeight(resolveInherited(el, "font-weight") || "400"));
|
|
16248
|
+
const italic = /italic|oblique/i.test(resolveInherited(el, "font-style") || "normal");
|
|
16249
|
+
const key = `${family}${weight}${italic ? "i" : "n"}`;
|
|
16250
|
+
if (!needed.has(key)) needed.set(key, { family, weight, italic });
|
|
16251
|
+
}
|
|
16252
|
+
let embedded = 0;
|
|
16253
|
+
for (const { family, weight, italic } of needed.values()) {
|
|
16254
|
+
if (isVariantEmbedded(family, weight, italic)) continue;
|
|
16255
|
+
await embedFontWithGoogleFallback(pdf, family, weight, fontBaseUrl, italic);
|
|
16256
|
+
if (isVariantEmbedded(family, weight, italic)) embedded++;
|
|
16257
|
+
}
|
|
16258
|
+
const fallbacks = [
|
|
16259
|
+
{ family: FONT_FALLBACK_SYMBOLS, weight: 400 },
|
|
16260
|
+
{ family: FONT_FALLBACK_MATH, weight: 400 }
|
|
16261
|
+
];
|
|
16262
|
+
for (const w of [300, 400, 500, 600, 700]) {
|
|
16263
|
+
fallbacks.push({ family: FONT_FALLBACK_DEVANAGARI, weight: w });
|
|
16264
|
+
}
|
|
16265
|
+
for (const { family, weight } of fallbacks) {
|
|
16266
|
+
if (isVariantEmbedded(family, weight, false)) continue;
|
|
16267
|
+
await embedFontWithGoogleFallback(pdf, family, weight, fontBaseUrl, false);
|
|
16268
|
+
if (isVariantEmbedded(family, weight, false)) embedded++;
|
|
16269
|
+
}
|
|
16270
|
+
for (const { family, weight, italic } of needed.values()) {
|
|
16271
|
+
if (!italic) continue;
|
|
16272
|
+
if (!isVariantEmbedded(family, weight, false)) {
|
|
16273
|
+
await embedFontWithGoogleFallback(pdf, family, weight, fontBaseUrl, false);
|
|
16274
|
+
if (isVariantEmbedded(family, weight, false)) embedded++;
|
|
16275
|
+
}
|
|
16276
|
+
if (!isVariantEmbedded(family, 400, false)) {
|
|
16277
|
+
await embedFontWithGoogleFallback(pdf, family, 400, fontBaseUrl, false);
|
|
16278
|
+
if (isVariantEmbedded(family, 400, false)) embedded++;
|
|
16279
|
+
}
|
|
16280
|
+
if (weight <= 400) continue;
|
|
16281
|
+
if (isVariantEmbedded(family, 400, true)) continue;
|
|
16282
|
+
await embedFontWithGoogleFallback(pdf, family, 400, fontBaseUrl, true);
|
|
16283
|
+
if (isVariantEmbedded(family, 400, true)) embedded++;
|
|
16284
|
+
}
|
|
16285
|
+
console.log("[pdf-fonts] embedFontVariantsFromSvg", {
|
|
16286
|
+
requested: needed.size,
|
|
16287
|
+
newlyEmbedded: embedded
|
|
16288
|
+
});
|
|
16289
|
+
return embedded;
|
|
16290
|
+
}
|
|
16206
16291
|
async function embedFontsInPdf(pdf, fontFamilies, fontBaseUrl) {
|
|
16207
16292
|
const embedded = /* @__PURE__ */ new Set();
|
|
16208
16293
|
const weights = [300, 400, 500, 600, 700];
|
|
@@ -16254,6 +16339,7 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
16254
16339
|
FONT_FILES,
|
|
16255
16340
|
FONT_WEIGHT_LABELS,
|
|
16256
16341
|
embedFont,
|
|
16342
|
+
embedFontVariantsFromSvg,
|
|
16257
16343
|
embedFontWithGoogleFallback,
|
|
16258
16344
|
embedFontsForConfig,
|
|
16259
16345
|
embedFontsInPdf,
|
|
@@ -16261,6 +16347,7 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
16261
16347
|
getEmbeddedJsPDFFontName,
|
|
16262
16348
|
getFontPathForWeight,
|
|
16263
16349
|
isFontAvailable,
|
|
16350
|
+
isVariantEmbedded,
|
|
16264
16351
|
resolveBestRegisteredVariant,
|
|
16265
16352
|
resolveFontWeight,
|
|
16266
16353
|
rewriteSvgFontsForJsPDF
|
|
@@ -17767,7 +17854,17 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
17767
17854
|
} catch {
|
|
17768
17855
|
}
|
|
17769
17856
|
await convertTextDecorationsToLines(processedSvg);
|
|
17770
|
-
const
|
|
17857
|
+
const liveSvgStr = new XMLSerializer().serializeToString(processedSvg);
|
|
17858
|
+
try {
|
|
17859
|
+
const { embedFontVariantsFromSvg: embedFontVariantsFromSvg2 } = await Promise.resolve().then(() => pdfFonts);
|
|
17860
|
+
await embedFontVariantsFromSvg2(pdf, liveSvgStr, fontBaseUrl);
|
|
17861
|
+
} catch (embedErr) {
|
|
17862
|
+
console.warn(
|
|
17863
|
+
"[canvas-renderer][pdf] embedFontVariantsFromSvg failed (page " + (i + 1) + "):",
|
|
17864
|
+
embedErr
|
|
17865
|
+
);
|
|
17866
|
+
}
|
|
17867
|
+
const rewrittenSvg = rewriteSvgFontsForJsPDF(liveSvgStr);
|
|
17771
17868
|
const reParser = new DOMParser();
|
|
17772
17869
|
const reDoc = reParser.parseFromString(rewrittenSvg, "image/svg+xml");
|
|
17773
17870
|
processedSvg = reDoc.documentElement;
|