@pixldocs/canvas-renderer 0.5.96 → 0.5.97
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 +139 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +139 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14581,6 +14581,10 @@ function getEmbeddedJsPDFFontName(fontName, weight, isItalic = false) {
|
|
|
14581
14581
|
function isFontAvailable(fontName) {
|
|
14582
14582
|
return fontName in FONT_FILES;
|
|
14583
14583
|
}
|
|
14584
|
+
const registeredFamilies = /* @__PURE__ */ new Set();
|
|
14585
|
+
function isFamilyEmbedded(family) {
|
|
14586
|
+
return registeredFamilies.has(family);
|
|
14587
|
+
}
|
|
14584
14588
|
const ttfCache = /* @__PURE__ */ new Map();
|
|
14585
14589
|
async function fetchTTFAsBase64(url) {
|
|
14586
14590
|
const cached = ttfCache.get(url);
|
|
@@ -14653,12 +14657,133 @@ async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
|
|
|
14653
14657
|
} catch {
|
|
14654
14658
|
}
|
|
14655
14659
|
}
|
|
14660
|
+
registeredFamilies.add(fontName);
|
|
14656
14661
|
return true;
|
|
14657
14662
|
} catch (e) {
|
|
14658
14663
|
console.warn(`[pdf-fonts] Failed to embed ${fontName} w${weight}:`, e);
|
|
14659
14664
|
return false;
|
|
14660
14665
|
}
|
|
14661
14666
|
}
|
|
14667
|
+
const googleFontNotFound = /* @__PURE__ */ new Set();
|
|
14668
|
+
const fontshareNotFound = /* @__PURE__ */ new Set();
|
|
14669
|
+
function bytesToBase64(bytes) {
|
|
14670
|
+
let binary = "";
|
|
14671
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
14672
|
+
return btoa(binary);
|
|
14673
|
+
}
|
|
14674
|
+
async function fetchGoogleFontTTF(fontFamily, weight, isItalic = false) {
|
|
14675
|
+
const cacheKey = `gf:${fontFamily}:${weight}:${isItalic ? "i" : "n"}`;
|
|
14676
|
+
if (ttfCache.has(cacheKey)) return ttfCache.get(cacheKey);
|
|
14677
|
+
if (googleFontNotFound.has(fontFamily)) return null;
|
|
14678
|
+
try {
|
|
14679
|
+
const ital = isItalic ? "1" : "0";
|
|
14680
|
+
const cssUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(
|
|
14681
|
+
fontFamily
|
|
14682
|
+
)}:ital,wght@${ital},${weight}&display=swap`;
|
|
14683
|
+
const cssRes = await fetch(cssUrl, {
|
|
14684
|
+
headers: {
|
|
14685
|
+
"User-Agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us) AppleWebKit/533.1 (KHTML, like Gecko)"
|
|
14686
|
+
}
|
|
14687
|
+
});
|
|
14688
|
+
if (!cssRes.ok) {
|
|
14689
|
+
if (cssRes.status === 400 || cssRes.status === 404) googleFontNotFound.add(fontFamily);
|
|
14690
|
+
return null;
|
|
14691
|
+
}
|
|
14692
|
+
const css = await cssRes.text();
|
|
14693
|
+
const urlMatch = css.match(/url\(([^)]+)\)\s+format\(['"]?truetype['"]?\)/i) || css.match(/url\(([^)]+)\)/);
|
|
14694
|
+
if (!urlMatch) return null;
|
|
14695
|
+
const ttfUrl = urlMatch[1].replace(/['"]/g, "");
|
|
14696
|
+
const ttfRes = await fetch(ttfUrl);
|
|
14697
|
+
if (!ttfRes.ok) return null;
|
|
14698
|
+
const buf = await ttfRes.arrayBuffer();
|
|
14699
|
+
const bytes = new Uint8Array(buf);
|
|
14700
|
+
if (!isJsPdfEmbeddableTrueType(bytes)) {
|
|
14701
|
+
console.warn(`[pdf-fonts] Google Fonts returned a non-TTF for ${fontFamily} (${weight}); skipping`);
|
|
14702
|
+
return null;
|
|
14703
|
+
}
|
|
14704
|
+
const b64 = bytesToBase64(bytes);
|
|
14705
|
+
ttfCache.set(cacheKey, b64);
|
|
14706
|
+
return b64;
|
|
14707
|
+
} catch (err) {
|
|
14708
|
+
console.warn(`[pdf-fonts] fetchGoogleFontTTF failed for ${fontFamily} (${weight}):`, err);
|
|
14709
|
+
return null;
|
|
14710
|
+
}
|
|
14711
|
+
}
|
|
14712
|
+
async function fetchFontshareTTF(fontFamily, weight, isItalic = false) {
|
|
14713
|
+
const cacheKey = `fs:${fontFamily}:${weight}:${isItalic ? "i" : "n"}`;
|
|
14714
|
+
if (ttfCache.has(cacheKey)) return ttfCache.get(cacheKey);
|
|
14715
|
+
if (fontshareNotFound.has(fontFamily)) return null;
|
|
14716
|
+
const slug = fontFamily.trim().toLowerCase().replace(/\s+/g, "-");
|
|
14717
|
+
try {
|
|
14718
|
+
const styleSuffix = isItalic ? "i" : "";
|
|
14719
|
+
const cssUrl = `https://api.fontshare.com/v2/css?f[]=${slug}@${weight}${styleSuffix}&display=swap`;
|
|
14720
|
+
const cssRes = await fetch(cssUrl);
|
|
14721
|
+
if (!cssRes.ok) {
|
|
14722
|
+
if (cssRes.status === 400 || cssRes.status === 404) fontshareNotFound.add(fontFamily);
|
|
14723
|
+
return null;
|
|
14724
|
+
}
|
|
14725
|
+
const css = await cssRes.text();
|
|
14726
|
+
const ttMatch = css.match(/url\(([^)]+)\)\s+format\(['"]?truetype['"]?\)/i);
|
|
14727
|
+
if (!ttMatch) {
|
|
14728
|
+
fontshareNotFound.add(fontFamily);
|
|
14729
|
+
return null;
|
|
14730
|
+
}
|
|
14731
|
+
let ttfUrl = ttMatch[1].replace(/['"]/g, "").trim();
|
|
14732
|
+
if (ttfUrl.startsWith("//")) ttfUrl = `https:${ttfUrl}`;
|
|
14733
|
+
const ttfRes = await fetch(ttfUrl);
|
|
14734
|
+
if (!ttfRes.ok) return null;
|
|
14735
|
+
const buf = await ttfRes.arrayBuffer();
|
|
14736
|
+
const bytes = new Uint8Array(buf);
|
|
14737
|
+
if (!isJsPdfEmbeddableTrueType(bytes)) return null;
|
|
14738
|
+
const b64 = bytesToBase64(bytes);
|
|
14739
|
+
ttfCache.set(cacheKey, b64);
|
|
14740
|
+
return b64;
|
|
14741
|
+
} catch (err) {
|
|
14742
|
+
console.warn(`[pdf-fonts] fetchFontshareTTF failed for ${fontFamily} (${weight}):`, err);
|
|
14743
|
+
return null;
|
|
14744
|
+
}
|
|
14745
|
+
}
|
|
14746
|
+
function registerJsPdfFont(pdf, fontName, resolvedWeight, isItalic, base64) {
|
|
14747
|
+
const label = FONT_WEIGHT_LABELS[resolvedWeight];
|
|
14748
|
+
const italicSuffix = isItalic ? "Italic" : "";
|
|
14749
|
+
const jsPdfFontName = getEmbeddedJsPDFFontName(fontName, resolvedWeight, isItalic);
|
|
14750
|
+
const fileName = `${getJsPDFFontName(fontName)}-${label}${italicSuffix}.ttf`;
|
|
14751
|
+
try {
|
|
14752
|
+
pdf.addFileToVFS(fileName, base64);
|
|
14753
|
+
pdf.addFont(fileName, jsPdfFontName, "normal");
|
|
14754
|
+
if (fontName !== jsPdfFontName) {
|
|
14755
|
+
try {
|
|
14756
|
+
pdf.addFont(fileName, fontName, "normal");
|
|
14757
|
+
} catch {
|
|
14758
|
+
}
|
|
14759
|
+
}
|
|
14760
|
+
registeredFamilies.add(fontName);
|
|
14761
|
+
return true;
|
|
14762
|
+
} catch (err) {
|
|
14763
|
+
console.warn(`[pdf-fonts] registerJsPdfFont failed for ${fontName}:`, err);
|
|
14764
|
+
return false;
|
|
14765
|
+
}
|
|
14766
|
+
}
|
|
14767
|
+
async function embedFontWithGoogleFallback(pdf, fontName, weight = 400, fontBaseUrl, isItalic = false) {
|
|
14768
|
+
if (FONT_FILES[fontName]) {
|
|
14769
|
+
const ok = await embedFont(pdf, fontName, weight, fontBaseUrl, isItalic);
|
|
14770
|
+
if (ok) return true;
|
|
14771
|
+
}
|
|
14772
|
+
const resolved = resolveFontWeight(weight);
|
|
14773
|
+
const fsB64 = await fetchFontshareTTF(fontName, resolved, isItalic);
|
|
14774
|
+
if (fsB64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, fsB64);
|
|
14775
|
+
if (isItalic) {
|
|
14776
|
+
const fsUpright = await fetchFontshareTTF(fontName, resolved, false);
|
|
14777
|
+
if (fsUpright) return registerJsPdfFont(pdf, fontName, resolved, isItalic, fsUpright);
|
|
14778
|
+
}
|
|
14779
|
+
const b64 = await fetchGoogleFontTTF(fontName, resolved, isItalic);
|
|
14780
|
+
if (b64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, b64);
|
|
14781
|
+
if (isItalic) {
|
|
14782
|
+
const uprightB64 = await fetchGoogleFontTTF(fontName, resolved, false);
|
|
14783
|
+
if (uprightB64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, uprightB64);
|
|
14784
|
+
}
|
|
14785
|
+
return false;
|
|
14786
|
+
}
|
|
14662
14787
|
async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
14663
14788
|
const fontKeys = /* @__PURE__ */ new Set();
|
|
14664
14789
|
const SEP = "";
|
|
@@ -14817,7 +14942,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
14817
14942
|
const rawFf = resolveInheritedValue(el, "font-family");
|
|
14818
14943
|
if (!rawFf) continue;
|
|
14819
14944
|
const clean = (_a = rawFf.split(",")[0]) == null ? void 0 : _a.replace(/['"]/g, "").trim();
|
|
14820
|
-
if (!isFontAvailable(clean)) continue;
|
|
14945
|
+
if (!isFontAvailable(clean) && !isFamilyEmbedded(clean)) continue;
|
|
14821
14946
|
const weightRaw = resolveInheritedValue(el, "font-weight") || "400";
|
|
14822
14947
|
const styleRaw = resolveInheritedValue(el, "font-style") || "normal";
|
|
14823
14948
|
const weight = resolveWeightNum(weightRaw);
|
|
@@ -14900,14 +15025,19 @@ async function embedFontsInPdf(pdf, fontFamilies, fontBaseUrl) {
|
|
|
14900
15025
|
fontFamilies.add(FONT_FALLBACK_SYMBOLS);
|
|
14901
15026
|
fontFamilies.add(FONT_FALLBACK_DEVANAGARI);
|
|
14902
15027
|
for (const family of fontFamilies) {
|
|
14903
|
-
if (
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
15028
|
+
if (isFontAvailable(family)) {
|
|
15029
|
+
for (const w of weights) {
|
|
15030
|
+
tasks.push(
|
|
15031
|
+
embedFont(pdf, family, w, fontBaseUrl).then((ok) => {
|
|
15032
|
+
if (ok) embedded.add(`${family}${w}`);
|
|
15033
|
+
})
|
|
15034
|
+
);
|
|
15035
|
+
}
|
|
15036
|
+
} else {
|
|
14908
15037
|
tasks.push(
|
|
14909
|
-
|
|
14910
|
-
if (ok) embedded.add(`${family}
|
|
15038
|
+
embedFontWithGoogleFallback(pdf, family, 400, fontBaseUrl, false).then((ok) => {
|
|
15039
|
+
if (ok) embedded.add(`${family}400`);
|
|
15040
|
+
else console.warn(`[pdf-fonts] No TTF (local/Google/Fontshare) for "${family}" — will use Helvetica fallback`);
|
|
14911
15041
|
})
|
|
14912
15042
|
);
|
|
14913
15043
|
}
|
|
@@ -14923,6 +15053,7 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14923
15053
|
FONT_FILES,
|
|
14924
15054
|
FONT_WEIGHT_LABELS,
|
|
14925
15055
|
embedFont,
|
|
15056
|
+
embedFontWithGoogleFallback,
|
|
14926
15057
|
embedFontsForConfig,
|
|
14927
15058
|
embedFontsInPdf,
|
|
14928
15059
|
extractFontFamiliesFromSvgs,
|