Usare la tipografia avanzata con i caratteri locali

Scopri come l'API Local Font Access ti permette di accedere ai caratteri installati localmente e ottenere dettagli di basso livello sugli stessi

Caratteri sicuri per il web

Se stai svolgendo attività di sviluppo web abbastanza a lungo, potresti ricordare il cosiddetto caratteri sicuri per il web. Questi caratteri sono noti per essere disponibili in quasi tutte le istanze dei sistemi operativi più utilizzati (ovvero Windows, macOS, le distribuzioni Linux più comuni, Android e iOS). All'inizio degli anni 2000, Microsoft ha anche lanciato una iniziativa chiamati caratteri principali TrueType per il Web che fornivano questi caratteri per il download senza costi con obiettivo che "ogni volta che visiti un sito web che li specifica, vedrai le pagine esattamente come dal designer del sito". Sì, questi siti inclusi sono impostati in Comic Sans MS. Ecco un stack classico di caratteri sicuri sul web (con il fallback definitivo di qualsiasi sans-serif: potrebbe avere il seguente aspetto:

body {
  font-family: Helvetica, Arial, sans-serif;
}

Caratteri web

Sono finiti i tempi in cui i caratteri sicuri per il web contavano davvero. Oggi abbiamo caratteri web, alcuni dei quali sono persino caratteri variabili che possiamo perfezionare ulteriormente modificando i valori dei valori da vari assi esposti. Puoi utilizzare i caratteri web dichiarando un Blocco @font-face all'inizio del CSS, che specifica i file dei caratteri da scaricare:

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: url('flamboyant.woff2');
}

Dopodiché, puoi utilizzare il carattere web personalizzato specificando la font-family, come di consueto:

body {
  font-family: 'FlamboyantSansSerif';
}

Caratteri locali come vettore di impronta

Gran parte dei caratteri web proviene, beh, dal web. Un fatto interessante, però, è che Proprietà src in @font-face dichiarazione separata, a parte url() , accetta anche una funzione local() personalizzata. In questo modo è possibile caricare localmente i caratteri personalizzati. Se l'utente ha FlamboyantSansSerif installato sul sistema operativo, verrà utilizzata la copia locale al posto di in fase di download:

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}

Questo approccio fornisce un buon meccanismo di riserva che potenzialmente risparmia larghezza di banda. Su internet, sfortunatamente non possiamo avere cose belle. Il problema con la funzione local() è che può essere utilizzati in modo illecito per il fingerprinting del browser. In questo caso, l'elenco di caratteri installati dall'utente può essere molto identificare. Molte aziende hanno i propri caratteri aziendali installati sui laptop. Ad esempio, Google ha un carattere aziendale chiamato Google Sans.

L'app macOS Font Book che mostra un'anteprima del carattere Google Sans.
. Carattere Google Sans installato sul laptop di un dipendente Google.

Un aggressore può cercare di determinare per quale azienda lavora qualcuno testando l’esistenza di un un gran numero di caratteri aziendali noti, come Google Sans. L'aggressore tenterà di eseguire il rendering del testo impostato in questi caratteri su una tela e misurare i glifi. Se i glifi corrispondono alla forma nota aziendale, l'aggressore ha subito un attacco. Se i glifi non corrispondono, l'aggressore sa che una È stato utilizzato un carattere sostitutivo predefinito perché il carattere aziendale non era installato. Per i dettagli completi questo e altri attacchi di fingerprinting del browser, leggi le sondaggio di Laperdix et al.

A parte i caratteri aziendali, anche solo l'elenco di caratteri installati può essere identificato. La situazione con questo vettore di attacco è diventato talmente grave che di recente il team WebKit deciso per "includere solo caratteri web e caratteri [in elenco disponibili] che vengono forniti con il ma non quelli installati localmente dall'utente". Eccomi qui, con un articolo sulla concessione dell'accesso ai caratteri locali).

API Local Font Access

L'inizio di questo articolo potrebbe averti messo in cattiva umore. Non possiamo davvero avere cose? No. Riteniamo di poter e forse non è tutto senza speranza. Innanzitutto, permettimi di rispondere a una domanda che potresti chiederti.

