Retrieve first font url when not inlining font

This commit is contained in:
Marcel Mraz 2024-08-19 18:00:02 +02:00
parent 03a03e8d21
commit 391497916f
2 changed files with 24 additions and 7 deletions

View File

@ -41,6 +41,7 @@ export const useLibraryItemSvg = (
// When there is no svg in cache export it and save to cache
(async () => {
const exportedSvg = await exportLibraryItemToSvg(elements);
// TODO: should likely be removed for custom fonts
exportedSvg.querySelector(".style-fonts")?.remove();
if (exportedSvg) {

View File

@ -39,6 +39,7 @@ import type { RenderableElementsMap } from "./types";
import { syncInvalidIndices } from "../fractionalIndex";
import { renderStaticScene } from "../renderer/staticScene";
import { Fonts } from "../fonts";
import type { Font } from "../fonts/ExcalidrawFont";
const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
@ -355,7 +356,8 @@ export const exportToSvg = async (
</clipPath>`;
}
const fontFaces = opts?.skipInliningFonts ? [] : await getFontFaces(elements);
const shouldInlineFonts = !opts?.skipInliningFonts;
const fontFaces = await getFontFaces(elements, shouldInlineFonts);
svgRoot.innerHTML = `
${SVG_EXPORT_TAG}
@ -436,10 +438,13 @@ export const getExportSize = (
const getFontFaces = async (
elements: readonly ExcalidrawElement[],
shouldInlineFonts: boolean,
): Promise<string[]> => {
const fontFamilies = new Set<number>();
const codePoints = new Set<number>();
let getSource: (font: Font) => string | Promise<string>;
for (const element of elements) {
if (!isTextElement(element)) {
continue;
@ -447,15 +452,26 @@ const getFontFaces = async (
fontFamilies.add(element.fontFamily);
for (const codePoint of Array.from(element.originalText, (u) =>
u.codePointAt(0),
)) {
if (codePoint) {
codePoints.add(codePoint);
// gather unique codepoints only when inlining fonts
if (shouldInlineFonts) {
for (const codePoint of Array.from(element.originalText, (u) =>
u.codePointAt(0),
)) {
if (codePoint) {
codePoints.add(codePoint);
}
}
}
}
if (shouldInlineFonts) {
// retrieve font source as dataurl based on the used codepoints
getSource = (font: Font) => font.getContent(codePoints);
} else {
// retrieve font source as a url otherwise
getSource = (font: Font) => font.urls[0].toString();
}
const fontFaces = await Promise.all(
Array.from(fontFamilies).map(async (x) => {
const { fonts, metadata } = Fonts.registered.get(x) ?? {};
@ -477,7 +493,7 @@ const getFontFaces = async (
fonts.map(
async (font) => `@font-face {
font-family: ${font.fontFace.family};
src: url(${await font.getContent(codePoints)});
src: url(${await getSource(font)});
}`,
),
);