-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Query local fonts to show a font list
This uses the [Local Font Access API](https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API) to query the list of fonts installed on the user's system. If we successfully query it we show a combobox with the list of fonts. Otherwise it's still a textbox. We also get information about the styles that are available for each font family. Unfortunately this comes as a string rather than individual fields, so we have to parse it. We do this by looking for specific style names in there. Since this is mostly heuristic based, instead of only showing the styles that we found, we still show all of them, but grey out those that we didn't find, but you can still select them.
- Loading branch information
Showing
2 changed files
with
136 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
let queriedKnownFonts = false; | ||
export let knownFamilies: string[] = []; | ||
export const knownStyles = new Map<string, Set<string>>(); | ||
|
||
// There's three values per row: | ||
// 1. What to look for in the style specifier of the loaded font list. | ||
// 2. The value to tell livesplit-core. | ||
// 3. The label to display in the UI. | ||
export const FONT_WEIGHTS = [ | ||
["thin", "thin", "Thin"], | ||
["extralight", "extra-light", "Extra Light"], | ||
["light", "light", "Light"], | ||
["semilight", "semi-light", "Semi Light"], | ||
["normal", "normal", "Normal"], | ||
["medium", "medium", "Medium"], | ||
["semibold", "semi-bold", "Semi Bold"], | ||
["bold", "bold", "Bold"], | ||
["extrabold", "extra-bold", "Extra Bold"], | ||
["black", "black", "Black"], | ||
["extrablack", "extra-black", "Extra Black"], | ||
]; | ||
|
||
export const FONT_STRETCHES = [ | ||
["ultracondensed", "ultra-condensed", "Ultra Condensed"], | ||
["extracondensed", "extra-condensed", "Extra Condensed"], | ||
["condensed", "condensed", "Condensed"], | ||
["semicondensed", "semi-condensed", "Semi Condensed"], | ||
["normal", "normal", "Normal"], | ||
["semiexpanded", "semi-expanded", "Semi Expanded"], | ||
["expanded", "expanded", "Expanded"], | ||
["extraexpanded", "extra-expanded", "Extra Expanded"], | ||
["ultraexpanded", "ultra-expanded", "Ultra Expanded"], | ||
]; | ||
|
||
// Italics are always supported. | ||
|
||
export function load(loadedCallback: () => void) { | ||
if (!queriedKnownFonts) { | ||
queriedKnownFonts = true; | ||
if ("queryLocalFonts" in window) { | ||
(window as any).queryLocalFonts().then((availableFonts: any) => { | ||
try { | ||
for (const font of availableFonts) { | ||
if (!knownStyles.has(font.family)) { | ||
knownStyles.set(font.family, new Set(["normal", "bold"])); | ||
} | ||
|
||
const set = knownStyles.get(font.family)!; | ||
const styles = (font.style as string).toLowerCase().split(" "); | ||
|
||
for (const [keyword, value] of FONT_STRETCHES) { | ||
if (styles.includes(keyword)) { | ||
set.add(value); | ||
} | ||
} | ||
|
||
for (const [keyword, value] of FONT_WEIGHTS) { | ||
if (styles.includes(keyword)) { | ||
set.add(value); | ||
} | ||
} | ||
} | ||
|
||
knownFamilies = Array.from(knownStyles.keys()); | ||
|
||
loadedCallback(); | ||
} catch { | ||
// It's fine if it fails, it's an experimental web API, and | ||
// the user may reject it. | ||
} | ||
}); | ||
} | ||
} | ||
} |