Die Local Font Access API bietet einen Mechanismus für den Zugriff auf die lokal installierten Schriftartdaten des Nutzers, einschließlich Details auf höherer Ebene wie Namen, Stile und Familien sowie die Rohbytes der zugrunde liegenden Schriftartdateien. Hier erfahren Sie, wie die SVG-Bearbeitungs-App Boxy SVG diese API nutzt.
Einführung
(Dieser Artikel ist auch als Video verfügbar.)
Boxy SVG ist ein Vektorgrafikeditor. Das Programm wird hauptsächlich zum Bearbeiten von Zeichnungen im SVG-Dateiformat verwendet, um Illustrationen, Logos, Symbole und andere Elemente des Grafikdesigns zu erstellen. Die App wurde vom polnischen Entwickler Jarosław Foksa entwickelt und am 15. März 2013 veröffentlicht. Jarosław betreibt einen Boxy SVG-Blog, in dem er neue Funktionen ankündigt, die er der App hinzufügt. Der Entwickler ist ein großer Unterstützer von Project Fugu von Chromium und hat sogar ein Fugu-Tag im Ideen-Tracker der App.
Local Font Access API in Boxy SVG
Eine Funktion, die Jarosław in seinem Blog vorgestellt hat, ist die Local Font Access API. Mit der Local Font Access API können Nutzer auf ihre lokal installierten Schriftarten zugreifen, einschließlich detaillierter Informationen wie Namen, Stile und Familien sowie der Rohbytes der zugrunde liegenden Schriftartdateien. Im folgenden Screenshot sehen Sie, wie ich der App Zugriff auf die lokal installierten Schriftarten auf meinem MacBook gewährt und die Schriftart „Marker Felt“ für meinen Text ausgewählt habe.
Der zugrunde liegende Code ist recht einfach. Wenn der Nutzer die Schriftfamilienauswahl zum ersten Mal öffnet, prüft die Anwendung zuerst, ob der Webbrowser die Local Font Access API unterstützt.
Außerdem wird nach der alten experimentellen Version der API gesucht und diese verwendet, falls sie vorhanden ist. Seit 2023 können Sie die alte API ignorieren, da sie nur kurze Zeit über experimentelle Chrome-Flags verfügbar war. Einige Chromium-Derivate verwenden sie jedoch möglicherweise noch.
let isLocalFontsApiEnabled = (
// Local Font Access API, Chrome >= 102
window.queryLocalFonts !== undefined ||
// Experimental Local Font Access API, Chrome < 102
navigator.fonts?.query !== undefined
);
Wenn die Local Font Access API nicht verfügbar ist, wird die Schriftfamilienauswahl grau dargestellt. Statt der Schriftartenliste wird dem Nutzer ein Platzhaltertext angezeigt:
if (isLocalFontsApiEnabled === false) {
showPlaceholder("no-local-fonts-api");
return;
}
Andernfalls wird die Local Font Access API verwendet, um die Liste aller Schriftarten aus dem Betriebssystem abzurufen. Beachten Sie den try…catch
-Block, der für die ordnungsgemäße Behandlung von Berechtigungsfehlern erforderlich ist.
let localFonts;
if (isLocalFontsApiEnabled === true) {
try {
// Local Font Access API, Chrome >= 102
if (window.queryLocalFonts) {
localFonts = await window.queryLocalFonts();
}
// Experimental Local Font Access API, Chrome < 102
else if (navigator.fonts?.query) {
localFonts = await navigator.fonts.query({
persistentAccess: true,
});
}
} catch (error) {
showError(error.message, error.name);
}
}
Nachdem die Liste der lokalen Schriftarten abgerufen wurde, wird daraus ein vereinfachtes und normalisiertes fontsIndex
erstellt:
let fontsIndex = [];
for (let localFont of localFonts) {
let face = "400";
// Determine the face name
{
let subfamily = localFont.style.toLowerCase();
subfamily = subfamily.replaceAll(" ", "");
subfamily = subfamily.replaceAll("-", "");
subfamily = subfamily.replaceAll("_", "");
if (subfamily.includes("thin")) {
face = "100";
} else if (subfamily.includes("extralight")) {
face = "200";
} else if (subfamily.includes("light")) {
face = "300";
} else if (subfamily.includes("medium")) {
face = "500";
} else if (subfamily.includes("semibold")) {
face = "600";
} else if (subfamily.includes("extrabold")) {
face = "800";
} else if (subfamily.includes("ultrabold")) {
face = "900";
} else if (subfamily.includes("bold")) {
face = "700";
}
if (subfamily.includes("italic")) {
face += "i";
}
}
let descriptor = fontsIndex.find((descriptor) => {
return descriptor.family === localFont.family);
});
if (descriptor) {
if (descriptor.faces.includes(face) === false) {
descriptor.faces.push(face);
}
} else {
let descriptor = {
family: localFont.family,
faces: [face],
};
fontsIndex.push(descriptor);
}
}
for (let descriptor of fontsIndex) {
descriptor.faces.sort();
}
Der normalisierte Schriftartenindex wird dann in der IndexedDB-Datenbank gespeichert, sodass er einfach abgefragt, zwischen App-Instanzen geteilt und zwischen Sitzungen beibehalten werden kann. Boxy SVG verwendet Dexie.js zum Verwalten der Datenbank:
let database = new Dexie("LocalFontsManager");
database.version(1).stores({cache: "family"}).
await database.cache.clear();
await database.cache.bulkPut(fontsIndex);
Sobald die Datenbank gefüllt ist, kann das Schriftartauswahl-Widget sie abfragen und die Ergebnisse auf dem Bildschirm anzeigen:
Boxy SVG rendert die Liste in einem benutzerdefinierten Element namens <bx-fontfamilypicker>
und weist jedem Schriftartlistenelement einen Stil zu, sodass es in der jeweiligen Schriftfamilie angezeigt wird. Um das Element vom Rest der Seite zu isolieren, verwendet Boxy SVG in diesem und anderen benutzerdefinierten Elementen das Shadow DOM.
Zusammenfassung
Die Funktion für lokale Schriftarten ist sehr beliebt. Nutzer können damit auf ihre lokalen Schriftarten für ihre Designs und Kreationen zugreifen. Als sich die API-Form änderte und die Funktion kurzzeitig nicht mehr funktionierte, bemerkten die Nutzer das sofort. Jarosław hat den Code schnell in das defensive Muster geändert, das Sie im Snippet oben sehen. Es funktioniert mit der aktuellen Chrome-Version und auch mit anderen Chromium-Derivaten, die möglicherweise noch nicht auf die neueste Version umgestellt wurden. Probieren Sie Boxy SVG aus und sehen Sie sich Ihre lokal installierten Schriftarten an. Vielleicht entdecken Sie einige längst vergessene Klassiker wie Zapf Dingbats oder Webdings.