82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
const fontListAPI = "https://api.graphite.rs/font-list";
|
|
|
|
// Taken from https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping
|
|
const weightNameMapping = new Map([
|
|
[100, "Thin"],
|
|
[200, "Extra Light"],
|
|
[300, "Light"],
|
|
[400, "Normal"],
|
|
[500, "Medium"],
|
|
[600, "Semi Bold"],
|
|
[700, "Bold"],
|
|
[800, "Extra Bold"],
|
|
[900, "Black"],
|
|
[950, "Extra Black"],
|
|
]);
|
|
|
|
type fontCallbackType = (font: string, data: Uint8Array) => void;
|
|
|
|
let fontList = [] as { family: string; variants: string[]; files: Map<string, string> }[];
|
|
let loadDefaultFontCallback = undefined as fontCallbackType | undefined;
|
|
|
|
fetch(fontListAPI)
|
|
.then((response) => response.json())
|
|
.then((json) => {
|
|
const loadedFonts = json.items as { family: string; variants: string[]; files: { [name: string]: string } }[];
|
|
fontList = loadedFonts.map((font) => {
|
|
const { family } = font;
|
|
const variants = font.variants.map(formatFontStyleName);
|
|
const files = new Map(font.variants.map((x) => [formatFontStyleName(x), font.files[x]]));
|
|
return { family, variants, files };
|
|
});
|
|
loadDefaultFont();
|
|
});
|
|
|
|
function formatFontStyleName(fontStyle: string): string {
|
|
const isItalic = fontStyle.endsWith("italic");
|
|
const weight = fontStyle === "regular" || fontStyle === "italic" ? 400 : parseInt(fontStyle, 10);
|
|
let weightName = "";
|
|
|
|
let bestWeight = Infinity;
|
|
weightNameMapping.forEach((nameChecking, weightChecking) => {
|
|
if (Math.abs(weightChecking - weight) < bestWeight) {
|
|
bestWeight = Math.abs(weightChecking - weight);
|
|
weightName = nameChecking;
|
|
}
|
|
});
|
|
|
|
return `${weightName}${isItalic ? " Italic" : ""} (${weight})`;
|
|
}
|
|
|
|
export function loadDefaultFont(): void {
|
|
const font = getFontFile("Merriweather", "Normal (400)");
|
|
|
|
if (font) {
|
|
fetch(font)
|
|
.then((response) => response.arrayBuffer())
|
|
.then((response) => {
|
|
if (loadDefaultFontCallback) loadDefaultFontCallback(font, new Uint8Array(response));
|
|
});
|
|
}
|
|
}
|
|
|
|
export function setLoadDefaultFontCallback(callback: fontCallbackType): void {
|
|
loadDefaultFontCallback = callback;
|
|
loadDefaultFont();
|
|
}
|
|
|
|
export function fontNames(): string[] {
|
|
return fontList.map((value) => value.family);
|
|
}
|
|
|
|
export function getFontStyles(fontFamily: string): string[] {
|
|
const font = fontList.find((value) => value.family === fontFamily);
|
|
return font ? font.variants : [];
|
|
}
|
|
|
|
export function getFontFile(fontFamily: string, fontStyle: string): string | undefined {
|
|
const font = fontList.find((value) => value.family === fontFamily);
|
|
const fontFile = font && font.files.get(fontStyle);
|
|
return fontFile && fontFile.replace("http://", "https://");
|
|
}
|