@pixldocs/canvas-renderer 0.5.95 → 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 +209 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +209 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -396,33 +396,6 @@ function measureTextHeight(element) {
|
|
|
396
396
|
return fallbackEstimateHeight(element);
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
function getMinTextWidth(element) {
|
|
400
|
-
if (element.type !== "text" || !element.text) {
|
|
401
|
-
return typeof element.width === "number" ? element.width : 200;
|
|
402
|
-
}
|
|
403
|
-
try {
|
|
404
|
-
const textbox = new fabric.Textbox(element.text, {
|
|
405
|
-
width: 1e4,
|
|
406
|
-
fontSize: element.fontSize || 16,
|
|
407
|
-
fontFamily: element.fontFamily || "Open Sans",
|
|
408
|
-
fontWeight: element.fontWeight || 400,
|
|
409
|
-
fontStyle: element.fontStyle || "normal",
|
|
410
|
-
lineHeight: element.lineHeight || 1.2,
|
|
411
|
-
charSpacing: element.charSpacing || 0,
|
|
412
|
-
splitByGrapheme: element.splitByGrapheme ?? element.wordWrap === "break-word",
|
|
413
|
-
left: 0,
|
|
414
|
-
top: 0
|
|
415
|
-
});
|
|
416
|
-
textbox.initDimensions();
|
|
417
|
-
const lineWidths = textbox.__lineWidths;
|
|
418
|
-
if (lineWidths && lineWidths.length > 0) {
|
|
419
|
-
const maxLine = Math.max(...lineWidths);
|
|
420
|
-
return Math.ceil(maxLine) + 2;
|
|
421
|
-
}
|
|
422
|
-
} catch (_) {
|
|
423
|
-
}
|
|
424
|
-
return typeof element.width === "number" ? element.width : 200;
|
|
425
|
-
}
|
|
426
399
|
function fallbackEstimateHeight(element) {
|
|
427
400
|
if (element.type !== "text" || !element.text) {
|
|
428
401
|
return element.height || 20;
|
|
@@ -2778,11 +2751,22 @@ const waitUntilFontsAvailable = async (fontFamilies, options) => {
|
|
|
2778
2751
|
}
|
|
2779
2752
|
};
|
|
2780
2753
|
const clearFabricCharCache = () => {
|
|
2754
|
+
var _a;
|
|
2781
2755
|
const fabricAny = fabric;
|
|
2756
|
+
if (fabricAny.cache && typeof fabricAny.cache.clearFontCache === "function") {
|
|
2757
|
+
fabricAny.cache.clearFontCache();
|
|
2758
|
+
}
|
|
2759
|
+
if (((_a = fabricAny.cache) == null ? void 0 : _a.charWidthsCache) instanceof Map) {
|
|
2760
|
+
fabricAny.cache.charWidthsCache.clear();
|
|
2761
|
+
}
|
|
2782
2762
|
if (typeof fabricAny.charWidthsCache === "object" && fabricAny.charWidthsCache !== null) {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
}
|
|
2763
|
+
if (fabricAny.charWidthsCache instanceof Map) {
|
|
2764
|
+
fabricAny.charWidthsCache.clear();
|
|
2765
|
+
} else {
|
|
2766
|
+
Object.keys(fabricAny.charWidthsCache).forEach((key) => {
|
|
2767
|
+
delete fabricAny.charWidthsCache[key];
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2786
2770
|
}
|
|
2787
2771
|
if (typeof fabric.util !== "undefined" && typeof fabric.util.clearFabricFontCache === "function") {
|
|
2788
2772
|
fabric.util.clearFabricFontCache();
|
|
@@ -5557,6 +5541,8 @@ function createText(element) {
|
|
|
5557
5541
|
const targetScaleY = element.scaleY ?? 1;
|
|
5558
5542
|
const textbox = new fabric.Textbox(text, {
|
|
5559
5543
|
width: targetWidth,
|
|
5544
|
+
minWidth: 1,
|
|
5545
|
+
dynamicMinWidth: 0,
|
|
5560
5546
|
scaleX: targetScaleX,
|
|
5561
5547
|
scaleY: targetScaleY,
|
|
5562
5548
|
fontSize,
|
|
@@ -5577,6 +5563,8 @@ function createText(element) {
|
|
|
5577
5563
|
textbox.initDimensions();
|
|
5578
5564
|
textbox.set({
|
|
5579
5565
|
width: targetWidth,
|
|
5566
|
+
minWidth: 1,
|
|
5567
|
+
dynamicMinWidth: 0,
|
|
5580
5568
|
scaleX: targetScaleX,
|
|
5581
5569
|
scaleY: targetScaleY
|
|
5582
5570
|
});
|
|
@@ -5586,6 +5574,7 @@ function createText(element) {
|
|
|
5586
5574
|
const scaleYAfterSet = textbox.scaleY ?? 1;
|
|
5587
5575
|
if (Math.abs(widthAfterSet - targetWidth) > 0.01 || Math.abs(scaleXAfterSet - targetScaleX) > 0.01 || Math.abs(scaleYAfterSet - targetScaleY) > 0.01) {
|
|
5588
5576
|
textbox.width = targetWidth;
|
|
5577
|
+
textbox.dynamicMinWidth = 0;
|
|
5589
5578
|
textbox.scaleX = targetScaleX;
|
|
5590
5579
|
textbox.scaleY = targetScaleY;
|
|
5591
5580
|
textbox.setCoords();
|
|
@@ -6432,6 +6421,48 @@ const PageCanvas = forwardRef(
|
|
|
6432
6421
|
if (!canvas2) return false;
|
|
6433
6422
|
return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
|
|
6434
6423
|
}, []);
|
|
6424
|
+
const reflowTextboxesFromCurrentElements = useCallback((canvas2) => {
|
|
6425
|
+
const elementById = new Map(elementsRef.current.map((el) => [el.id, el]));
|
|
6426
|
+
let didReflow = false;
|
|
6427
|
+
const reflowObject = (obj) => {
|
|
6428
|
+
var _a;
|
|
6429
|
+
if (obj instanceof fabric.Group) {
|
|
6430
|
+
(_a = obj._objects) == null ? void 0 : _a.forEach(reflowObject);
|
|
6431
|
+
obj.dirty = true;
|
|
6432
|
+
return;
|
|
6433
|
+
}
|
|
6434
|
+
if (!(obj instanceof fabric.Textbox)) return;
|
|
6435
|
+
const id = getObjectId(obj);
|
|
6436
|
+
const element = id ? elementById.get(id) : void 0;
|
|
6437
|
+
if (!element) return;
|
|
6438
|
+
const targetWidth = Math.max(1, Number(element.width) > 0 ? Number(element.width) : Number(obj.width ?? 200));
|
|
6439
|
+
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
6440
|
+
const splitByGrapheme = overflowPolicy === "auto-shrink" ? false : element.splitByGrapheme ?? element.wordWrap === "break-word";
|
|
6441
|
+
obj.set({
|
|
6442
|
+
width: targetWidth,
|
|
6443
|
+
minWidth: 1,
|
|
6444
|
+
dynamicMinWidth: 0,
|
|
6445
|
+
text: element.text || "Text",
|
|
6446
|
+
fontSize: element.fontSize || 16,
|
|
6447
|
+
fontFamily: element.fontFamily || "Open Sans",
|
|
6448
|
+
fontWeight: element.fontWeight || 400,
|
|
6449
|
+
fontStyle: element.fontStyle || "normal",
|
|
6450
|
+
lineHeight: element.lineHeight || 1.2,
|
|
6451
|
+
charSpacing: element.charSpacing || 0,
|
|
6452
|
+
splitByGrapheme
|
|
6453
|
+
});
|
|
6454
|
+
obj.initDimensions();
|
|
6455
|
+
if (Math.abs((obj.width ?? 0) - targetWidth) > 0.01) {
|
|
6456
|
+
obj.width = targetWidth;
|
|
6457
|
+
}
|
|
6458
|
+
obj.dynamicMinWidth = 0;
|
|
6459
|
+
obj.setCoords();
|
|
6460
|
+
obj.dirty = true;
|
|
6461
|
+
didReflow = true;
|
|
6462
|
+
};
|
|
6463
|
+
canvas2.getObjects().forEach(reflowObject);
|
|
6464
|
+
if (didReflow) canvas2.requestRenderAll();
|
|
6465
|
+
}, []);
|
|
6435
6466
|
useEffect(() => {
|
|
6436
6467
|
if (!canvasElRef.current) return;
|
|
6437
6468
|
const zoom2 = workspaceZoom || 1;
|
|
@@ -6512,6 +6543,8 @@ const PageCanvas = forwardRef(
|
|
|
6512
6543
|
};
|
|
6513
6544
|
initFonts();
|
|
6514
6545
|
const persistTextDimensionsAfterFontLoad = (canvas2) => {
|
|
6546
|
+
reflowTextboxesFromCurrentElements(canvas2);
|
|
6547
|
+
if (isPreviewMode) return;
|
|
6515
6548
|
const state = useEditorStore.getState();
|
|
6516
6549
|
const page = state.canvas.pages.find((p) => p.id === pageId);
|
|
6517
6550
|
if (!page) return;
|
|
@@ -9108,10 +9141,11 @@ const PageCanvas = forwardRef(
|
|
|
9108
9141
|
text = result;
|
|
9109
9142
|
}
|
|
9110
9143
|
}
|
|
9111
|
-
const
|
|
9112
|
-
const textboxWidth = overflowPolicy === "auto-shrink" ? fixedWidth : Math.max(storedWidth, minWidth);
|
|
9144
|
+
const textboxWidth = fixedWidth;
|
|
9113
9145
|
obj.set({
|
|
9114
9146
|
width: textboxWidth,
|
|
9147
|
+
minWidth: 1,
|
|
9148
|
+
dynamicMinWidth: 0,
|
|
9115
9149
|
fontSize,
|
|
9116
9150
|
fontFamily: element.fontFamily || "Open Sans",
|
|
9117
9151
|
fill: element.fill || "#1a1a1a",
|
|
@@ -9131,6 +9165,7 @@ const PageCanvas = forwardRef(
|
|
|
9131
9165
|
if (Math.abs((obj.width ?? 0) - textboxWidth) > 0.01) {
|
|
9132
9166
|
obj.width = textboxWidth;
|
|
9133
9167
|
}
|
|
9168
|
+
obj.dynamicMinWidth = 0;
|
|
9134
9169
|
obj.setCoords();
|
|
9135
9170
|
obj.dirty = true;
|
|
9136
9171
|
try {
|
|
@@ -12919,7 +12954,6 @@ function PixldocsPreview(props) {
|
|
|
12919
12954
|
const [isLoading, setIsLoading] = useState(false);
|
|
12920
12955
|
const [fontsReady, setFontsReady] = useState(false);
|
|
12921
12956
|
const [canvasSettled, setCanvasSettled] = useState(false);
|
|
12922
|
-
const [stabilizationPass, setStabilizationPass] = useState(0);
|
|
12923
12957
|
const isResolveMode = !("config" in props && props.config);
|
|
12924
12958
|
useEffect(() => {
|
|
12925
12959
|
if (!isResolveMode) {
|
|
@@ -12990,21 +13024,16 @@ function PixldocsPreview(props) {
|
|
|
12990
13024
|
isResolveMode ? props.themeId : void 0
|
|
12991
13025
|
]);
|
|
12992
13026
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
12993
|
-
const previewKey = useMemo(
|
|
12994
|
-
() => `${pageIndex}-${stabilizationPass}`,
|
|
12995
|
-
[pageIndex, stabilizationPass]
|
|
12996
|
-
);
|
|
13027
|
+
const previewKey = useMemo(() => `${pageIndex}`, [pageIndex]);
|
|
12997
13028
|
useEffect(() => {
|
|
12998
13029
|
if (isResolveMode) return;
|
|
12999
13030
|
if (!config) {
|
|
13000
13031
|
setFontsReady(false);
|
|
13001
13032
|
setCanvasSettled(false);
|
|
13002
|
-
setStabilizationPass(0);
|
|
13003
13033
|
return;
|
|
13004
13034
|
}
|
|
13005
13035
|
setFontsReady(false);
|
|
13006
13036
|
setCanvasSettled(false);
|
|
13007
|
-
setStabilizationPass(0);
|
|
13008
13037
|
let cancelled = false;
|
|
13009
13038
|
const hasAutoShrink = configHasAutoShrinkText$1(config);
|
|
13010
13039
|
const waitMs = hasAutoShrink ? 4e3 : 1800;
|
|
@@ -13027,16 +13056,10 @@ function PixldocsPreview(props) {
|
|
|
13027
13056
|
};
|
|
13028
13057
|
}, [isResolveMode, config]);
|
|
13029
13058
|
const handleCanvasReady = useCallback(() => {
|
|
13030
|
-
|
|
13031
|
-
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
|
|
13032
|
-
setCanvasSettled(false);
|
|
13033
|
-
setStabilizationPass(1);
|
|
13034
|
-
return;
|
|
13035
|
-
}
|
|
13036
|
-
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
|
|
13059
|
+
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready", { pageIndex, action: "settled" });
|
|
13037
13060
|
setCanvasSettled(true);
|
|
13038
13061
|
onReady == null ? void 0 : onReady();
|
|
13039
|
-
}, [onReady, pageIndex
|
|
13062
|
+
}, [onReady, pageIndex]);
|
|
13040
13063
|
if (isLoading) {
|
|
13041
13064
|
return /* @__PURE__ */ jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
13042
13065
|
}
|
|
@@ -14558,6 +14581,10 @@ function getEmbeddedJsPDFFontName(fontName, weight, isItalic = false) {
|
|
|
14558
14581
|
function isFontAvailable(fontName) {
|
|
14559
14582
|
return fontName in FONT_FILES;
|
|
14560
14583
|
}
|
|
14584
|
+
const registeredFamilies = /* @__PURE__ */ new Set();
|
|
14585
|
+
function isFamilyEmbedded(family) {
|
|
14586
|
+
return registeredFamilies.has(family);
|
|
14587
|
+
}
|
|
14561
14588
|
const ttfCache = /* @__PURE__ */ new Map();
|
|
14562
14589
|
async function fetchTTFAsBase64(url) {
|
|
14563
14590
|
const cached = ttfCache.get(url);
|
|
@@ -14630,12 +14657,133 @@ async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
|
|
|
14630
14657
|
} catch {
|
|
14631
14658
|
}
|
|
14632
14659
|
}
|
|
14660
|
+
registeredFamilies.add(fontName);
|
|
14633
14661
|
return true;
|
|
14634
14662
|
} catch (e) {
|
|
14635
14663
|
console.warn(`[pdf-fonts] Failed to embed ${fontName} w${weight}:`, e);
|
|
14636
14664
|
return false;
|
|
14637
14665
|
}
|
|
14638
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
|
+
}
|
|
14639
14787
|
async function embedFontsForConfig(pdf, config, fontBaseUrl) {
|
|
14640
14788
|
const fontKeys = /* @__PURE__ */ new Set();
|
|
14641
14789
|
const SEP = "";
|
|
@@ -14794,7 +14942,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
14794
14942
|
const rawFf = resolveInheritedValue(el, "font-family");
|
|
14795
14943
|
if (!rawFf) continue;
|
|
14796
14944
|
const clean = (_a = rawFf.split(",")[0]) == null ? void 0 : _a.replace(/['"]/g, "").trim();
|
|
14797
|
-
if (!isFontAvailable(clean)) continue;
|
|
14945
|
+
if (!isFontAvailable(clean) && !isFamilyEmbedded(clean)) continue;
|
|
14798
14946
|
const weightRaw = resolveInheritedValue(el, "font-weight") || "400";
|
|
14799
14947
|
const styleRaw = resolveInheritedValue(el, "font-style") || "normal";
|
|
14800
14948
|
const weight = resolveWeightNum(weightRaw);
|
|
@@ -14877,14 +15025,19 @@ async function embedFontsInPdf(pdf, fontFamilies, fontBaseUrl) {
|
|
|
14877
15025
|
fontFamilies.add(FONT_FALLBACK_SYMBOLS);
|
|
14878
15026
|
fontFamilies.add(FONT_FALLBACK_DEVANAGARI);
|
|
14879
15027
|
for (const family of fontFamilies) {
|
|
14880
|
-
if (
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
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 {
|
|
14885
15037
|
tasks.push(
|
|
14886
|
-
|
|
14887
|
-
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`);
|
|
14888
15041
|
})
|
|
14889
15042
|
);
|
|
14890
15043
|
}
|
|
@@ -14900,6 +15053,7 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14900
15053
|
FONT_FILES,
|
|
14901
15054
|
FONT_WEIGHT_LABELS,
|
|
14902
15055
|
embedFont,
|
|
15056
|
+
embedFontWithGoogleFallback,
|
|
14903
15057
|
embedFontsForConfig,
|
|
14904
15058
|
embedFontsInPdf,
|
|
14905
15059
|
extractFontFamiliesFromSvgs,
|