Wie die App zur Bearbeitung von Vektorbildern, Boxy SVG, die Local Font Access API nutzt, damit Nutzer ihre bevorzugten lokalen Schriftarten auswählen können

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.

Die Boxy SVG App, in der das SVG-Symbol von Project Fugu bearbeitet wird.

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.

In der Boxy SVG App wird das SVG-Symbol „Project Fugu“ bearbeitet und der Text „Project Fugu rocks“ wird in der Schriftart „Marker Felt“ hinzugefügt, die in der Schriftauswahl ausgewählt ist.

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;
}

In der Schriftartenauswahl wird die Meldung „Ihr Browser unterstützt die Local Font Access API nicht“ angezeigt.

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);

Der Chrome DevTools-Speicherbereich mit der IndexedDB-Tabelle mit dem Schriftarten-Cache

Sobald die Datenbank gefüllt ist, kann das Widget für die Schriftauswahl sie abfragen und die Ergebnisse auf dem Bildschirm anzeigen:

Schriftartenauswahl mit Schriftarten

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.

Der Chrome DevTools-Bereich „Elemente“ mit der untersuchten Schriftartenauswahl: ein benutzerdefiniertes Element namens „bx-fontfamiliypicker“.

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.