@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.cjs
CHANGED
|
@@ -14600,6 +14600,10 @@ function getEmbeddedJsPDFFontName(fontName, weight, isItalic = false) {
|
|
|
14600
14600
|
function isFontAvailable(fontName) {
|
|
14601
14601
|
return fontName in FONT_FILES;
|
|
14602
14602
|
}
|
|
14603
|
+
const registeredFamilies = /* @__PURE__ */ new Set();
|
|
14604
|
+
function isFamilyEmbedded(family) {
|
|
14605
|
+
return registeredFamilies.has(family);
|
|
14606
|
+
}
|
|
14603
14607
|
const ttfCache = /* @__PURE__ */ new Map();
|
|
14604
14608
|
async function fetchTTFAsBase64(url) {
|
|
14605
14609
|
const cached = ttfCache.get(url);
|
|
@@ -14672,12 +14676,133 @@ async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
|
|
|
14672
14676
|
} catch {
|
|
14673
14677
|
}
|
|
14674
14678
|
}
|
|
14679
|
+
registeredFamilies.add(fontName);
|
|
14675
14680
|
return true;
|
|
14676
14681
|
} catch (e) {
|
|
14677
14682
|
console.warn(`[pdf-fonts] Failed to embed ${fontName} w${weight}:`, e);
|
|
14678
14683
|
return false;
|
|
14679
14684
|
}
|
|
14680
14685
|
}
|
|
14686
|
+
const googleFontNotFound = /* @__PURE__ */ new Set();
|
|
14687
|
+
const fontshareNotFound = /* @__PURE__ */ new Set();
|
|
14688
|
+
function bytesToBase64(bytes) {
|
|
14689
|
+
let binary = "";
|
|
14690
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
14691
|
+
return btoa(binary);
|
|
14692
|
+
}
|
|
14693
|
+
async function fetchGoogleFontTTF(fontFamily, weight, isItalic = false) {
|
|
14694
|
+
const cacheKey = `gf:${fontFamily}:${weight}:${isItalic ? "i" : "n"}`;
|
|
14695
|
+
if (ttfCache.has(cacheKey)) return ttfCache.get(cacheKey);
|
|
14696
|
+
if (googleFontNotFound.has(fontFamily)) return null;
|
|
14697
|
+
try {
|
|
14698
|
+
const ital = isItalic ? "1" : "0";
|
|
14699
|
+
const cssUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(
|
|
14700
|
+
fontFamily
|
|
14701
|
+
)}:ital,wght@${ital},${weight}&display=swap`;
|
|
14702
|
+
const cssRes = await fetch(cssUrl, {
|
|
14703
|
+
headers: {
|
|
14704
|
+
"User-Agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us) AppleWebKit/533.1 (KHTML, like Gecko)"
|
|
14705
|
+
}
|
|
14706
|
+
});
|
|
14707
|
+
if (!cssRes.ok) {
|
|
14708
|
+
if (cssRes.status === 400 || cssRes.status === 404) googleFontNotFound.add(fontFamily);
|
|
14709
|
+
return null;
|
|
14710
|
+
}
|
|
14711
|
+
const css = await cssRes.text();
|
|
14712
|
+
const urlMatch = css.match(/url\(([^)]+)\)\s+format\(['"]?truetype['"]?\)/i) || css.match(/url\(([^)]+)\)/);
|
|
14713
|
+
if (!urlMatch) return null;
|
|
14714
|
+
const ttfUrl = urlMatch[1].replace(/['"]/g, "");
|
|
14715
|
+
const ttfRes = await fetch(ttfUrl);
|
|
14716
|
+
if (!ttfRes.ok) return null;
|
|
14717
|
+
const buf = await ttfRes.arrayBuffer();
|
|
14718
|
+
const bytes = new Uint8Array(buf);
|
|
14719
|
+
if (!isJsPdfEmbeddableTrueType(bytes)) {
|
|
14720
|
+
console.warn(`[pdf-fonts] Google Fonts returned a non-TTF for ${fontFamily} (${weight}); skipping`);
|
|
14721
|
+
return null;
|
|
14722
|
+
}
|
|
14723
|
+
const b64 = bytesToBase64(bytes);
|
|
14724
|
+
ttfCache.set(cacheKey, b64);
|
|
14725
|
+
return b64;
|
|
14726
|
+
} catch (err) {
|
|
14727
|
+
console.warn(`[pdf-fonts] fetchGoogleFontTTF failed for ${fontFamily} (${weight}):`, err);
|
|
14728
|
+
return null;
|
|
14729
|
+
}
|
|
14730
|
+
}
|
|
14731
|
+
async function fetchFontshareTTF(fontFamily, weight, isItalic = false) {
|
|
14732
|
+
const cacheKey = `fs:${fontFamily}:${weight}:${isItalic ? "i" : "n"}`;
|
|
14733
|
+
if (ttfCache.has(cacheKey)) return ttfCache.get(cacheKey);
|
|
14734
|
+
if (fontshareNotFound.has(fontFamily)) return null;
|
|
14735
|
+
const slug = fontFamily.trim().toLowerCase().replace(/\s+/g, "-");
|
|
14736
|
+
try {
|
|
14737
|
+
const styleSuffix = isItalic ? "i" : "";
|
|
14738
|
+
const cssUrl = `https://api.fontshare.com/v2/css?f[]=${slug}@${weight}${styleSuffix}&display=swap`;
|
|
14739
|
+
const cssRes = await fetch(cssUrl);
|
|
14740
|
+
if (!cssRes.ok) {
|
|
14741
|
+
if (cssRes.status === 400 || cssRes.status === 404) fontshareNotFound.add(fontFamily);
|
|
14742
|
+
return null;
|
|
14743
|
+
}
|
|
14744
|
+
const css = await cssRes.text();
|
|
14745
|
+
const ttMatch = css.match(/url\(([^)]+)\)\s+format\(['"]?truetype['"]?\)/i);
|
|
14746
|
+
if (!ttMatch) {
|
|
14747
|
+
fontshareNotFound.add(fontFamily);
|
|
14748
|
+
return null;
|
|
14749
|
+
}
|
|
14750
|
+
let ttfUrl = ttMatch[1].replace(/['"]/g, "").trim();
|
|
14751
|
+
if (ttfUrl.startsWith("//")) ttfUrl = `https:${ttfUrl}`;
|
|
14752
|
+
const ttfRes = await fetch(ttfUrl);
|
|
14753
|
+
if (!ttfRes.ok) return null;
|
|
14754
|
+
const buf = await ttfRes.arrayBuffer();
|
|
14755
|
+
const bytes = new Uint8Array(buf);
|
|
14756
|
+
if (!isJsPdfEmbeddableTrueType(bytes)) return null;
|
|
14757
|
+
const b64 = bytesToBase64(bytes);
|
|
14758
|
+
ttfCache.set(cacheKey, b64);
|
|
14759
|
+
return b64;
|
|
14760
|
+
} catch (err) {
|
|
14761
|
+
console.warn(`[pdf-fonts] fetchFontshareTTF failed for ${fontFamily} (${weight}):`, err);
|
|
14762
|
+
return null;
|
|
14763
|
+
}
|
|
14764
|
+
}
|
|
14765
|
+
function registerJsPdfFont(pdf, fontName, resolvedWeight, isItalic, base64) {
|
|
14766
|
+
const label = FONT_WEIGHT_LABELS[resolvedWeight];
|
|
14767
|
+
const italicSuffix = isItalic ? "Italic" : "";
|
|
14768
|
+
const jsPdfFontName = getEmbeddedJsPDFFontName(fontName, resolvedWeight, isItalic);
|
|
14769
|
+
const fileName = `${getJsPDFFontName(fontName)}-${label}${italicSuffix}.ttf`;
|
|
14770
|
+
try {
|
|
14771
|
+
pdf.addFileToVFS(fileName, base64);
|
|
14772
|
+
pdf.addFont(fileName, jsPdfFontName, "normal");
|
|
14773
|
+
if (fontName !== jsPdfFontName) {
|
|
14774
|
+
try {
|
|
14775
|
+
pdf.addFont(fileName, fontName, "normal");
|
|
14776
|
+
} catch {
|
|
14777
|
+
}
|
|
14778
|
+
}
|
|
14779
|
+
registeredFamilies.add(fontName);
|
|
14780
|
+
return true;
|
|
14781
|
+
} catch (err) {
|
|
14782
|
+
console.warn(`[pdf-fonts] registerJsPdfFont failed for ${fontName}:`, err);
|
|
14783
|
+
return false;
|
|
14784
|
+
}
|
|
14785
|
+
}
|
|
14786
|
+
async function embedFontWithGoogleFallback(pdf, fontName, weight = 400, fontBaseUrl, isItalic = false) {
|
|
14787
|
+
if (FONT_FILES[fontName]) {
|
|
14788
|
+
const ok = await embedFont(pdf, fontName, weight, fontBaseUrl, isItalic);
|
|
14789
|
+
if (ok) return true;
|
|
14790
|
+
}
|
|
14791
|
+
const resolved = resolveFontWeight(weight);
|
|
14792
|
+
const fsB64 = await fetchFontshareTTF(fontName, resolved, isItalic);
|
|
14793
|
+
if (fsB64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, fsB64);
|
|
14794
|
+
if (isItalic) {
|
|
14795
|
+
const fsUpright = await fetchFontshareTTF(fontName, resolved, false);
|
|
14796
|
+
if (fsUpright) return registerJsPdfFont(pdf, fontName, resolved, isItalic, fsUpright);
|
|
14797
|
+
}
|
|
14798
|
+
const b64 = await fetchGoogleFontTTF(fontName, resolved, isItalic);
|
|
14799
|
+
if (b64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, b64);
|
|
14800
|
+
if (isItalic) {
|
|
14801
|
+
const uprightB64 = await fetchGoogleFontTTF(fontName, resolved, false);
|
|
14802
|
+
if (uprightB64) return registerJsPdfFont(pdf, fontName, resolved, isItalic, uprightB64);
|
|
14803
|
+
}
|
|
14804
|
+
return false;
|
|
14805
|
+
}
|
|
14681
14806
|
async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
14682
14807
|
const fontKeys = /* @__PURE__ */ new Set();
|
|
14683
14808
|
const SEP = "";
|
|
@@ -14836,7 +14961,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
14836
14961
|
const rawFf = resolveInheritedValue(el, "font-family");
|
|
14837
14962
|
if (!rawFf) continue;
|
|
14838
14963
|
const clean = (_a = rawFf.split(",")[0]) == null ? void 0 : _a.replace(/['"]/g, "").trim();
|
|
14839
|
-
if (!isFontAvailable(clean)) continue;
|
|
14964
|
+
if (!isFontAvailable(clean) && !isFamilyEmbedded(clean)) continue;
|
|
14840
14965
|
const weightRaw = resolveInheritedValue(el, "font-weight") || "400";
|
|
14841
14966
|
const styleRaw = resolveInheritedValue(el, "font-style") || "normal";
|
|
14842
14967
|
const weight = resolveWeightNum(weightRaw);
|
|
@@ -14919,14 +15044,19 @@ async function embedFontsInPdf(pdf, fontFamilies, fontBaseUrl) {
|
|
|
14919
15044
|
fontFamilies.add(FONT_FALLBACK_SYMBOLS);
|
|
14920
15045
|
fontFamilies.add(FONT_FALLBACK_DEVANAGARI);
|
|
14921
15046
|
for (const family of fontFamilies) {
|
|
14922
|
-
if (
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
15047
|
+
if (isFontAvailable(family)) {
|
|
15048
|
+
for (const w of weights) {
|
|
15049
|
+
tasks.push(
|
|
15050
|
+
embedFont(pdf, family, w, fontBaseUrl).then((ok) => {
|
|
15051
|
+
if (ok) embedded.add(`${family}${w}`);
|
|
15052
|
+
})
|
|
15053
|
+
);
|
|
15054
|
+
}
|
|
15055
|
+
} else {
|
|
14927
15056
|
tasks.push(
|
|
14928
|
-
|
|
14929
|
-
if (ok) embedded.add(`${family}
|
|
15057
|
+
embedFontWithGoogleFallback(pdf, family, 400, fontBaseUrl, false).then((ok) => {
|
|
15058
|
+
if (ok) embedded.add(`${family}400`);
|
|
15059
|
+
else console.warn(`[pdf-fonts] No TTF (local/Google/Fontshare) for "${family}" — will use Helvetica fallback`);
|
|
14930
15060
|
})
|
|
14931
15061
|
);
|
|
14932
15062
|
}
|
|
@@ -14942,6 +15072,7 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14942
15072
|
FONT_FILES,
|
|
14943
15073
|
FONT_WEIGHT_LABELS,
|
|
14944
15074
|
embedFont,
|
|
15075
|
+
embedFontWithGoogleFallback,
|
|
14945
15076
|
embedFontsForConfig,
|
|
14946
15077
|
embedFontsInPdf,
|
|
14947
15078
|
extractFontFamiliesFromSvgs,
|