Tipi di carattere della variabile OpenType
Questo argomento descrive i tipi di carattere delle variabili OpenType, il supporto in DirectWrite e Direct2D e come usarli nell'app.
- Quali sono i tipi di carattere delle variabili OpenType?
- supporto dei tipi di carattere delle variabili OpenType in DirectWrite
- Uso di tipi di carattere variabili OpenType
Che cosa sono i tipi di carattere delle variabili OpenType?
La versione 1.8 della specifica del formato del carattere OpenType ha introdotto una nuova estensione per il formato noto come OpenType Font Variations. I tipi di carattere che usano queste estensioni sono noti come tipi di carattere variabili OpenType. Un tipo di carattere variabile OpenType è un singolo tipo di carattere che può comportarsi come diversi tipi di carattere usando l'interpolazione continua tra diverse progettazioni, tutte definite all'interno del singolo tipo di carattere.
Un tipo di carattere variabile OpenType può definire una variazione continua della progettazione lungo uno o più assi indipendenti, ad esempio peso o larghezza:
Uno sviluppatore di tipi di carattere determina un set di assi di variazione da utilizzare in un determinato tipo di carattere. Questi assi possono includere un set di assi noti (o "registrati") di variazione, ad esempio peso e larghezza, ma possono includere anche assi arbitrari e personalizzati di variazione definiti dallo sviluppatore di tipi di carattere.
Selezionando un set di assi di variazione per un tipo di carattere, lo sviluppatore di tipi di carattere definisce uno spazio astratto e ndimensionale della variante di progettazione per il tipo di carattere. I motori di testo possono specificare potenzialmente qualsiasi posizione, o "istanza", all'interno di tale spazio continuo per la disposizione e il rendering del testo.
Lo sviluppatore di tipi di carattere può anche selezionare e assegnare nomi a istanze particolari all'interno dello spazio di variazione della progettazione; questi vengono definiti "istanze denominate". Ad esempio, un tipo di carattere con variazione di spessore può supportare variazioni continue tra tratti molto leggeri e molto pesanti, mentre lo sviluppatore del tipo di carattere ha selezionato pesi particolari lungo tale continuum e assegna loro nomi, ad esempio "Light", "Regular" e "Semibold".
Il formato del tipo di carattere della variabile OpenType usa tabelle di dati presenti nei tipi di carattere OpenType tradizionali e alcune tabelle aggiuntive che descrivono come cambiano i valori di vari elementi di dati per istanze diverse. Il formato definisce un'istanza di variante come "istanza predefinita", che usa le tabelle tradizionali per ottenere i valori predefiniti. Tutte le altre istanze dipendono dai dati predefiniti e da altri dati differenziali. Ad esempio, una tabella "glyf" può avere una descrizione della curva di Bézier di una forma di glifo nominale, ovvero la forma utilizzata per l'istanza predefinita, mentre una tabella "gvar" descrive come i punti di controllo di Bezier per il glifo vengono modificati per altre istanze. Analogamente, altri valori dei tipi di carattere possono avere un valore nominale più dati differenziali che descrivono come tali valori cambiano per istanze diverse; ad esempio, altezza x e altre metriche a livello di carattere o posizioni di ancoraggio del contrassegno specifiche del glifo e regolazioni della crenatura.
Poiché i tipi di carattere variabile possono supportare un set arbitrario di assi di varianti, richiedono un modello estendibile di famiglie di caratteri che riflettono più direttamente il modo in cui i progettisti di tipi di carattere creano famiglie di tipi di carattere: una famiglia di caratteri è definita da un nome di famiglia e determinate caratteristiche di progettazione costanti, con un numero arbitrario (determinato dallo sviluppatore di tipi di carattere) di modi in cui la progettazione può variare. È possibile creare una famiglia di caratteri con varianti per il peso, ma è possibile creare una famiglia di caratteri diversa con varianti per x-height, serif-size, "funkiness" o qualsiasi cosa lo sviluppatore del tipo di carattere desideri. In questo modello, una selezione del tipo di carattere è descritta meglio usando il nome generale o "preferito" o "tipografico", il nome della famiglia più un set di coppie chiave-valore, ognuna che rappresenta un tipo di variazione e un valore specifico, con i tipi di variazione in generale essendo un set estendibile. Questa nozione generale di una famiglia di caratteri può essere applicata ai tipi di carattere tradizionali, non variabili e ai tipi di carattere variabili. Ad esempio, in questo modello generale di famiglia tipografica, una famiglia "Selawik VF" potrebbe avere variazioni per peso, dimensioni ottiche e design serif, con istanze come "Sans banner semilight".
Alcune implementazioni software esistenti, tuttavia, incluse le API DirectWrite esistenti, possono essere progettate presupponendo un modello più limitato di famiglie di caratteri. Ad esempio, alcune applicazioni possono presupporre che una famiglia di caratteri possa avere al massimo varianti Regular, Bold, Italic e Bold Italic. Le interfacce IDWriteFontCollection e IDWriteFontFamily presuppongono un modello di famiglia weight/stretch/style ("WSS"), consentendo di specificare varianti all'interno di una famiglia usando le enumerazioni DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH o DWRITE_FONT_STYLE come parametri. Prendendo l'esempio precedente, le dimensioni ottiche e gli assi serif non vengono considerati assi interni della famiglia di variazioni nel modello WSS.
Il supporto completo per i tipi di carattere delle variabili richiede api che consentono di specificare un membro della famiglia con potenzialmente diversi parametri, come determinato dal tipo di carattere. Tuttavia, le progettazioni API esistenti possono essere in grado di fornire supporto parziale per i tipi di carattere variabili proiettando le istanze denominate definite in un tipo di carattere variabile nei modelli della famiglia di caratteri più limitati. Nell'esempio precedente, "Selawik VF Semilight Banner Sans" potrebbe essere proiettato nel modello WSS come famiglia "Selawik VF Banner Sans" con "Semilight" come variante di peso.
Per un altro esempio, si consideri una famiglia di caratteri tipografici come Sitka, con varianti di peso e dimensioni ottiche. Le varianti denominate all'interno della famiglia includono Sitka Text Regular e Sitka Banner Bold (più molti altri). Il nome della famiglia tipografica è "Sitka", mentre i nomi dei visi per queste varianti nel modello di famiglia tipografica sarebbero "Text Regular" e "Banner Bold". I modelli di famiglia di quattro membri e WSS non consentono varianti di dimensioni ottiche all'interno di una famiglia, quindi le distinzioni delle dimensioni ottiche devono essere trattate come distinzioni a livello di famiglia. Nella tabella seguente viene illustrato come una selezione di tipi di carattere della famiglia tipografica Sitka verrebbe trattata nel modello di famiglia WSS:
Modello di famiglia tipografico
Modello di famiglia WSS
Famiglia
Faccia
Famiglia
Faccia
Sitka
Testo normale
Testo Sitka
Regolare
Sitka
Banner in grassetto
Sitka Banner
Audace
Sitka
Corsivo didascalia
Sitka Caption
Corsivo
La proiezione di nomi da un modello di famiglia tipografica al modello di famiglia WSS può essere applicata ai tipi di carattere non variabili e alle istanze denominate dei tipi di carattere variabili. Questa operazione non può essere eseguita, tuttavia, per altre istanze non denominate dallo spazio di variazione di progettazione continua di un tipo di carattere variabile. Per questo motivo, il supporto per la funzionalità completa dei tipi di carattere delle variabili richiederà API progettate per fare riferimento ai visi all'interno di una famiglia tipografica in termini di un set non vincolato di assi di variazione e valori dell'asse.
Supporto dei tipi di carattere delle variabili OpenType in DirectWrite
A partire dal rilascio di Windows 10 Creators Update, il formato del tipo di carattere della variabile OpenType è ancora molto nuovo e i fornitori di tipi di carattere, le piattaforme e le app sono ancora in fase di implementazione del nuovo formato. Questo aggiornamento fornisce l'implementazione iniziale per questo formato in DirectWrite.
Gli elementi interni di DirectWrite sono stati aggiornati per supportare i tipi di carattere delle variabili OpenType. Usando le API correnti, questo fornisce il supporto per qualsiasi istanza denominata di un tipo di carattere variabile. Questo supporto può essere usato per flussi di lavoro completi, dall'enumerazione delle istanze denominate, dalla selezione di un'istanza denominata, dall'uso nel layout e nel data shaping, al rendering e alla stampa. Per il vantaggio delle app che usano anche l'interoperabilità del testo GDI per determinate operazioni, è stato aggiunto anche un supporto simile nelle API GDI esistenti.
In Windows 10 Creators Update DirectWrite non supporta istanze arbitrarie che utilizzano la funzionalità di variazione continua dei tipi di carattere variabili.
In molte operazioni, il comportamento in DirectWrite di istanze denominate di un tipo di carattere variabile non può essere distinto dal comportamento dei tipi di carattere non variabili. Poiché il supporto viene fornito usando le API DirectWrite esistenti, le istanze denominate dei tipi di carattere delle variabili possono funzionare anche in molte app DirectWrite esistenti senza modifiche. Le eccezioni possono tuttavia essere applicate in determinate situazioni:
- Se un'app elabora i dati dei tipi di carattere direttamente per determinate operazioni. Ad esempio, se un'app legge i dati della struttura del glifo direttamente dal file di tipo di carattere per creare determinati effetti visivi.
- Se un'app usa una libreria di terze parti per determinate operazioni. Ad esempio, se un'app usa DirectWrite per il layout, per ottenere indici e posizioni finali del glifo, ma usa una libreria di terze parti per il rendering.
- Se un'app incorpora i dati dei tipi di carattere in un documento o in un altro modo passa i dati del tipo di carattere a un processo downstream.
Se le operazioni vengono eseguite usando implementazioni che non supportano tipi di carattere variabili, queste operazioni potrebbero non produrre i risultati previsti. Ad esempio, le posizioni del glifo potrebbero essere calcolate per un'istanza denominata del tipo di carattere della variabile, ma è possibile che venga eseguito il rendering dei glifi presupponendo un'istanza denominata diversa. A seconda dell'implementazione dell'applicazione, i risultati possono funzionare in alcuni contesti, ma non in altri contesti in cui è possibile usare altre librerie. Ad esempio, il testo potrebbe essere visualizzato correttamente sullo schermo, ma non quando viene stampato. Se i flussi di lavoro end-to-end vengono implementati usando solo DirectWrite, è possibile prevedere un comportamento corretto per le istanze denominate di un tipo di carattere variabile.
Poiché le API DirectWrite esistenti supportano la selezione dei visi usando il modello di spessore/estensione/stile, le istanze denominate di tipi di carattere che usano altri assi di variazione verranno proiettate dal modello generale della famiglia tipografica nel modello WSS, come descritto in precedenza. Ciò si basa su un tipo di carattere variabile che include una tabella "attributi di stile" ('STAT') con sottotable asse-valore, che DWrite usa per distinguere i token dei nomi del viso che designano attributi di peso, estensione o stile dai token che riguardano altri assi di variazione.
Se un tipo di carattere variabile non include una tabella 'STAT', come richiesto per i tipi di carattere variabili dalla specifica OpenType, DirectWrite considererà il tipo di carattere come un tipo di carattere non variabile contenente solo l'istanza predefinita.
Se un tipo di carattere contiene una tabella "STAT", ma non include tabelle secondarie appropriate per valori dell'asse, ciò può causare risultati imprevisti, ad esempio avere più visi con nomi di visi identici. Tali tipi di carattere non sono attualmente supportati.
La specifica OpenType consente di rappresentare i dati della struttura del glifo in uno dei due formati seguenti: usando una tabella "glyf", che usa il formato di struttura e hint di TrueType oppure una tabella "CFF", che usa una rappresentazione CFF (Compact Font Format ("CFF"). In un tipo di carattere variabile con struttura TrueType, la tabella 'glyf' continua a essere utilizzata e viene integrata con una tabella 'gvar' che fornisce i dati di variante per i contorni. Ciò significa che l'istanza predefinita di un tipo di carattere variabile con contorni TrueType usa solo le tabelle OpenType tradizionali che saranno supportate nel software precedente senza supporto di tipi di carattere variabili. In un tipo di carattere variabile con struttura CFF, tuttavia, la tabella 'CFF' viene sostituita dalla tabella 'CFF2', che incapsula i dati struttura predefiniti e i dati di variazione associati in una tabella. I dati CFF vengono elaborati da un rasterizzatore separato da quello usato per i dati TrueType e una tabella 'CFF2' richiede un rasterizzatore CFF aggiornato con supporto 'CFF2'. Una tabella 'CFF2' non può essere elaborata da rasterizzatori CFF meno recenti. Per un tipo di carattere variabile con dati struttura CFF, ciò significa che anche l'istanza predefinita non funzionerà nel software precedente.
In Windows 10 Creators Update DirectWrite non supporta i tipi di carattere variabili con i dati della struttura CFF usando la tabella 'CFF2'.
Uso dei tipi di carattere delle variabili OpenType
I tipi di carattere delle variabili OpenType possono essere facili da usare, tenendo presente le limitazioni correnti indicate in precedenza:
- Attualmente sono supportate solo le istanze denominate di un tipo di carattere variabile.
- Attualmente sono supportati solo i tipi di carattere variabili che usano i dati di struttura del glifo TrueType (non le strutture CFF).
- Per i tipi di carattere che usano assi di variazione di progettazione diversi da peso, estensione o stile, le istanze denominate verranno proiettate nel modello di famiglia WSS, il che può comportare la visualizzazione di alcune istanze denominate come famiglie separate (come accade nel passato per i tipi di carattere non variabili). Per supportare questo problema, i tipi di carattere delle variabili devono avere una tabella 'STAT' che include le tabelle secondarie appropriate per i valori dell'asse.
- Le istanze denominate dei tipi di carattere delle variabili sono supportate nelle API DirectWrite, ma se alcune operazioni vengono eseguite in implementazioni meno recenti che non supportano tipi di carattere variabili, tali tipi di carattere potrebbero produrre risultati non corretti.
- Alcune API DirectWrite usano le enumerazioni DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH e DWRITE_FONT_STYLE per specificare attributi di spessore, estensione e stile durante la selezione dei visi. Se un tipo di carattere variabile usa gli assi di variazione corrispondenti ma ha molte istanze denominate che richiedono una granularità più fine, non tutte le istanze denominate saranno selezionabili in tali API.
I tipi di carattere delle variabili OpenType conformi a questi requisiti possono essere installati dalla shell di Windows esattamente come altri tipi di carattere OpenType e possono essere usati anche in set di tipi di carattere personalizzati creati da un'app.
Quando viene installato nel sistema, tutte le istanze denominate di un tipo di carattere variabile verranno incluse nel set di tipi di carattere restituito chiamando il metodo IDWriteFontFamily3::GetSystemFontSet. Si noti che un set di caratteri è un elenco semplice senza una gerarchia di raggruppamento di famiglie, ma ogni elemento nel set ha una proprietà family-name basata sul modello di famiglia WSS. Il set di tipi di carattere può essere filtrato per una particolare istanza denominata di tipo variabile usando i metodi IDWriteFontSet::GetMatchingFonts. Se si usa il GetMatchingFonts overload che accetta un familyName, tuttavia, il nome specificato deve usare il nome conforme al modello della famiglia di caratteri WSS. È possibile ottenere l'elenco completo dei nomi di famiglia compatibili con WSS in un set di caratteri usando i metodi IDWriteFontSet::GetPropertyValues usando DWRITE_FONT_PROPERTY_ID_FAMILY_NAME.
Analogamente, tutte le istanze denominate di un tipo di carattere variabile verranno rappresentate nella raccolta di tipi di carattere restituita dal metodo IDWriteFactory::GetSystemFontCollection. Poiché gli elementi di una raccolta di caratteri sono famiglie di tipi di carattere basati sul modello WSS, le istanze denominate di un tipo di carattere variabile possono essere rappresentate in una raccolta come membri di due o più famiglie di caratteri. Se viene utilizzato il metodo IDWriteFontCollection::FindFamilyName, il parametro familyName deve essere un nome di famiglia compatibile con WSS. Per trovare tutti i nomi di famiglia compatibili con WSS da una raccolta di tipi di carattere, un'app può scorrere in ciclo ogni famiglia e chiamare IDWriteFontFamily::GetFamilyNames, anche se può essere più semplice ottenere un set di tipi di carattere corrispondente e usare il metodo GetPropertyValues come descritto in precedenza.
Quando si usano tipi di carattere personalizzati, è possibile usare vari approcci descritti nell'argomento set di caratteri personalizzati per creare un set di tipi di carattere. Per aggiungere un tipo di carattere variabile a un set di caratteri personalizzato, è consigliabile usare il metodo IDWriteFontSetBuilder1::AddFontFile poiché supporta tipi di carattere variabili e aggiungerà tutte le istanze denominate di un tipo di carattere di una variabile in una singola chiamata. Al momento non è possibile aggiungere singole istanze denominate di un tipo di carattere di una variabile personalizzata a un set di tipi di carattere usando il IDWriteFontSetBuilder::AddFontFaceReference metodi poiché non è possibile creare un riferimento al viso del tipo di carattere specificando quale delle istanze denominate di un file di tipo di carattere variabile è previsto. Ciò significa che attualmente non è possibile aggiungere istanze denominate di un tipo di carattere personalizzato a un set di caratteri personalizzato con proprietà personalizzate assegnate. Ciò a sua volta significa che i tipi di carattere variabili personalizzati non possono essere usati facilmente insieme alle API DirectWrite per i tipi di carattere remoti. Se le istanze denominate di un tipo di carattere variabile sono incluse in un set di tipi di carattere di sistema, tuttavia, i riferimenti ai visi dei caratteri per ogni istanza denominata esisteranno già e possono essere aggiunti a set di tipi di carattere personalizzati, incluso l'uso dei valori delle proprietà personalizzate. Per altri dettagli, vedere l'argomento Set di caratteri personalizzati.
Quando si utilizzano tipi di carattere variabili, le enumerazioni DirectWrite DWRITE_FONT_WEIGHT e DWRITE_FONT_STRETCH sono strettamente connesse agli assi di variazione di spessore e spessore definiti nella specifica OpenType, ma non sono uguali. Prima di tutto, la scala numerica per qualsiasi asse delle varianti supporta sempre i valori frazionari, mentre fontWeight e fontStretch usano numeri interi. La scala dell'asse dei pesi OpenType usa valori compresi tra 1 e 1000, supportati anche da fontWeight. Di conseguenza, la modifica da un valore dell'asse di ponderazione di variazione a fontWeight è relativamente minore: il fontWeight segnalato per un'istanza denominata può essere arrotondato dal valore preciso usato per definire l'istanza denominata all'interno del tipo di carattere. La distinzione tra il tipo di carattere DirectWriteStretch e la scala dell'asse di larghezza OpenType è maggiore: DirectWrite usa valori compresi tra 1 e 9, seguendo i valori usWidthClass della tabella OpenType OS/2, mentre la scala dell'asse della larghezza OpenType usa valori positivi che rappresentano una percentuale di larghezza normale. La documentazione usWidthClass nella specifica OpenType fornisce un mapping tra i valori da 1 a 9 e percentuale dei valori normali. Il valore fontStretch segnalato per un'istanza denominata può comportare l'arrotondamento durante la conversione da valori dell'asse di larghezza.
Quando si crea un IDWriteTextFormat, è necessario specificare una raccolta di caratteri e proprietà dei tipi di carattere compatibili con WSS (nome della famiglia, spessore, estensione e stile). Questo vale anche quando si impostano le proprietà di formattazione del carattere in un IDWriteTextLayout intervallo di testo. Le proprietà possono essere ottenute da un oggetto IDWriteFontFace3 o da IDWriteFont e oggetti IDWriteFontFamily che rappresentano una particolare istanza denominata. Come osservato in precedenza, i valori restituiti dai metodi GetWeight e GetStretch possono essere approssimazioni arrotondate per i valori effettivi dell'asse usati per definire l'istanza denominata, ma DirectWrite eseguirà il mapping della combinazione di proprietà all'istanza denominata desiderata.
Analogamente, se un'app usa IDWriteFontFallbackBuilder per creare dati di fallback dei tipi di carattere personalizzati, le famiglie vengono specificate per i mapping di intervalli di caratteri usando nomi di famiglia compatibili con WSS. Il fallback dei tipi di carattere all'interno di DirectWrite si basa sulle famiglie con DirectWrite che seleziona una variante all'interno di una famiglia di fallback che rappresenta una corrispondenza più vicina per la variante della famiglia iniziale. Per le varianti che prevedono dimensioni diverse da peso, estensione e stile, DirectWrite attualmente non sarà in grado di selezionare tali varianti all'interno di una famiglia di fallback a meno che non siano stati creati dati di fallback personalizzati specificamente per fornire mapping di fallback per le famiglie con attributi non WSS specifici, ad esempio varianti di dimensioni ottiche "Caption".