Perché è necessaria l'API Local Font Access in presenza di caratteri web?

Gli strumenti grafici e di progettazione di qualità professionale sono storicamente difficili da offrire sul sul web. Un ostacolo è stata l'incapacità di accedere e utilizzare l'intera varietà di strumenti i caratteri creati e suggeriti che i designer hanno installato localmente. I caratteri web consentono alcune pubblicazioni ma non consentono l'accesso programmatico alle forme di glifo vettoriali e alle tabelle di caratteri utilizzate rasterizzatori per eseguire il rendering dei contorni dei glifi. Allo stesso modo, non è possibile accedere al file binario di un carattere web e i dati di Google Cloud.

  • Gli strumenti di progettazione devono accedere ai byte del carattere per eseguire la propria implementazione del layout OpenType e consentire progettare strumenti da agganciare ai livelli inferiori per azioni come l'esecuzione di filtri vettoriali o trasforma le forme delle forme dei glifo.
  • Gli sviluppatori potrebbero disporre di stack di caratteri legacy per le loro applicazioni che stanno introducendo sul web. Per utilizzarle, di solito richiedono l'accesso diretto ai dati dei caratteri, cosa che i caratteri web non devono che forniscono.
  • Alcuni caratteri potrebbero non essere concessi in licenza per la pubblicazione sul web. Ad esempio, Linotype ha una licenza per alcuni caratteri solo per l'uso su computer.

L'API Local Font Access è un tentativo di risolvere queste sfide. Si compone di due parti:

  • Un'API font enumeration, che consente agli utenti di concedere l'accesso all'insieme completo dei sistemi disponibili i caratteri.
  • Da ogni risultato di enumerazione, la possibilità di richiedere un container SFNT di basso livello (orientato ai byte) che include i dati completi sui caratteri.

Supporto browser

Supporto dei browser

  • Chrome: 103.
  • Edge: 103.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

Come utilizzare l'API Local Font Access

Rilevamento delle caratteristiche

Per verificare se l'API Local Font Access è supportata, utilizza:

if ('queryLocalFonts' in window) {
  // The Local Font Access API is supported
}

Enumerazione dei caratteri locali

Per ottenere un elenco dei caratteri installati localmente, devi chiamare window.queryLocalFonts(). La la prima volta, verrà attivata una richiesta di autorizzazione che l'utente può approvare o rifiutare. Se l'utente approva i loro caratteri locali da interrogare, il browser restituirà un array con i dati dei caratteri che puoi riprodurre in loop. Ogni carattere è rappresentato come un oggetto FontData con le proprietà family (ad es. "Comic Sans MS"), fullName (ad es. "Comic Sans MS"), postscriptName (ad esempio, "ComicSansMS") e style (ad esempio, "Regular").

// Query for all available fonts and log metadata.
try {
  const availableFonts = await window.queryLocalFonts();
  for (const fontData of availableFonts) {
    console.log(fontData.postscriptName);
    console.log(fontData.fullName);
    console.log(fontData.family);
    console.log(fontData.style);
  }
} catch (err) {
  console.error(err.name, err.message);
}

Se ti interessa solo un sottoinsieme di caratteri, puoi anche filtrarli in base al modello PostScript aggiungendo un parametro postscriptNames.

const availableFonts = await window.queryLocalFonts({
  postscriptNames: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});

Accesso ai dati SFNT

L'accesso completo a SFNT è disponibile tramite il metodo blob() della FontData oggetto. SFNT è un formato di file font che può contenere altri caratteri, come PostScript, Caratteri TrueType, OpenType, Web Open Font Format (WOFF) e altri.

