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 für den Zugriff auf die lokal installierten Schriftartdaten des Nutzers, darunter auch übergeordnete Details wie Namen, Stile und Familien sowie die Rohbyte der zugrunde liegenden Schriftartdateien. So nutzt die SVG-Bearbeitungs-App Boxy SVG diese API.

Einführung

(Dieser Artikel ist auch in Form eines Videos verfügbar.)

Boxy SVG ist ein Vektorgrafikeditor. Sie wird hauptsächlich zum Bearbeiten von Zeichnungen im SVG-Dateiformat verwendet, um Illustrationen, Logos, Symbole und andere Elemente des Grafikdesigns zu erstellen. Sie wurde vom polnischen Entwickler Jarosław Foksa entwickelt und wurde 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 Befürworter des Chromium-Projekts Fugu und hat sogar ein Fugu-Tag im Ideen-Tracker der App.

Mit der SVG-App von Boxy wird das Project Fugu-Symbol SVG bearbeitet.

Lokale Font Access API in Boxy (SVG)

Eine Neuerung, die Jarosław in seinem Blog veröffentlicht hat, war die Local Font Access API. Mit der Local Font Access API können Nutzer auf ihre lokal installierten Schriftarten zugreifen, einschließlich allgemeiner Details wie Namen, Stile und Familien sowie die Rohbyte der zugrunde liegenden Schriftartdateien. Im folgenden Screenshot sehen Sie, wie ich der App Zugriff auf die lokal auf meinem MacBook installierten Schriftarten gewährt und die Schriftart Marker Felt für meinen Text ausgewählt habe.

Die Boxy SVG-App bearbeitet das Project Fugu-Symbol SVG und fügt den Text „Project Fugu Rocks“ in der Schriftart „Marker Felt“ hinzu, der in der Schriftartauswahl ausgewählt ist.

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 wird verwendet, falls vorhanden. Seit 2023 können Sie die alte API bedenkenlos ignorieren, da sie nur für 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. Anstelle der Schriftartenliste wird dem Nutzer ein Platzhaltertext angezeigt:

if (isLocalFontsApiEnabled === false) {
  showPlaceholder("no-local-fonts-api");
  return;
}

Schriftartauswahl mit der Meldung „Ihr Browser unterstützt die Local Font Access API nicht“.

Andernfalls wird die Local Font Access API verwendet, um die Liste aller Schriftarten vom Betriebssystem abzurufen. Beachten Sie den try…catch-Block, der erforderlich ist, um Berechtigungsfehler richtig zu verarbeiten.

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 Schriftartenindex wird dann in der IndexedDB-Datenbank gespeichert, damit er einfach abgefragt, von Anwendungsinstanzen gemeinsam genutzt und zwischen Sitzungen beibehalten werden kann. Boxy SVG verwendet zur Verwaltung der Datenbank Dexie.js:

let database = new Dexie("LocalFontsManager");
database.version(1).stores({cache: "family"}).
await database.cache.clear();
await database.cache.bulkPut(fontsIndex);

Bereich „Speicher“ der Chrome-Entwicklertools mit der Tabelle „IndexedDB“ mit dem Schriftarten-Cache.

Sobald die Datenbank ausgefüllt ist, kann das Schriftartauswahl-Widget diese abfragen und die Ergebnisse auf dem Bildschirm anzeigen:

Schriftartauswahl mit Schriftarten ausgefüllt.

Hinweis: Boxy SVG rendert die Liste in einem benutzerdefinierten Element namens <bx-fontfamilypicker> und gestaltet die einzelnen Schriftartlistenelemente so, dass sie in der jeweiligen Schriftfamilie angezeigt werden. Um vom Rest der Seite zu isolieren, verwendet Boxy SVG das Shadow DOM in diesem und anderen benutzerdefinierten Elementen.

Bereich „Elemente“ in Chrome DevTools mit der zu prüfenden Schriftauswahl: ein benutzerdefiniertes Element namens „bx-fontfamiliypicker“.

Ergebnisse

Die Funktion für lokale Schriftarten ist sehr beliebt, da Nutzer häufig auf lokale Schriftarten für ihre Designs und Kreationen zugreifen. Als sich die API-Form änderte und die Funktion für kurze Zeit fehlerhaft war, bemerkten die Nutzer sofort. Jarosław hat den Code schnell auf das im Snippet oben gezeigte Defensivmuster umgestellt, das mit der aktuellen Version von Chrome und anderen Chromium-Ableitungen funktioniert, die möglicherweise nicht auf die neueste Version umgestellt wurden. Testen Sie Boxy SVG und sehen Sie sich auf jeden Fall auch Ihre lokal installierten Schriftarten an. Vielleicht entdecken Sie längst vergessene Klassiker wie Zapf Dingbats oder Webdings.