From 391497916f0c918931c13e3d0388980f5fcd8853 Mon Sep 17 00:00:00 2001 From: Marcel Mraz Date: Mon, 19 Aug 2024 18:00:02 +0200 Subject: [PATCH] Retrieve first font url when not inlining font --- .../excalidraw/hooks/useLibraryItemSvg.ts | 1 + packages/excalidraw/scene/export.ts | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/excalidraw/hooks/useLibraryItemSvg.ts b/packages/excalidraw/hooks/useLibraryItemSvg.ts index 4e95712af..b1332cb05 100644 --- a/packages/excalidraw/hooks/useLibraryItemSvg.ts +++ b/packages/excalidraw/hooks/useLibraryItemSvg.ts @@ -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) { diff --git a/packages/excalidraw/scene/export.ts b/packages/excalidraw/scene/export.ts index 51b6ccc22..9bf438ec1 100644 --- a/packages/excalidraw/scene/export.ts +++ b/packages/excalidraw/scene/export.ts @@ -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 = ``; @@ -355,7 +356,8 @@ export const exportToSvg = async ( `; } - 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 => { const fontFamilies = new Set(); const codePoints = new Set(); + let getSource: (font: Font) => string | Promise; + 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)}); }`, ), );