try {
  const availableFonts = await window.queryLocalFonts({
    postscriptNames: ['ComicSansMS'],
  });
  for (const fontData of availableFonts) {
    // `blob()` returns a Blob containing valid and complete
    // SFNT-wrapped font data.
    const sfnt = await fontData.blob();
    // Slice out only the bytes we need: the first 4 bytes are the SFNT
    // version info.
    // Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
    const sfntVersion = await sfnt.slice(0, 4).text();

    let outlineFormat = 'UNKNOWN';
    switch (sfntVersion) {
      case '\x00\x01\x00\x00':
      case 'true':
      case 'typ1':
        outlineFormat = 'truetype';
        break;
      case 'OTTO':
        outlineFormat = 'cff';
        break;
    }
    console.log('Outline format:', outlineFormat);
  }
} catch (err) {
  console.error(err.name, err.message);
}

Demo

Puoi vedere l'API Local Font Access in azione nel demo qui sotto. Consulta anche codice sorgente. La demo mostra un elemento personalizzato chiamato <font-select> che implementa un selettore di caratteri locale.

Considerazioni sulla privacy

Sembra che l'autorizzazione "local-fonts" fornisca una superficie facilmente identificabile. Tuttavia, i browser sono liberi di restituire qualsiasi cosa vogliano. Ad esempio, i browser incentrati sull'anonimato potrebbero scegliere di fornire solo un insieme di caratteri predefiniti integrati nel browser. Analogamente, i browser non sono obbligatori per fornire i dati della tabella esattamente come appaiono sul disco.

Ove possibile, l'API Local Font Access è progettata solo per esporre esattamente le informazioni necessari per abilitare i casi d'uso menzionati. Le API di sistema possono produrre un elenco di caratteri installati non casuale o ordinato, ma nell'ordine di installazione dei caratteri. Restituire esattamente l'elenco i caratteri installati forniti da un'API di sistema di questo tipo possono esporre altri dati utilizzabili per: il fingerprinting e i casi d'uso che vogliamo abilitare non vengono assistiti dal mantenere questo ordine. Come questa API richiede che i dati restituiti vengano ordinati prima di essere restituiti.

Sicurezza e autorizzazioni

Il team di Chrome ha progettato e implementato l'API Local Font Access sulla base dei principi fondamentali definita in Controllo dell'accesso a funzionalità avanzate della piattaforma web, tra cui le controllo, trasparenza ed ergonomia.

Controllo utenti

L'accesso ai caratteri di un utente è completamente sotto il suo controllo e non sarà consentito a meno che il "local-fonts", come elencato nell' registro autorizzazioni.

Trasparenza

Se a un sito è stato concesso l'accesso ai caratteri locali dell'utente sarà visibile nel scheda informativa del sito.

Persistenza dell'autorizzazione

L'autorizzazione "local-fonts" verrà mantenuto tra un caricamento e l'altro della pagina. Può essere revocato tramite foglio informativo del sito.

Feedback

Il team di Chrome vuole conoscere la tua esperienza con l'API Local Font Access.

Parlaci della progettazione dell'API

C'è qualcosa nell'API che non funziona come previsto? Oppure mancano metodi o le proprietà necessarie per implementare la tua idea? Hai una domanda o un commento sulla sicurezza modello? Segnala un problema relativo alle specifiche sul repository GitHub corrispondente o aggiungi le tue opinioni a un problema esistente.

Segnalare un problema con l'implementazione

Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione è diversa dalle specifiche? Segnala un bug all'indirizzo new.crbug.com. Includi il maggior numero di dettagli possibile, semplici istruzioni per la riproduzione e inserisci Blink>Storage>FontAccess nella casella Componenti. Glitch è la soluzione perfetta per condividere riproduzioni in modo facile e veloce.

Mostra il supporto per l'API

Intendi utilizzare l'API Local Font Access? Il tuo supporto pubblico aiuta il team di Chrome a dare la priorità alle funzionalità e indica agli altri fornitori di browser quanto sia fondamentale supportarli.

Invia un tweet a @ChromiumDev utilizzando l'hashtag #LocalFontAccess e lascia sapere dove e come lo utilizzi.

Ringraziamenti

La specifica dell'API Local Font Access è stata modificata da Emil A. Eklund Alex Russell Joshua Bell e Olivier Yiptong. Questo articolo è stato esaminato da Mario Rossi Dominik Röttsches e Olivier Yiptong. Immagine hero di Brett Jordan su Rimuovi schermo.