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 gebruikmaakt van deze API.

Invoering

(Dit artikel is ook beschikbaar als video.)

Boxy SVG is een vectorafbeeldingseditor. De belangrijkste toepassing is het bewerken van tekeningen in SVG-formaat, 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 in de ideeëntracker van de app.

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

API voor lokale lettertypetoegang in Boxy SVG

Een van de nieuwe functies waarover Jarosław blogde, was de Local Font Access API . Met de Local Font Access API krijgen 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 ziet u hoe ik de app toegang heb gegeven tot de lokaal geïnstalleerde lettertypen op mijn MacBook en het lettertype Marker Felt heb gekozen voor mijn tekst.

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

De onderliggende code is vrij eenvoudig. Wanneer de gebruiker de lettertypekiezer voor het eerst 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 gerust negeren, aangezien deze slechts korte tijd beschikbaar was via experimentele Chrome-vlaggen, maar sommige Chromium-derivaten gebruiken deze mogelijk nog steeds.

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 lettertypekiezer grijs. In plaats van de lettertypelijst wordt een tijdelijke tekst aan de gebruiker getoond:

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

De lettertypekiezer toont het bericht 'Uw browser ondersteunt de Local Font Access API niet'.

Anders wordt de Local Font Access API gebruikt om de lijst met alle lettertypen van 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);

Het gedeelte Opslag in Chrome DevTools toont de IndexedDB-tabel met de lettertypecache.

Zodra de database is gevuld, kan de widget voor het selecteren van lettertypen deze raadplegen en de resultaten op het scherm weergeven:

Lettertypekiezer gevuld met lettertypen.

Het is belangrijk om te vermelden dat Boxy SVG de lijst weergeeft in een aangepast element met de naam <bx-fontfamilypicker> en elk item in de lettertypelijst zo stylet dat het in de specifieke lettertypefamilie wordt weergegeven. Om de pagina van elkaar te isoleren, gebruikt Boxy SVG de Shadow DOM in dit en andere aangepaste elementen.

Het elementenpaneel van Chrome DevTools toont de lettertypekiezer die wordt geïnspecteerd: een aangepast element met de naam 'bx-fontfamiliypicker'.

Conclusies

De functie voor lokale lettertypen is erg populair en gebruikers genieten van toegang tot hun lokale lettertypen voor hun ontwerpen en creaties. Toen de API-vorm veranderde en de functie kortstondig niet werkte , merkten gebruikers dit meteen op. Jarosław paste de code snel aan naar het defensieve patroon dat je in het bovenstaande fragment kunt zien en dat werkt met de nieuwste versie van Chrome en ook met andere afgeleide versies van Chromium die mogelijk nog niet zijn overgestapt naar de nieuwste versie. Probeer Boxy SVG eens uit en controleer zeker je lokaal geïnstalleerde lettertypen. Misschien ontdek je wel lang vergeten klassiekers zoals Zapf Dingbats of Webdings .