Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här avsnittet beskriver OpenType-variabelteckensnitt, deras stöd i DirectWrite och Direct2D och hur du använder dem i din app.
- Vad är OpenType-variabelteckensnitt?
- stöd för OpenType-variabelteckensnitt i DirectWrite
- Använda OpenType-variabelteckensnitt
Vad är OpenType-variabelteckensnitt?
Version 1.8 av OpenType-teckensnittsformatspecifikationen introducerade ett nytt tillägg till formatet OpenType Font Variations. Teckensnitt som använder dessa tillägg kallas opentype-variabelteckensnitt. Ett OpenType-variabelteckensnitt är ett enda teckensnitt som kan fungera som flera teckensnitt med hjälp av kontinuerlig interpolering mellan olika design, som alla definieras i det enskilda teckensnittet.
Ett OpenType-variabelteckensnitt kan definiera kontinuerlig variation av dess design längs en eller flera oberoende axlar, till exempel vikt eller bredd:
En teckensnittsutvecklare bestämmer en uppsättning variantaxlar som ska användas i ett visst teckensnitt. Dessa axlar kan innehålla en uppsättning välkända (eller "registrerade") varianter, till exempel vikt och bredd, men de kan också innehålla godtyckliga anpassade varianter som definierats av teckensnittsutvecklaren.
Genom att välja en uppsättning variantaxlar för ett teckensnitt definierar teckensnittsutvecklaren ett abstrakt, n-dimensionellt utrymme med designvariant för teckensnittet. Textmotorer kan ange potentiellt valfri position, eller "instans", inom det kontinuerliga utrymmet för att lägga ut och återge text.
Teckensnittsutvecklaren kan också välja och tilldela namn till vissa instanser inom designvariantutrymmet. dessa kallas "namngivna instanser". Ett teckensnitt med viktvariant kan till exempel ha stöd för kontinuerlig variation mellan mycket lätta och mycket tunga linjer, medan teckensnittsutvecklaren har valt särskilda vikter längs det kontinuum och tilldelade namn till dem, till exempel "Ljus", "Regular" och "Semibold".
OpenType-variabelns teckensnittsformat använder datatabeller som finns i traditionella OpenType-teckensnitt plus vissa ytterligare tabeller som beskriver hur värdena för olika dataobjekt ändras för olika instanser. Formatet anger en variantinstans som en "standardinstans", som använder traditionella tabeller för att hämta standardvärden. Alla andra instanser är beroende av standarddata plus andra deltadata. Till exempel kan en "glyf"-tabell ha en Bezier-kurva beskrivning av en nominell glyphform, som är den form som används för standardinstansen, medan en "gvar"-tabell beskriver hur Bezier-kontrollpunkterna för glyfen justeras för andra instanser. På samma sätt kan andra teckensnittsvärden ha ett nominellt värde plus deltadata som beskriver hur dessa värden ändras för olika instanser. till exempel x-height och andra teckensnittsomfattande mått, eller glyph-specifika mark-anchoring-positioner och kerningsjusteringar.
Eftersom variabelteckensnitt kan stödja en godtycklig uppsättning variantaxlar kräver de en utökningsbar modell av teckensnittsfamiljer som mer direkt återspeglar hur teckensnittsdesigners skapar teckensnittsfamiljer: en teckensnittsfamilj definieras av ett efternamn och vissa designegenskaper som är konstanta, med ett godtyckligt tal (bestäms av teckensnittsutvecklaren) på sätt som designen kan variera på. En teckensnittsfamilj kan skapas med varianter för vikt, men en annan teckensnittsfamilj kan skapas med varianter för x-height, serif-size, "funkiness" eller vad teckensnittsutvecklaren vill. I den här modellen beskrivs ett val av teckensnittsigenkänning bäst med hjälp av det allmänna, eller "föredragna" eller "typografiska", familjenamnet plus en uppsättning nyckel/värde-par, som var och en representerar en typ av variant och specifikt värde, där de typer av variation i allmänhet är en utökningsbar uppsättning. Den här allmänna uppfattningen om en teckensnittsfamilj kan gälla för traditionella teckensnitt som inte är variabler samt för variabelteckensnitt. I den här allmänna typografiska familjemodellen kan till exempel en familj "Selawik VF" ha variationer för vikt, optisk storlek och serifdesign, med instanser som "Semilight Banner Sans".
Vissa befintliga programvaruimplementeringar, inklusive befintliga DirectWrite-API:er, kan dock utformas med en mer begränsad modell av teckensnittsfamiljer. Vissa program kan till exempel anta att en teckensnittsfamilj kan ha varianterna Regular, Bold, Italic och Bold Italic. Den befintliga IDWriteFontCollection och IDWriteFontFamily gränssnitt förutsätter en vikt/stretch/stil ("WSS") familjemodell, vilket gör det möjligt för varianter inom en familj att anges med hjälp av DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH eller DWRITE_FONT_STYLE uppräkningar som parametrar. I föregående exempel skulle den optiska storleken och serifaxlarna inte behandlas som familjeinterna axlar av variation i WSS-modellen.
Fullständigt stöd för variabelteckensnitt skulle kräva API:er som gör det möjligt för en familjemedlem att anges med potentiellt flera parametrar, vilket bestäms av teckensnittet. Men befintliga API-design kan ge partiellt stöd för variabelteckensnitt genom att projicera de namngivna instanser som definieras i ett variabelteckensnitt i de mer begränsade teckensnittsfamiljemodellerna. I föregående exempel kunde "Selawik VF Semilight Banner Sans" projiceras i WSS-modellen som en "Selawik VF Banner Sans"-familj med "Semilight" som en viktvariant.
Ett annat exempel kan vara en typografisk teckensnittsfamilj, till exempel Sitka, med varianter av vikt och optisk storlek. Namngivna varianter inom familjen inkluderar Sitka Text Regular och Sitka Banner Bold (plus många andra). Det typografiska familjenamnet är "Sitka" medan ansiktsnamnen för dessa varianter i den typografiska familjemodellen skulle vara "Text Regular" och "Banner Bold". Modellerna med fyra medlemmar och WSS-familjer tillåter inte optiska storleksvarianter inom en familj, och därför måste skillnader i optisk storlek behandlas som skillnader på familjenivå. I följande tabell visas hur ett urval av teckensnitt från sitkatypografiska familjen skulle behandlas i WSS-familjemodellen:
Typografisk familjemodell
WSS-familjemodell
Familj
Ansikte
Familj
Ansikte
Sitka
Vanlig text
Sitka-text
Ordinarie
Sitka
Banderoll, fet
Sitka-banderoll
Djärv
Sitka
Kursiv bildtext
Sitka-undertext
Kursiv
Projektionen av namn från en typografisk familjemodell till WSS-familjemodellen kan tillämpas på icke-variabelteckensnitt och på namngivna instanser av variabelteckensnitt. Detta kan dock inte göras för andra, icke-namngivna instanser från det kontinuerliga designvariantutrymmet för ett variabelteckensnitt. Därför krävs API:er som är utformade för att referera till ansikten i en typografisk familj när det gäller en obegränsad uppsättning variantaxlar och axelvärden för stöd för de fullständiga funktionerna i variabelteckensnitt.
Stöd för OpenType-variabelteckensnitt i DirectWrite
Från och med lanseringen av Windows 10 Creators Update är OpenType-variabelns teckensnittsformat fortfarande mycket nytt, och teckensnittsleverantörer, plattformar och appar håller fortfarande på att implementera det nya formatet. Den här uppdateringen ger inledande implementering för det här formatet i DirectWrite.
DirectWrite internals har uppdaterats för att stödja OpenType-variabelteckensnitt. Med hjälp av aktuella API:er ger detta stöd för namngivna instanser av ett variabelteckensnitt. Det här stödet kan användas för fullständiga arbetsflöden – från uppräkning av namngivna instanser, val av en namngiven instans, användning i layout och formning till rendering och utskrift. Till förmån för appar som också använder GDI-text interop för vissa åtgärder har liknande stöd också lagts till i befintliga GDI-API:er.
I Windows 10 Creators Update stöder DirectWrite inte godtyckliga instanser som använder funktionen för kontinuerlig variation av variabelteckensnitt.
I många åtgärder kan beteendet i DirectWrite för namngivna instanser av ett variabelteckensnitt inte skiljas från beteendet för icke-variabelteckensnitt. Och eftersom stöd ges med befintliga DirectWrite-API:er kan de namngivna instanserna av variabelteckensnitt till och med fungera i många befintliga DirectWrite-appar utan några ändringar. Undantag kan dock gälla i vissa situationer:
- Om en app bearbetar teckensnittsdata direkt för vissa åtgärder. Om en app till exempel läser teckendispositionsdata direkt från teckensnittsfilen för att skapa vissa visuella effekter.
- Om en app använder ett bibliotek från tredje part för vissa åtgärder. Om en app till exempel använder DirectWrite för layout, för att hämta slutgiltiga glyph-index och positioner, men sedan använder ett bibliotek från tredje part för återgivning.
- Om en app bäddar in teckensnittsdata i ett dokument eller på något annat sätt skickar teckensnittsdata till en nedströmsprocess.
Om åtgärder utförs med implementeringar som inte stöder variabelteckensnitt kanske dessa åtgärder inte ger det förväntade resultatet. Till exempel kan teckenpositioner beräknas för en namngiven instans av variabelteckensnittet, men glyferna kan återges förutsatt att en annan namngiven instans. Beroende på programimplementering kan resultaten fungera i vissa sammanhang, men inte i andra sammanhang där andra bibliotek kan användas. Text kan till exempel visas korrekt på skärmen, men inte när den skrivs ut. Om arbetsflöden från slutpunkt till slutpunkt implementeras med endast DirectWrite kan korrekt beteende för namngivna instanser av ett variabelteckensnitt förväntas.
Eftersom befintliga DirectWrite-API:er stöder ansiktsval med hjälp av modellen weight/stretch/style projiceras de namngivna instanserna av teckensnitt som använder andra varianter från den allmänna typografiska familjemodellen till WSS-modellen enligt beskrivningen ovan. Detta förlitar sig på ett variabelteckensnitt, inklusive en tabell med "formatattribut" ('STAT') med undertabeller för axelvärde, som DWrite använder för att skilja ansiktsnamnstoken som anger vikt-, stretch- eller formatattribut från token som gäller för andra varianter.
Om ett variabelteckensnitt inte innehåller en STAT-tabell, vilket krävs för variabelteckensnitt enligt OpenType-specifikationen, behandlar DirectWrite teckensnittet som ett icke-variabelt teckensnitt som endast innehåller standardinstansen.
Om ett teckensnitt innehåller en STAT-tabell men inte innehåller lämpliga undertabeller för axel/värde kan detta leda till oväntade resultat, till exempel att flera ansikten har identiska ansiktsnamn. Sådana teckensnitt stöds inte just nu.
OpenType-specifikationen gör att glyph-dispositionsdata kan representeras i ett av två format: med hjälp av en "glyf"-tabell, som använder TrueType-disposition och tipsformat, eller med hjälp av en CFF-tabell, som använder kompakt teckensnittsformat ("CFF") representation. I ett variabelteckensnitt med TrueType-konturer fortsätter tabellen "glyf" att användas och kompletteras med en "gvar"-tabell som tillhandahåller variantdata för dispositionerna. Det innebär att standardinstansen av ett variabelteckensnitt med TrueType-dispositioner endast använder traditionella OpenType-tabeller som stöds i äldre program som inte har stöd för variabelteckensnitt. I ett variabelteckensnitt med CFF-dispositioner ersätts dock CFF-tabellen av tabellen "CFF2", som kapslar in standarddispositionsdata och associerade variantdata i en tabell. CFF-data bearbetas av en separat rastrering från den som används för TrueType-data, och en CFF2-tabell kräver en uppdaterad CFF-rastrering som har CFF2-stöd. En CFF2-tabell kan inte bearbetas av äldre CFF-rastreringar. För ett variabelteckensnitt med CFF-dispositionsdata innebär det att inte ens standardinstansen fungerar i äldre programvara.
I Windows 10 Creators Update stöder DirectWrite inte variabelteckensnitt med CFF-dispositionsdata med hjälp av tabellen CFF2.
Använda OpenType-variabelteckensnitt
OpenType-variabelteckensnitt kan vara enkla att använda, med tanke på de aktuella begränsningarna som anges ovan:
- Endast namngivna instanser av ett variabelteckensnitt stöds just nu.
- Endast variabelteckensnitt som använder TrueType glyph-dispositionsdata (inte CFF-dispositioner) stöds just nu.
- För teckensnitt som använder axlar med andra designvarianter än vikt, stretch eller format projiceras namngivna instanser i WSS-familjemodellen, vilket kan leda till att vissa namngivna instanser visas som separata familjer (vilket tidigare skulle inträffa för icke-variabelteckensnitt). För att stödja detta måste variabelteckensnitt ha en STAT-tabell som innehåller lämpliga undertabeller för axel/värde.
- Namngivna instanser av variabelteckensnitt stöds i DirectWrite-API:er, men om vissa åtgärder utförs i äldre implementeringar som inte stöder variabelteckensnitt kan de ge felaktiga resultat.
- Vissa DirectWrite-API:er använder DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH och DWRITE_FONT_STYLE uppräkningar för att ange vikt-, stretch- och formatattribut när du väljer ansikten. Om ett variabelteckensnitt använder motsvarande variantaxlar men har många namngivna instanser som kräver finare kornighet kan inte alla namngivna instanser väljas i dessa API:er.
OpenType-variabelteckensnitt som uppfyller dessa krav kan installeras från Windows-gränssnittet precis som andra OpenType-teckensnitt och kan även användas i anpassade teckensnittsuppsättningar som skapats av en app.
När de installeras i systemet inkluderas alla namngivna instanser av ett variabelteckensnitt i teckensnittsuppsättningen som returneras genom att anropa metoden IDWriteFontFamily3::GetSystemFontSet-metoden. Observera att en teckensnittsuppsättning är en platt lista utan en hierarki för familjegruppering, men varje objekt i uppsättningen har en familjenamnsegenskap baserat på WSS-familjemodellen. Teckensnittsuppsättningen kan filtreras efter en viss instans med namnet variable-font med hjälp av metoderna IDWriteFontSet::GetMatchingFonts. Om du använder GetMatchingFonts överlagring som tar ett familyName, måste det angivna familyName dock använda namnet som överensstämmer med WSS-teckensnittsfamiljemodellen. Den fullständiga listan över WSS-kompatibla efternamn som förekommer i en teckensnittsuppsättning kan hämtas med hjälp av IDWriteFontSet::GetPropertyValues metoder med hjälp av DWRITE_FONT_PROPERTY_ID_FAMILY_NAME.
På samma sätt representeras alla namngivna instanser av ett variabelteckensnitt i teckensnittssamlingen som returneras av IDWriteFactory::GetSystemFontCollection-metoden. Eftersom elementen i en teckensnittssamling är teckensnittsfamiljer baserat på WSS-modellen kan de namngivna instanserna av ett variabelteckensnitt representeras i en samling som medlemmar i två eller flera teckensnittsfamiljer. Om metoden IDWriteFontCollection::FindFamilyName används måste parametern familyName vara ett WSS-kompatibelt familjenamn. För att hitta alla WSS-kompatibla familjenamn från en teckensnittssamling kan en app loopa igenom varje familj och anropa IDWriteFontFamily::GetFamilyNames, även om det kan vara lättare att hämta en motsvarande teckensnittsuppsättning och använda metoden GetPropertyValues enligt beskrivningen ovan.
När du arbetar med anpassade teckensnitt kan olika metoder som beskrivs i avsnittet anpassade teckensnittsuppsättningar användas för att skapa en teckensnittsuppsättning. Om du vill lägga till ett variabelteckensnitt i en anpassad teckensnittsuppsättning rekommenderas metoden IDWriteFontSetBuilder1::AddFontFile eftersom den stöder variabelteckensnitt och lägger till alla namngivna instanser av ett variabelteckensnitt i ett enda anrop. För närvarande går det inte att lägga till enskilda namngivna instanser av ett anpassat variabelteckensnitt i en teckensnittsuppsättning med hjälp av IDWriteFontSetBuilder::AddFontFaceReference metoder eftersom det inte finns något sätt att skapa en teckensnittsreferens som anger vilken av de namngivna instanserna från en variabel teckensnittsfil som är avsedd. Det innebär att det för närvarande inte finns något sätt att lägga till namngivna instanser av ett anpassat teckensnitt i en anpassad teckensnittsuppsättning med anpassade egenskaper tilldelade. Det innebär i sin tur att anpassade variabelteckensnitt för närvarande inte enkelt kan användas tillsammans med DirectWrite-API:er för fjärrteckensnitt. Om namngivna instanser av ett variabelteckensnitt ingår i en systemteckensnittsuppsättning finns det dock redan teckenigenkänningsreferenser för varje namngiven instans, och dessa kan läggas till i anpassade teckensnittsuppsättningar, inklusive med hjälp av anpassade egenskapsvärden. Mer information finns i avsnittet Anpassade teckensnittsuppsättningar.
När du arbetar med variabelteckensnitt är DirectWrite-DWRITE_FONT_WEIGHT och DWRITE_FONT_STRETCH uppräkningar nära kopplade till vikt- och breddvariantaxlarna som definierats i OpenType-specifikationen, men är inte desamma. För det första stöder den numeriska skalan för valfri variantaxel alltid bråkvärden, medan fontWeight och fontStretch använder heltal. Skalan för OpenType-viktaxeln använder värden från 1 till 1 000, vilket också stöds av fontWeight. Därför är ändringen från ett värde för variantviktaxeln till fontWeight relativt liten: fontWeight som rapporteras för en namngiven instans kan avrundas från det exakta värde som används för att definiera den namngivna instansen inom teckensnittet. Skillnaden mellan DirectWrite fontStretch och skalan för OpenType-breddaxeln är större: DirectWrite använder värden från 1 till 9, efter usWidthClass värden för OpenType OS/2-tabellen, medan OpenType-breddaxelskalan använder positiva värden som representerar en procentandel av normal bredd. Dokumentationen usWidthClass i OpenType-specifikationen innehåller en mappning mellan värdena 1 till 9 och procent av normalvärdena. FontStretch-värdet som rapporteras för en namngiven instans kan innebära avrundning när du konverterar från breddaxelvärden.
När du skapar en IDWriteTextFormatmåste en teckensnittssamling och WSS-kompatibla teckensnittsegenskaper (efternamn, vikt, stretch och stil) anges. Detta gäller även när du anger egenskaper för teckensnittsformatering på ett IDWriteTextLayout textintervall. Egenskaperna kan hämtas från ett IDWriteFontFace3--objekt eller från IDWriteFont och IDWriteFontFamily objekt som representerar en viss namngiven instans. Som observerats ovan kan de värden som returneras av metoderna GetWeight och GetStretch avrundas för de faktiska axelvärden som används för att definiera den namngivna instansen, men DirectWrite mappar kombinationen av egenskaper tillbaka till den önskade namngivna instansen.
Om en app använder IDWriteFontFallbackBuilder för att skapa anpassade återställningsdata för teckensnitt, anges familjer för teckenintervallmappningar med hjälp av WSS-kompatibla familjenamn. Återställning av teckensnitt i DirectWrite baseras på familjer med DirectWrite som väljer en variant inom en reservfamilj som är en närmaste matchning för varianten av startfamiljen. För varianter som omfattar andra dimensioner än vikt, stretch och stil skulle DirectWrite för närvarande inte kunna välja sådana varianter inom en reservfamilj om inte anpassade återställningsdata skapades specifikt för att tillhandahålla reservmappningar för familjer som har särskilda icke-WSS-attribut, till exempel "Bildtext" optiska storleksvarianter.