mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: fonts not loading on export (again) (#9064)
This commit is contained in:
parent
a58822c1c1
commit
d29c3db7f6
1 changed files with 9 additions and 35 deletions
|
@ -3,7 +3,6 @@ import {
|
||||||
FONT_FAMILY_FALLBACKS,
|
FONT_FAMILY_FALLBACKS,
|
||||||
CJK_HAND_DRAWN_FALLBACK_FONT,
|
CJK_HAND_DRAWN_FALLBACK_FONT,
|
||||||
WINDOWS_EMOJI_FALLBACK_FONT,
|
WINDOWS_EMOJI_FALLBACK_FONT,
|
||||||
isSafari,
|
|
||||||
getFontFamilyFallbacks,
|
getFontFamilyFallbacks,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
import { isTextElement } from "../element";
|
import { isTextElement } from "../element";
|
||||||
|
@ -137,50 +136,28 @@ export class Fonts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load font faces for a given scene and trigger scene update.
|
* Load font faces for a given scene and trigger scene update.
|
||||||
*
|
|
||||||
* FontFaceSet loadingdone event we listen on may not always
|
|
||||||
* fire (looking at you Safari), so on init we manually load all
|
|
||||||
* fonts and rerender scene text elements once done.
|
|
||||||
*
|
|
||||||
* For Safari we make sure to check against each loaded font face
|
|
||||||
* with the unique characters per family in the scene,
|
|
||||||
* otherwise fonts might remain unloaded.
|
|
||||||
*/
|
*/
|
||||||
public loadSceneFonts = async (): Promise<FontFace[]> => {
|
public loadSceneFonts = async (): Promise<FontFace[]> => {
|
||||||
const sceneFamilies = this.getSceneFamilies();
|
const sceneFamilies = this.getSceneFamilies();
|
||||||
const charsPerFamily = isSafari
|
const charsPerFamily = Fonts.getCharsPerFamily(
|
||||||
? Fonts.getCharsPerFamily(this.scene.getNonDeletedElements())
|
this.scene.getNonDeletedElements(),
|
||||||
: undefined;
|
);
|
||||||
|
|
||||||
return Fonts.loadFontFaces(sceneFamilies, charsPerFamily);
|
return Fonts.loadFontFaces(sceneFamilies, charsPerFamily);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load font faces for passed elements - use when the scene is unavailable (i.e. export).
|
* Load font faces for passed elements - use when the scene is unavailable (i.e. export).
|
||||||
*
|
|
||||||
* For Safari we make sure to check against each loaded font face,
|
|
||||||
* with the unique characters per family in the elements
|
|
||||||
* otherwise fonts might remain unloaded.
|
|
||||||
*/
|
*/
|
||||||
public static loadElementsFonts = async (
|
public static loadElementsFonts = async (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
): Promise<FontFace[]> => {
|
): Promise<FontFace[]> => {
|
||||||
const fontFamilies = Fonts.getUniqueFamilies(elements);
|
const fontFamilies = Fonts.getUniqueFamilies(elements);
|
||||||
const charsPerFamily = isSafari
|
const charsPerFamily = Fonts.getCharsPerFamily(elements);
|
||||||
? Fonts.getCharsPerFamily(elements)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return Fonts.loadFontFaces(fontFamilies, charsPerFamily);
|
return Fonts.loadFontFaces(fontFamilies, charsPerFamily);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Load all registered font faces.
|
|
||||||
*/
|
|
||||||
public static loadAllFonts = async (): Promise<FontFace[]> => {
|
|
||||||
const allFamilies = Fonts.getAllFamilies();
|
|
||||||
return Fonts.loadFontFaces(allFamilies);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate CSS @font-face declarations for the given elements.
|
* Generate CSS @font-face declarations for the given elements.
|
||||||
*/
|
*/
|
||||||
|
@ -223,7 +200,7 @@ export class Fonts {
|
||||||
|
|
||||||
private static async loadFontFaces(
|
private static async loadFontFaces(
|
||||||
fontFamilies: Array<ExcalidrawTextElement["fontFamily"]>,
|
fontFamilies: Array<ExcalidrawTextElement["fontFamily"]>,
|
||||||
charsPerFamily?: Record<number, Set<string>>,
|
charsPerFamily: Record<number, Set<string>>,
|
||||||
) {
|
) {
|
||||||
// add all registered font faces into the `document.fonts` (if not added already)
|
// add all registered font faces into the `document.fonts` (if not added already)
|
||||||
for (const { fontFaces, metadata } of Fonts.registered.values()) {
|
for (const { fontFaces, metadata } of Fonts.registered.values()) {
|
||||||
|
@ -248,7 +225,7 @@ export class Fonts {
|
||||||
|
|
||||||
private static *fontFacesLoader(
|
private static *fontFacesLoader(
|
||||||
fontFamilies: Array<ExcalidrawTextElement["fontFamily"]>,
|
fontFamilies: Array<ExcalidrawTextElement["fontFamily"]>,
|
||||||
charsPerFamily?: Record<number, Set<string>>,
|
charsPerFamily: Record<number, Set<string>>,
|
||||||
): Generator<Promise<void | readonly [number, FontFace[]]>> {
|
): Generator<Promise<void | readonly [number, FontFace[]]>> {
|
||||||
for (const [index, fontFamily] of fontFamilies.entries()) {
|
for (const [index, fontFamily] of fontFamilies.entries()) {
|
||||||
const font = getFontString({
|
const font = getFontString({
|
||||||
|
@ -256,12 +233,9 @@ export class Fonts {
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
});
|
});
|
||||||
|
|
||||||
// WARN: without "text" param it does not have to mean that all font faces are loaded, instead it could be just one!
|
// WARN: without "text" param it does not have to mean that all font faces are loaded as it could be just one irrelevant font face!
|
||||||
// for Safari on init, we rather check with the "text" param, even though it's less efficient, as otherwise fonts might remain unloaded
|
// instead, we are always checking chars used in the family, so that no required font faces remain unloaded
|
||||||
const text =
|
const text = Fonts.getCharacters(charsPerFamily, fontFamily);
|
||||||
isSafari && charsPerFamily
|
|
||||||
? Fonts.getCharacters(charsPerFamily, fontFamily)
|
|
||||||
: "";
|
|
||||||
|
|
||||||
if (!window.document.fonts.check(font, text)) {
|
if (!window.document.fonts.check(font, text)) {
|
||||||
yield promiseTry(async () => {
|
yield promiseTry(async () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue