Die Local Font Access API bietet einen Mechanismus zum 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 Schriftdateien. 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 Vektorgrafik-Editor. Ihr Hauptanwendungsfall ist die Bearbeitung von Zeichnungen im SVG-Dateiformat, um Illustrationen, Logos, Symbole und andere Elemente des Grafikdesigns zu erstellen. Es 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 starker 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 neue Funktion, über die Jarosław gebloggt hat, war die Local Font Access API. Über die Local Font Access API können Nutzer auf ihre lokal installierten Schriftarten zugreifen, einschließlich Details auf höherer Ebene wie Namen, Stile und Familien sowie die Rohbytes der zugrunde liegenden Schriftdateien. 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 Schriftartenauswahl zum ersten Mal öffnet, prüft die Anwendung zuerst, ob der Webbrowser die Local Font Access API unterstützt.
Außerdem wird die alte experimentelle Version der API geprüft und verwendet, falls vorhanden. Ab 2023 können Sie die alte API ignorieren, da sie nur für kurze Zeit über experimentelle Chrome-Flags verfügbar war. Einige Chromium-Derivate verwenden sie jedoch möglicherweise weiterhin.
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. Anstelle 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 Block try…catch
, der erforderlich ist, um Berechtigungsfehler ordnungsgemäß zu behandeln.
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 eine vereinfachte und normalisierte 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 Schriftindex wird dann in der IndexedDB-Datenbank gespeichert, damit er einfach abgefragt, zwischen App-Instanzen freigegeben und zwischen Sitzungen beibehalten werden kann. Boxy SVG verwendet Dexie.js, um die Datenbank zu verwalten:
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 Widget für die Schriftauswahl sie abfragen und die Ergebnisse auf dem Bildschirm anzeigen:
Beachten Sie, dass Boxy SVG die Liste in einem benutzerdefinierten Element namens <bx-fontfamilypicker>
rendert und jedes Schriftlistenelement so formatiert, dass 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.
Schlussfolgerungen
Die Funktion für lokale Schriftarten ist sehr beliebt, da Nutzer so auf ihre lokalen Schriftarten für ihre Designs und Kreationen zugreifen können. Als sich die API-Form änderte und die Funktion kurzzeitig nicht funktionierte, haben die Nutzer das sofort bemerkt. Jarosław änderte den Code schnell in das defensive Muster, 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 schon längst vergessene Klassiker wie Zapf Dingbats oder Webdings.