Hoe de vectorafbeeldingsbewerkingsapp Boxy SVG de Local Font Access API gebruikt om gebruikers hun favoriete lokale lettertypen te laten kiezen

De Local Font Access API biedt een mechanisme om toegang te krijgen tot de lokaal geïnstalleerde lettertypegegevens van de gebruiker, inclusief details op een hoger niveau, zoals namen, stijlen en families, evenals de onbewerkte bytes van de onderliggende lettertypebestanden. Ontdek hoe de SVG-bewerkingsapp Boxy SVG gebruik maakt van deze API.

Invoering

(Dit artikel is ook beschikbaar in de vorm van een video.)

Boxy SVG is een vectorafbeeldingseditor. Het belangrijkste gebruiksscenario is het bewerken van tekeningen in het SVG-bestandsformaat, voor het maken van illustraties, logo's, pictogrammen en andere elementen van grafisch ontwerp. Het is ontwikkeld door de Poolse ontwikkelaar Jarosław Foksa en werd oorspronkelijk uitgebracht op 15 maart 2013. Jarosław beheert een Boxy SVG-blog waarin hij nieuwe functies aankondigt die hij aan de app toevoegt. De ontwikkelaar is een groot voorstander van Chromium's Project Fugu en heeft zelfs een Fugu-tag op de ideeëntracker van de app.

De Boxy SVG-app bewerkt het Project Fugu-pictogram SVG.

Lokale API voor toegang tot lettertypen in Boxy SVG

Een functietoevoeging waar Jarosław over blogde, was de Local Font Access API . Met de Local Font Access API hebben gebruikers toegang tot hun lokaal geïnstalleerde lettertypen, inclusief details op een hoger niveau, zoals namen, stijlen en families, evenals de onbewerkte bytes van de onderliggende lettertypebestanden. In de volgende schermafbeelding kun je zien hoe ik de app toegang heb verleend tot de lokaal geïnstalleerde lettertypen op mijn MacBook en het Marker Felt-lettertype voor mijn tekst heb gekozen.

De Boxy SVG-app bewerkt het Project Fugu-pictogram SVG en voegt de tekst 'Project Fugu rocks' toe, ingesteld in het lettertype Marker Felt, dat geselecteerd wordt weergegeven in de lettertypekiezer.

De onderliggende code is vrij eenvoudig. Wanneer de gebruiker de lettertypefamiliekiezer voor de eerste keer opent, controleert de applicatie eerst of de webbrowser de Local Font Access API ondersteunt.

Het controleert ook op de oude experimentele versie van de API en gebruikt deze indien aanwezig. Vanaf 2023 kun je de oude API veilig negeren, aangezien deze slechts korte tijd beschikbaar was via experimentele Chrome-vlaggen, maar sommige Chromium-derivaten deze mogelijk nog steeds gebruiken.

let isLocalFontsApiEnabled = (
  // Local Font Access API, Chrome >= 102
  window.queryLocalFonts !== undefined ||
  // Experimental Local Font Access API, Chrome < 102
  navigator.fonts?.query !== undefined
);

Als de Local Font Access API niet beschikbaar is, wordt de lettertypefamiliekiezer grijs. Er wordt een tijdelijke tekst voor de gebruiker weergegeven in plaats van de lijst met lettertypen:

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

Lettertypekiezer met de melding 'Uw browser ondersteunt de Local Font Access API niet'.

Anders wordt de Local Font Access API gebruikt om de lijst met alle lettertypen uit het besturingssysteem op te halen. Let op het try…catch blok dat nodig is om toestemmingsfouten correct af te handelen.

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

Zodra de lijst met lokale lettertypen is opgehaald, wordt er een vereenvoudigde en genormaliseerde fontsIndex van gemaakt:

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

De genormaliseerde lettertype-index wordt vervolgens opgeslagen in de IndexedDB-database, zodat deze eenvoudig kan worden opgevraagd, gedeeld tussen app-instanties en bewaard tussen sessies. Boxy SVG gebruikt Dexie.js om de database te beheren:

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

Chrome DevTools Storage-sectie met de IndexedDB-tabel met de lettertypecache.

Zodra de database is gevuld, kan de lettertypekiezer-widget deze opvragen en de resultaten op het scherm weergeven:

Lettertypekiezer gevuld met lettertypen.

Het is de moeite waard te vermelden dat Boxy SVG de lijst weergeeft in een aangepast element met de naam <bx-fontfamilypicker> en elk lettertypelijstitem zo opmaakt dat het in de specifieke lettertypefamilie wordt weergegeven. Om te isoleren van de rest van de pagina, gebruikt Boxy SVG de Shadow DOM in deze en andere aangepaste elementen.

Chrome DevTools Elements-paneel met de lettertypekiezer die wordt geïnspecteerd: een aangepast element met de naam 'bx-fontfamiliypicker'.

Conclusies

De functie voor lokale lettertypen is erg populair, waarbij gebruikers toegang hebben tot hun lokale lettertypen voor hun ontwerpen en creaties. Toen de API-vorm veranderde en de functie kortstondig kapot ging , merkten gebruikers dit onmiddellijk op. Jarosław veranderde de code snel in het defensieve patroon dat je in het bovenstaande fragment kunt zien en dat werkt met het up-to-date Chrome en ook met andere Chromium-derivaten die mogelijk niet naar de nieuwste versie zijn overgeschakeld. Probeer Boxy SVG eens uit en bekijk zeker uw lokaal geïnstalleerde lettertypen. Misschien ontdek je enkele lang vergeten klassiekers zoals Zapf Dingbats of Webdings .