Dela via


Anpassade teckensnittsuppsättningar

I det här avsnittet beskrivs olika sätt att använda anpassade teckensnitt i din app.

Införandet

För det mesta använder appar de teckensnitt som installeras lokalt i systemet. DirectWrite ger åtkomst till dessa teckensnitt med hjälp av IDWriteFactory3::GetSystemFontSet eller IDWriteFactory::GetSystemFontCollection metoder. I vissa fall kanske appar också vill använda teckensnitt som ingår som en del av Windows 10, men som för närvarande inte är installerade i det aktuella systemet. Sådana teckensnitt kan nås från Windows-teckensnittstjänsten med hjälp av metoden GetSystemFontSet eller genom att anropa IDWriteFactory3::GetSystemFontCollection med includeDownloadableFonts inställt på TRUE. 

I vissa programscenarier måste appar dock använda teckensnitt som inte är installerade i systemet och som inte tillhandahålls av Windows Font Service. Följande är exempel på sådana scenarier:

  • Teckensnitt bäddas in som resurser i en binär app.
  • Teckensnittsfiler paketeras i ett apppaket och lagras på disk under appens installationsmapp.
  • Appen är ett teckensnittsutvecklingsverktyg som måste läsa in användardefinierade teckensnittsfiler. 
  • Teckensnitt är inbäddade i dokumentfiler som kan visas eller redigeras i appen. 
  • Appen använder teckensnitt som hämtats från en offentlig webbteckensnittstjänst. 
  • Appen använder teckensnittsdata som strömmas via ett protokoll för privat nätverk. 

DirectWrite tillhandahåller API:er för att arbeta med anpassade teckensnitt i dessa och andra liknande scenarier. Anpassade teckensnittsdata kan komma från filer i det lokala filsystemet. från fjärranslutna, molnbaserade källor som nås via HTTP; eller från godtyckliga källor efter att ha lästs in i en minnesbuffert. 

Not

Även om DirectWrite har tillhandahållit API:er för att arbeta med anpassade teckensnitt sedan Windows 7, lades nyare API:er till i Windows 10 och igen i Windows 10 Creators Update (förhandsversion 15021 eller senare) som gör det enklare att implementera flera av de scenarier som nämns. Det här avsnittet fokuserar på API:er som är tillgängliga i Fönster 10. Program som behöver arbeta med tidigare Windows-versioner finns i Anpassade teckensnittssamlingar (Windows 7/8)

 

Sammanfattning av API:er

Det här avsnittet fokuserar på funktioner som tillhandahålls av följande API:er:

 

Viktiga begrepp

För att förstå DirectWrite-API:er för att arbeta med anpassade teckensnitt kan det vara bra att förstå den konceptuella modell som ligger till grund för dessa API:er. Viktiga begrepp beskrivs här. 

När DirectWrite utför faktisk textlayout eller rendering måste den komma åt faktiska teckensnittsdata. Ett teckensnittsobjekt innehåller faktiska teckensnittsdata, som måste finnas i det lokala systemet. Men för andra åtgärder, till exempel att kontrollera tillgängligheten för ett visst teckensnitt eller presentera teckensnittsalternativ för en användare, är allt som behövs en referens till ett visst teckensnitt, inte själva teckensnittsdata. I DirectWrite innehåller ett ansiktsreferensobjekt för teckensnitt bara den information som behövs för att hitta och instansiera ett teckensnitt. Eftersom ansiktsreferensen för teckensnitt inte innehåller faktiska data kan DirectWrite hantera ansiktsreferenser för teckensnitt där faktiska data finns på en fjärrnätverksplats samt när faktiska data är lokala.

En teckensnittsuppsättning är en uppsättning teckenigenkänningsreferenser, tillsammans med vissa grundläggande, informationsegenskaper som kan användas för att referera till teckensnittet eller för att jämföra det med andra teckensnitt, till exempel familjenamnet eller ett teckensnittsviktvärde. De faktiska data för de olika teckensnitten kan vara lokala, eller så kan allt vara fjärranslutet eller någon blandning.

En teckensnittsuppsättning kan användas för att hämta ett motsvarande teckensnittssamlingsobjekt. Mer information finns i Teckensnittsuppsättningar och teckensnittssamlingar nedan. 

Gränssnittet IDWriteFontSet innehåller metoder som tillåter frågor om egenskapsvärden som familjenamn eller teckensnittsvikt, eller för teckenigenkänningsreferenser som matchar specifika egenskapsvärden. När du har filtrerat ned till en viss markering kan du hämta en instans av IDWriteFontFaceReference-gränssnittet med metoder för nedladdning (om de faktiska teckensnittsdata för närvarande är fjärranslutna) för att hämta motsvarande IDWriteFontFace3 objekt som kan användas för layout och återgivning. 

Gränssnittet IDWriteFontFile ligger till grund för varje ansiktsigenkänning eller teckensnittsreferens. Detta representerar platsen för en teckensnittsfil och har två komponenter: en teckensnittsfilinläsare och en teckensnittsfilnyckel. Teckensnittsfilinläsaren (IDWriteFontFileLoader) används för att öppna en fil om det behövs och returnerar en dataström (IDWriteFontFileStream). Beroende på inläsaren kan data finnas på en lokal filsökväg, en fjärr-URL eller i en minnesbuffert. Nyckeln är ett inläsningsdefinierat värde som unikt identifierar filen i inläsningskontexten, vilket gör att inläsaren kan hitta data och skapa en ström för den. 

Anpassade teckensnitt kan enkelt läggas till i en anpassad teckensnittsuppsättning, som i sin tur kan användas för att filtrera eller organisera teckensnittsinformation för ändamål som att skapa ett användargränssnitt för teckensnittsväljaren. Teckensnittsuppsättningen kan också användas för att skapa en teckensnittssamling för användning i API:er på högre nivå som IDWriteTextFormat och IDWriteTextLayout. Gränssnittet IDWriteFontSetBuilder kan användas för att skapa en anpassad teckensnittsuppsättning som innehåller flera anpassade teckensnitt. Den kan också användas för att skapa en anpassad teckensnittsuppsättning som blandar anpassade teckensnitt och systembaserade teckensnitt. eller som blandar teckensnitt med olika källor för faktiska data – lokal lagring, fjärr-URL:er och minne. 

Som nämnts kan en teckenigenkänningsreferens referera till teckensnittsdata i en fjärrkälla, men data måste vara lokala för att kunna hämta ett teckensnittsobjekt som kan användas för layout och återgivning. Nedladdning av fjärrdata hanteras av en kö för teckensnittsnedladdning. Appar kan använda IDWriteFontDownloadQueue-gränssnittet för att skicka begäranden om att ladda ned fjärrteckensnitt för att initiera nedladdningsprocessen och registrera en IDWriteFontDownloadListener objekt för att vidta åtgärder när nedladdningsprocessen har slutförts. 

För de flesta av de gränssnitt som beskrivs här tillhandahåller DirectWrite systemimplementeringar. Det enda undantaget är gränssnittet IDWriteFontDownloadListener, som en app implementerar för att vidta appspecifika åtgärder när fjärrteckensnitt har laddats ned lokalt. Appar kan ha anledning att tillhandahålla egna anpassade implementeringar för vissa andra gränssnitt, men det skulle bara behövas i specifika, mer avancerade scenarier. En app skulle till exempel behöva tillhandahålla en anpassad implementering av IDWriteFontFileLoader- gränssnitt för att hantera teckensnittsfiler i lokal lagring som använder WOFF2-containerformatet. Ytterligare information finns nedan. 

Teckensnitt och teckensnittsfilformat

Ett annat viktigt begrepp som är användbart för att förstå är relationen mellan enskilda teckensnittsytor och teckensnittsfiler som innehåller dem. Tanken på en OpenType-teckensnittsfil (.ttf eller .otf) som innehåller ett enda teckensnitt är bekant. Men OpenType-teckensnittsformatet tillåter också en OpenType-teckensnittssamling (.ttc eller .otc), som är en enda fil som innehåller flera teckensnitt. OpenType-samlingsfiler används ofta för stora teckensnitt som är nära besläktade och har identiska värden för vissa teckensnittsdata: genom att kombinera teckensnitten i en enda fil kan de gemensamma data de dupliceras. Därför måste en ansiktsreferens för teckensnitt eller teckensnitt referera inte bara till en teckensnittsfil (eller motsvarande datakälla), utan också ange ett teckensnittsindex i filen, för det allmänna fallet där filen kan vara en samlingsfil. 

För teckensnitt som används på webben packas teckensnittsdata ofta i vissa containerformat, WOFF eller WOFF2, vilket ger viss komprimering av teckensnittsdata och viss skyddsnivå mot piratkopiering och brott mot teckensnittslicenser. Funktionellt motsvarar en WOFF- eller WOFF2-fil ett OpenType-teckensnitt eller en teckensnittssamlingsfil, men data kodas i ett annat format som kräver uppackning innan de kan användas. 

Vissa DirectWrite-API:er kan hantera enskilda teckensnittsytor, medan andra API:er kan hantera filer som kan innehålla OpenType-samlingsfiler som innehåller flera ansikten. På samma sätt hanterar vissa API:er endast rådata i OpenType-format, medan andra API:er kan hantera paketerade containerformat, WOFF- och WOFF2-containerformat. Den här informationen finns i diskussionen nedan. 

Teckensnittsuppsättningar och teckensnittssamlingar

Vissa program kan implementeras för att fungera med teckensnitt med hjälp av gränssnittet IDWriteFontCollection. Det finns en direkt korrespondens mellan en teckensnittssamling och en teckensnittsuppsättning. Var och en kan innehålla samma teckensnitt, men de presenterar dem med en annan organisation. Från valfri teckensnittssamling kan du hämta en motsvarande teckensnittsuppsättning och vice versa.

När du arbetar med ett antal anpassade teckensnitt är det enklast att använda ett builder-gränssnitt för teckensnittsuppsättningar för att skapa en anpassad teckensnittsuppsättning och sedan hämta en teckensnittssamling när teckensnittsuppsättningen har skapats. Processen för att skapa en anpassad teckensnittsuppsättning beskrivs i detalj nedan. För att hämta ett IDWriteFontCollection1--gränssnitt från en teckensnittsuppsättning används metoden IDWriteFactory3::CreateFontCollectionFromFontSet.

Om appen har ett samlingsobjekt och behöver hämta en motsvarande teckensnittsuppsättning kan detta göras med hjälp av metoden IDWriteFontCollection1::GetFontSet

Vanliga scenarier

I det här avsnittet beskrivs några av de vanligaste scenarierna med anpassade teckensnittsuppsättningar:

  • Skapa en anpassad teckensnittsuppsättning med godtyckliga teckensnitt på sökvägar i det lokala filsystemet.
  • Skapa en anpassad teckensnittsuppsättning med kända teckensnitt (kanske paketerade med appen) som lagras i det lokala filsystemet.
  • Skapa en anpassad teckensnittsuppsättning med kända fjärrteckensnitt på webben.
  • Skapa en anpassad teckensnittsuppsättning med teckensnittsdata som läses in i minnet.

Fullständiga implementeringar för dessa scenarier finns i exemplet DirectWrite Custom Font Sets. Det exemplet illustrerar också ett mer avancerat scenario för hantering av teckensnittsdata som är packade i WOFF- eller WOFF2-containerformat, vilket beskrivs nedan. 

Skapa en teckensnittsuppsättning med godtyckliga teckensnitt i det lokala filsystemet

När du hanterar en godtycklig uppsättning teckensnittsfiler i lokal lagring är IDWriteFontSetBuilder1::AddFontFile metod bekväm eftersom den i ett enda anrop kan hantera alla teckensnittsansikten i en OpenType-teckensnittssamlingsfil samt alla instanser för ett OpenType-variabelteckensnitt. Detta är tillgängligt i Windows 10 Creators Update (förhandsversion 15021 eller senare) och rekommenderas när det är tillgängligt. 

Använd följande process om du vill använda den här metoden.

1. Börja med att skapa gränssnittet IDWriteFactory5:
IDWriteFactory5* pDWriteFactory; 
HRESULT hr = DWriteCreateFactory( 
  DWRITE_FACTORY_TYPE_SHARED, 
  __uuidof(IDWriteFactory5), 
  reinterpret_cast<IUnknown**>(&pDWriteFactory) 
); 

 
2. Använd fabriken för att hämta IDWriteFontSetBuilder1 gränssnitt:

IDWriteFontSetBuilder1* pFontSetBuilder; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder); 
}  
                
  1. För varje teckensnittsfil i det lokala filsystemet skapar du en IDWriteFontFile- som refererar till den:
IDWriteFontFile* pFontFile; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile); 
} 

 
4. Lägg till objektet IDWriteFontFile i teckensnittsuppsättningsverktyget med hjälp av metoden AddFontFile:

hr = pFontSetBuilder->AddFontFile(pFontFile); 

Om filsökvägen som anges i anropet till CreateFontFileReference hänvisat till något annat än en OpenType-fil som stöds, returnerar anropet till AddFontFile ett fel, DWRITE_E_FILEFORMAT.

  1. När alla filer har lagts till i teckensnittsuppsättningsverktyget kan du skapa den anpassade teckensnittsuppsättningen:
IDWriteFontSet* pFontSet; 
hr = pFontSetBuilder->CreateFontSet(&pFontSet); 

 

Om appen behöver köras på Windows 10-versioner tidigare än Windows 10 Creators Update är metoden AddFontFile inte tillgänglig. Tillgänglighet kan identifieras genom att skapa ett IDWriteFactory3--gränssnitt och sedan använda QueryInterface för att försöka hämta ett IDWriteFactory5--gränssnitt: om detta lyckas kommer IDWriteFontSetBuilder1-gränssnittet och AddFontFile-metoden också att vara tillgänglig.

Om metoden AddFontFile inte är tillgänglig måste metoden IDWriteFontSetBuilder::AddFontFaceReference användas för att lägga till enskilda teckensnittsansikten. Om du vill tillåta opentype-teckensnittssamlingsfiler som innehåller flera ansikten kan metoden IDWriteFontFile::Analyze användas för att fastställa antalet ansikten i filen. Processen är följande.

1. Börja med att skapa gränssnittet IDWriteFactory3:
IDWriteFactory3* pDWriteFactory; 
HRESULT hr = DWriteCreateFactory( 
DWRITE_FACTORY_TYPE_SHARED, 
  __uuidof(IDWriteFactory5), 
  reinterpret_cast<IUnknown**>(&pDWriteFactory) 
); 
  1. Använd fabriken för att hämta gränssnittet IDWriteFontSetBuilder:
IDWriteFontSetBuilder* pFontSetBuilder; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder); 
} 
  1. För varje teckensnittsfil skapar du en IDWriteFontFile, enligt ovan:
IDWriteFontFile* pFontFile; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile); 
} 

I stället för att lägga till filen direkt i teckensnittsuppsättningsverktyget måste vi fastställa antalet ansikten och skapa enskilda IDWriteFontFaceReference objekt. 
4. Använd metoden Analysera för att hämta antalet ansikten i filen. 

BOOL isSupported; 
DWRITE_FONT_FILE_TYPE fileType; 
UINT32 numberOfFonts; 
hr = pFontFile->Analyze(&isSupported, &fileType, /* face type */ nullptr, &numberOfFonts); 

Metoden Analyze anger också värden för parametrarna isSupported och fileType. Om filen inte är ett format som stöds kommer isSupported att vara FALSE, och lämpliga åtgärder, till exempel att ignorera filen, kan vidtas. 
5. Loopa över antalet teckensnitt som anges i parametern numberOfFonts. I loopen skapar du en IDWriteFontFaceReference- för varje fil-/indexpar och lägger till den i teckensnittsuppsättningsverktyget. 

for (uint32_t fontIndex = 0; fontIndex < numberOfFonts; fontIndex++) 
{ 
  IDWriteFontFaceReference* pFontFaceReference;
  hr = pDWriteFactory->CreateFontFaceReference(pFontFile, fontIndex, DWRITE_FONT_SIMULATIONS_NONE, &pFontFaceReference);

  if (SUCCEEDED(hr))
  {
    hr = pFontSetBuilder->AddFontFaceReference(pFontFaceReference);
  }
} 
  1. När alla ansikten har lagts till i teckensnittsuppsättningsverktyget skapar du den anpassade teckensnittsuppsättningen enligt ovan.

En app kan utformas så att den använder önskad AddFontFile--metod när den körs på Windows 10 Creators Update, men återgår till att använda metoden AddFontFaceReference när den körs på tidigare Windows 10-versioner. Testa tillgängligheten för IDWriteFactory5-gränssnittet enligt beskrivningen ovan och förgrena sedan därefter. Den här metoden visas i exempelexemplet DirectWrite Custom Font Sets

Skapa en teckensnittsuppsättning med kända teckensnitt i det lokala filsystemet

Som nämnts ovan associeras varje teckenigenkänningsreferens i en teckensnittsuppsättning med vissa informationsegenskaper, till exempel familjenamn och teckenvikt. När anpassade teckensnitt läggs till i en teckensnittsuppsättningsbyggare med hjälp av API-anropen ovan hämtas dessa informationsegenskaper direkt från de faktiska teckensnittsdata som läses när teckensnittet läggs till. I vissa situationer kan det dock vara bra att ange egna anpassade värden för dessa egenskaper om en app har en annan informationskälla om ett teckensnitt. 

Ett exempel på hur detta kan vara användbart är att anta att en app paketar några teckensnitt som används för att presentera vissa användargränssnittselement i appen. Ibland, till exempel med en ny appversion, kan de specifika teckensnitt som appen använder för dessa element behöva ändras. Om appen har kodade referenser till de specifika teckensnitten kräver ersättning av ett teckensnitt med ett annat att var och en av dessa referenser ändras. Om appen i stället använder anpassade egenskaper för att tilldela funktionella alias baserat på vilken typ av element eller text som återges mappar varje alias till ett visst teckensnitt på ett ställe och sedan använder aliasen i alla kontexter där teckensnitt skapas och manipuleras. Om du ersätter ett teckensnitt med ett annat måste du bara ändra den plats där aliaset mappas till ett visst teckensnitt. 

Anpassade värden för informationsegenskaper kan tilldelas när metoden IDWriteFontSetBuilder::AddFontFaceReference anropas. Metoden för att göra detta är följande; Detta kan användas på valfri Windows 10-version. 

Som du ser ovan börjar du med att hämta IDWriteFactory3 och IDWriteFontSet-gränssnitt. För varje anpassat teckensnittsansikte som ska läggas till skapar du en IDWriteFontFaceReference, enligt ovan. Innan detta läggs till i teckensnittsuppsättningsverktyget (i loopen i steg 5, som visas ovan), definierar appen dock de anpassade egenskapsvärden som ska användas. 

En uppsättning anpassade egenskapsvärden definieras med hjälp av en matris med DWRITE_FONT_PROPERTY strukturer. Var och en av dessa identifierar en viss egenskap från DWRITE_FONT_PROPERTY_ID uppräkning och motsvarande egenskapsvärde som ska användas.  

Observera att alla egenskapsvärden tilldelas som strängar. Om dessa senare kan visas för användare kan alternativa värden för en viss egenskap för olika språk anges, men detta krävs inte. Observera också att om några anpassade egenskapsvärden anges av appen används endast de angivna värdena i teckensnittsuppsättningen. DirectWrite härleder inga värden direkt från teckensnittet för informationsegenskaper som används i en teckensnittsuppsättning. 

I följande exempel definieras anpassade värden för tre informationsegenskaper: familjenamn, fullständigt namn och teckenvikt. 

DWRITE_FONT_PROPERTY props[] = 
{ 
  { DWRITE_FONT_PROPERTY_ID_FAMILY_NAME, L"My Icon Font", L"en-US" }, 
  { DWRITE_FONT_PROPERTY_ID_FULL_NAME, L"My Icon Font", L"en-US" }, 
  { DWRITE_FONT_PROPERTY_ID_WEIGHT, L"400", nullptr } 
}; 
               
            

När du har definierat den önskade matrisen med egenskapsvärden för ett teckensnitt gör du ett anrop till AddFontFaceRefence och skickar egenskapsmatrisen samt teckensnittets ansiktsreferens. 

hr = pFontSetBuilder->AddFontFaceReference(pFontFaceReference, props, ARRAYSIZE(props)); 

 

När alla anpassade teckensnittsytor har lagts till i teckensnittsuppsättningsverktyget, tillsammans med deras anpassade egenskaper, skapar du den anpassade teckensnittsuppsättningen, som du ser ovan. 

Skapa en anpassad teckensnittsuppsättning med kända fjärrteckensnitt på webben

Anpassade egenskaper är viktiga för att arbeta med fjärrteckensnitt. Varje ansiktsreferens för teckensnitt måste ha vissa informationsegenskaper för att karakterisera teckensnittet och skilja det från andra teckensnitt. Eftersom teckensnittsdata för fjärrteckensnitt inte är lokala kan DirectWrite inte härleda egenskaper direkt från teckensnittsdata. Därför måste egenskaper anges uttryckligen när du lägger till ett fjärrteckensnitt i teckensnittsuppsättningsverktyget.

Sekvensen med API-anrop för att lägga till fjärrteckensnitt i en teckensnittsuppsättning liknar sekvensen som beskrevs för föregående scenario. Eftersom teckensnittsdata är fjärranslutna kommer de åtgärder som krävs för att läsa de faktiska teckensnittsdata att skilja sig från när du arbetar med filer i lokal lagring. I det här fallet har ett nytt gränssnitt på lägre nivå, IDWriteRemoteFontFileLoader, lagts till i Windows 10 Creators Update. 

Om du vill använda filinläsaren för fjärrteckensnitt måste den först registreras med en DirectWrite-fabrik. Inläsaren måste lagras av appen så länge som de teckensnitt som är associerade med den används. När teckensnitten inte längre används, och någon gång innan fabriken förstörs, måste lastaren avregistreras. Detta kan göras i destruktatorn för klassen som äger inläsningsobjektet. De här stegen visas nedan. 

Metoden för att skapa en anpassad teckensnittsuppsättning med hjälp av fjärrteckensnitt är följande. Detta kräver Windows 10 Creators Update.  

1. Skapa ett IDWriteFactory5-gränssnitt enligt ovan.  2. Skapa ett IDWriteFontSetBuilder- gränssnitt, som du ser ovan.  3. Använd fabriken för att hämta en IDWriteRemoteFontFileLoader
IDWriteRemoteFontFileLoader* pRemoteFontFileLoader; 
if (SUCCEEDED(hr)) 
{ 
    hr = pDWriteFactory->CreateHttpFontFileLoader( 
        /* referrerURL */ nullptr, 
        /* extraHeaders */ nullptr, 
        &pRemoteFontFileLoader 
    ); 
} 

Detta returnerar en systemimplementering av fjärrgränssnittet för teckensnittsfilinläsning som kan hantera HTTP-interaktioner för att ladda ned teckensnittsdata för appens räkning. En referens-URL eller extra rubriker kan anges om det krävs av teckensnittstjänsten eller tjänsterna som är källan för teckensnitten.  

Viktig

Säkerhetsmeddelande: När ett försök görs att hämta ett fjärrteckensnitt finns det risk för att en angripare förfalskar den avsedda servern som anropas. I så fall skulle mål- och referens-URL:er och rubrikinformation lämnas ut till angriparen. Apputvecklare ansvarar för att minska den här risken. Användning av HTTPS-protokollet i stället för HTTP rekommenderas. 

 

En enda filinläsare för fjärrteckensnitt kan användas för flera teckensnitt, men olika inläsare kan användas om teckensnitt hämtas från flera tjänster som har olika krav för referens-URL eller extra rubriker. 
4. Registrera den fjärranslutna teckensnittsfilinläsaren i fabriken. 

 if (SUCCEEDED(hr)) 
 { 
     hr = pDWriteFactory->RegisterFontFileLoader(pRemoteFontFileLoader); 
 } 

Från och med nu liknar stegen för att skapa den anpassade teckensnittsuppsättningen de som beskrivs för kända, lokala teckensnittsfiler, med två viktiga undantag. Först skapas objektet IDWriteFontFile med fjärrgränssnittet för teckensnittsfil i stället för att använda fabriken. För det andra går det inte att använda metoden Analysera eftersom teckensnittsdata inte är lokala. I stället måste appen veta om fjärrteckensnittsfilen är en OpenType-teckensnittssamlingsfil, och i så fall måste den veta vilka av teckensnitten i samlingen den ska använda och indexet för var och en. Därför är de återstående stegen följande. 
5. För varje fjärrteckensnittsfil använder du fjärrgränssnittet för teckensnittsfilen för att skapa en IDWriteFontFileoch anger den URL som krävs för att komma åt teckensnittsfilen. 

 IDWriteFontFile* pFontFile; 
 hr = pRemoteFontFileLoader->CreateFontFileReferenceFromUrl( 
     pDWriteFactory, 
     /* baseUrl */ L"https://github.com/", 
     /* fontFileUrl */ L"winjs/winjs/blob/master/src/fonts/Symbols.ttf?raw=true", 
     &pFontFile 
 ); 

Observera att den fullständiga URL:en kan anges i parametern fontFileUrl eller delas upp i bas- och relativa delar. Om en bas-URL har angetts måste sammanfogningen av värdena baseUrl och fontFileUrl ange den fullständiga URL:en – DirectWrite anger ingen ytterligare avgränsare.

Viktig

Säkerhets-/prestandaanteckning: När ett försök görs att hämta ett fjärrteckensnitt finns det ingen garanti för att Windows får ett svar från servern. I vissa fall kan en server svara med ett filfel som inte hittades för en ogiltig relativ URL, men sluta svara om den tar emot flera ogiltiga begäranden. Om servern inte svarar överskrider Windows tidsgränsen, men det kan ta flera minuter om flera hämtningar initieras. Du bör göra vad du kan för att se till att URL:er är giltiga när anrop görs. 

 

Observera också att URL:en kan peka på en rå OpenType-teckensnittsfil (.ttf, .otf, .ttc, .otc), men den kan också peka på teckensnitt i en WOFF- eller WOFF2-containerfil. Om en WOFF- eller WOFF2-fil refereras kommer DirectWrite-implementeringen av filinläsaren för fjärrteckensnitt automatiskt att packa upp teckensnittsdata från containerfilen. 
6. Skapa en IDWriteFontFaceReferenceför varje teckensnittsindex i den fjärranslutna teckensnittsfilen som ska användas. 

 IDWriteFontFaceReference* pFontFaceReference; 
 hr = pDWriteFactory->CreateFontFaceReference(pFontFile, /* faceIndex */ 0, DWRITE_FONT_SIMULATIONS_NONE, &pFontFaceReference);
  1. Definiera anpassade egenskaper för teckensnittets ansikte enligt ovan. 
  2. Lägg till ansiktsreferensen för teckensnitt tillsammans med anpassade egenskaper i teckensnittsuppsättningsverktyget, som du ser ovan. 
  3. När alla teckensnitt har lagts till i teckensnittsuppsättningsverktyget skapar du teckensnittsuppsättningen enligt ovan. 
  4. När fjärrteckensnitten inte längre används avregistrerar du filinläsaren för fjärrteckensnitt. 
hr = pDWriteFactory->UnregisterFontFileLoader(pRemoteFontFileLoader); 

När en anpassad teckensnittsuppsättning med anpassade fjärrteckensnitt har skapats innehåller teckensnittsuppsättningen referenser och informationsegenskaper för fjärrteckensnitten, men de faktiska data är fortfarande fjärranslutna. DirectWrite-stöd för fjärrteckensnitt gör att en teckensnittsreferens kan behållas i teckensnittsuppsättningen och för att ett teckensnitt ska väljas för användning i layout och rendering, men att faktiska data inte laddas ned förrän det finns ett faktiskt behov av att använda det, till exempel när textlayouten ska utföras.  

En app kan använda en klientmetod genom att begära att DirectWrite laddar ned teckensnittsdata och sedan väntar på bekräftelse av en lyckad nedladdning innan någon bearbetning med teckensnittet påbörjas. Men en nätverksnedladdning innebär en viss fördröjning av oförutsägbar varaktighet, och framgång är också osäkert. Av den anledningen är det vanligtvis bättre att använda en annan metod, så att layout och rendering kan göras från början med alternativa teckensnitt eller återställningsteckensnitt som redan är lokala, samtidigt som du begär nedladdning av önskat fjärrteckensnitt parallellt och sedan uppdaterar resultatet när det önskade teckensnittet har laddats ned. 

Om du vill begära att hela teckensnittet laddas ned innan det används kan metoden IDWriteFontFaceReference::EnqueueFontDownloadRequest användas. Om teckensnittet är mycket stort kan endast en del av data behövas för bearbetning av vissa strängar. DirectWrite innehåller ytterligare metoder som kan användas för att begära delar av teckensnittsdata som behövs för visst innehåll, EnqueueCharacterDownloadRequest och EnqueueGlyphDownloadRequest.  

Anta att metoden som ska användas i appen är att tillåta bearbetning till att börja med med lokala teckensnitt, alternativa teckensnitt eller återställningsteckensnitt. Metoden IDWriteFontFallback::MapCharacters kan användas för att identifiera lokala återställningsteckensnitt, och den skickar också automatiskt en begäran om att ladda ned det önskade teckensnittet. Om IDWriteTextLayout- används och en del av eller all text i layouten formateras med hjälp av en fjärrteckensnittsreferens, använder DirectWrite automatiskt metoden MapCharacters för att hämta lokala återställningsteckensnitt och för att skicka en begäran om att ladda ned fjärrteckensnittsdata. 

DirectWrite underhåller en kö för nedladdning av teckensnitt för varje fabrik och begäranden som görs med hjälp av metoderna ovan läggs till i kön. Du kan hämta teckensnittsnedladdningskön med hjälp av metoden IDWriteFactory3::GetFontDownloadQueue

Om en nedladdningsbegäran görs men teckensnittsdata redan är lokala resulterar detta i en no-op: Ingenting läggs till i nedladdningskön. En app kan kontrollera om kön är tom eller om det finns väntande nedladdningsbegäranden genom att anropa metoden IDWriteFontDownloadQueue::IsEmpty

När fjärranslutna teckensnittsbegäranden har lagts till i kön måste nedladdningsprocessen initieras. När fjärrteckensnitt används i IDWriteTextLayoutinitieras nedladdningen automatiskt när appen anropar IDWriteTextLayout metoder som framtvingar layout- eller återgivningsåtgärder, till exempel GetLineMetrics- eller Draw-metoderna. I andra scenarier måste appen initiera nedladdningen direkt genom att anropa IDWriteFontDownloadQueue::BeginDownload.  

När en nedladdning har slutförts är det upp till appen att vidta lämpliga åtgärder – fortsätta med väntande åtgärder eller upprepa åtgärder som utfördes inledningsvis med återställningsteckensnitt. (Om DirectWrite textlayout används kan IDWriteTextLayout3::InvalidateLayout användas för att rensa de tillfälliga resultat som beräknas med hjälp av återställningsteckensnitt.) För att appen ska kunna meddelas när nedladdningsprocessen har slutförts och vidta lämpliga åtgärder måste appen tillhandahålla en implementering av IDWriteFontDownloadListener--gränssnittet och skicka detta till BeginDownload-anropet. 

Viktig

Säkerhets-/prestandaanteckning: När ett försök görs att hämta ett fjärrteckensnitt finns det ingen garanti för att Windows får ett svar från servern. Om servern inte svarar överskrider Windows tidsgränsen, men det kan ta flera minuter om flera fjärrteckensnitt hämtas men misslyckas. BeginDownload-anropet returneras omedelbart. Appar bör inte blockera användargränssnittet i väntan på att IDWriteFontDownloadListener::D ownloadCompleted anropas. 

 

Exempelimplementeringar av dessa interaktioner med DirectWrite teckensnittsnedladdningskö och av IDWriteFontDownloadListener-gränssnittet kan visas i DirectWrite Custom Font Sets-exempel, och även i exemplet DirectWrite Downloadable Fonts

Skapa en anpassad teckensnittsuppsättning med teckensnittsdata som läses in i minnet

Precis som lågnivååtgärderna för att läsa data från en teckensnittsfil skiljer sig åt för filer på en lokal disk jämfört med fjärrfiler på webben, gäller samma sak även för teckensnittsdata som läses in i en minnesbuffert. Ett nytt lågnivågränssnitt för hantering av minnesintern teckensnittsdata har lagts till i Windows 10 Creators Update, IDWriteInMemoryFontFileLoader

Precis som med en fjärrteckensnittsfilinläsare måste en inläsare av minnesintern teckensnittsfil först registreras med en DirectWrite-fabrik. Inläsaren måste lagras av appen så länge som de teckensnitt som är associerade med den används. När teckensnitten inte längre används, och någon gång innan fabriken förstörs, måste lastaren avregistreras. Detta kan göras i destruktatorn för klassen som äger inläsningsobjektet. De här stegen visas nedan. 

Om appen har separat information om teckensnittsytor som representeras av data kan den lägga till individuella teckenigenkänningsreferenser till en teckensnittsuppsättningsbyggare med anpassade egenskaper angivna. Eftersom teckensnittsdata finns i det lokala minnet krävs det dock inte. DirectWrite kan läsa data direkt för att härleda egenskapsvärdena. 

DirectWrite förutsätter att teckensnittsdata är i raw-format, OpenType-format, motsvarande en OpenType-fil (.ttf, .otf, .ttc, .otc), men i minnet i stället för på disk. Data kan inte vara i ett WOFF- eller WOFF2-containerformat. Data kan representera en OpenType-teckensnittssamling. Om anpassade egenskaper inte används kan metoden IDWriteFontSetBuilder1::AddFontFile användas för att lägga till alla teckensnittsansikten i data i ett enda anrop. 

Ett viktigt övervägande för det minnesinterna scenariot är datans livslängd. Om en pekare till bufferten tillhandahålls till DirectWrite utan en tydlig indikation på att det finns en ägare, kommer DirectWrite att göra en kopia av data till en ny minnesbuffert som den kommer att äga. För att undvika kopiering av data och ytterligare minnesallokering kan appen skicka ett dataägarobjekt som implementerar IUnknown och som äger minnesbufferten som innehåller teckensnittsdata. Genom att implementera det här gränssnittet kan DirectWrite lägga till referensantalet för objektet, vilket säkerställer livslängden för de ägda data. 

Metoden för att skapa en anpassad teckensnittsuppsättning med minnesintern teckensnittsdata är följande. Detta kräver Windows 10 Creators Update. Detta förutsätter ett app-implementerat dataägarobjekt som implementerar IUnknown och även har metoder som returnerar en pekare till minnesbufferten och buffertens storlek. 

1. Skapa ett IDWriteFactory5-gränssnitt enligt ovan. 2. Skapa ett [**IDWriteFontSetBuilder1**](/windows/win32/api/dwrite_3/nn-dwrite_3-idwritefontsetbuilder1) som du ser ovan. 3. Använd fabriken för att hämta en IDWriteInMemoryFontFileLoader. 
 IDWriteInMemoryFontFileLoader* pInMemoryFontFileLoader; 
if (SUCCEEDED(hr)) 
{ 
    hr = pDWriteFactory->CreateInMemoryFontFileLoader(&pInMemoryFontFileLoader); 
}

Detta returnerar en systemimplementering av det minnesinterna teckensnittsfilinläsningsgränssnittet. 
4. Registrera den minnesinterna teckensnittsfilinläsaren med fabriken. 

if (SUCCEEDED(hr)) 
{ 
    hr = pDWriteFactory->RegisterFontFileLoader(pInMemoryFontFileLoader); 
}

 
5. För varje minnesintern teckensnittsfil använder du den minnesinterna teckensnittsfilinläsaren för att skapa en IDWriteFontFile

IDWriteFontFile* pFontFile; 
hr = pInMemoryFontFileLoader->CreateInMemoryFontFileReference( 
    pDWriteFactory, 
    pFontDataOwner->fontData /* returns void* */, 
    pFontDataOwner->fontDataSize /* returns UINT32 */, 
    pFontDataOwner /* ownerObject, owns the memory with font data and implements IUnknown */, 
    &pFontFile 
); 

 
6. Lägg till objektet IDWriteFontFile i teckensnittsuppsättningsverktyget med hjälp av metoden AddFontFile, enligt ovan.  Om det finns ett behov kan appen i stället skapa enskilda IDWriteFontFaceReference- objekt baserat på IDWriteFontFile, alternativt definiera anpassade egenskaper för varje teckensnittsansikte och sedan lägga till ansiktsreferensen för teckensnitt med anpassade egenskaper i teckensnittsuppsättningen med hjälp av metoden AddFontFaceReference, som visas ovan. 
7. När alla teckensnitt har lagts till i teckensnittsuppsättningsverktyget skapar du den anpassade teckensnittsuppsättningen enligt ovan. 
8. När de minnesinterna teckensnitten inte längre används avregistrerar du den minnesinterna teckensnittsfilinläsaren. 

hr = pDWriteFactory->UnregisterFontFileLoader(pInMemoryFontFileLoader);

 

Avancerade scenarier

Vissa appar kan ha särskilda krav som kräver mer avancerad bearbetning än vad som beskrivs ovan. 

Kombinera teckensnittsuppsättningar

Vissa appar kan behöva skapa en teckensnittsuppsättning som består av en kombination av objekt från andra teckensnittsuppsättningar. En app kanske till exempel vill skapa en teckensnittsuppsättning som kombinerar alla teckensnitt som är installerade i systemet med ett urval av anpassade teckensnitt, eller som kombinerar installerade teckensnitt som matchar vissa villkor med andra teckensnitt. DirectWrite har API:er som stöd för manipulering och kombination av teckensnittsuppsättningar. 

Om du vill kombinera två eller flera teckensnittsuppsättningar lägger IDWriteFontSetBuilder::AddFontSet-metoden till alla teckensnitt i angiven teckensnittsuppsättning som ska läggas till i en teckensnittsuppsättningsbyggare i ett enda anrop. Om endast vissa teckensnitt från en befintlig teckensnittsuppsättning är önskade i den nya teckensnittsuppsättningen kan metoden IDWriteFontSet::GetMatchingFonts användas för att härleda ett nytt teckensnittsuppsättningsobjekt som har filtrerats för att endast innehålla teckensnitt som matchar angivna egenskaper. De här metoderna är ett enkelt sätt att skapa en anpassad teckensnittsuppsättning som kombinerar teckensnitt från två eller flera befintliga teckensnittsuppsättningar

Använda lokala WOFF- eller WOFF2-teckensnittsdata

Om en app har teckensnittsfiler i det lokala filsystemet eller i en minnesbuffert, men de använder containerformaten WOFF eller WOFF2, tillhandahåller DirectWrite (Windows 10 Creator Update eller senare) en metod för att packa upp containerformatet, IDWriteFactory5::UnpackFontFile, som returnerar en IDWriteFontFileStream

Appen behöver dock ett sätt att hämta IDWriteFontFileStream- till ett teckensnittsfilinläsningsobjekt. Ett sätt att göra detta är att skapa en anpassad IDWriteFontFileLoader implementering som omsluter strömmen. Precis som med andra teckensnittsfilinläsare måste detta registreras före användning och avregistreras innan fabriken hamnar utanför omfånget.  

Om den anpassade inläsaren också ska användas med råa (inte packade) teckensnittsfiler måste appen också tillhandahålla en anpassad implementering av IDWriteFontFileStream--gränssnittet för hantering av dessa filer. Det finns dock enklare sätt att använda API:er som beskrivs ovan för hantering av råa teckensnittsfiler. Behovet av en anpassad strömimplementering kan undvikas genom att använda separata kodsökvägar för packade teckensnittsfiler jämfört med råa teckensnittsfiler. 

När ett anpassat teckensnittsfilinläsningsobjekt har skapats läggs de packade teckensnittsfildata till i inläsaren på ett appspecifikt sätt. Inläsaren kan hantera flera teckensnittsfiler, som var och en identifieras med hjälp av en appdefinierad nyckel som är ogenomskinlig för DirectWrite. När en packad teckensnittsfil har lagts till i inläsaren används metoden IDWriteFactory::CreateCustomFontFileReference för att hämta en IDWriteFontFile- baserat på den inläsaren för teckensnittsdata som identifieras av en viss nyckel.  

Den faktiska uppackningen av teckensnittsdata kan göras när teckensnitt läggs till i inläsaren, men kan också hanteras i metoden IDWriteFontFileLoader::CreateStreamFromKey metod, som DirectWrite anropar när den först behöver läsa teckensnittsdata. 

När ett IDWriteFontFile-objekt har skapats kommer återstående steg för att lägga till teckensnitten i en anpassad teckensnittsuppsättning att vara enligt beskrivningen ovan. 

En implementering med den här metoden illustreras i exemplet DirectWrite Custom Font Sets

Använda DirectWrite-fjärrteckensnittsmekanismer med anpassad nätverksimplementering på låg nivå

DirectWrite-mekanismerna för hantering av fjärrteckensnitt kan delas in i mekanismer på högre nivå – med teckensnittsuppsättningar som innehåller teckenigenkänningsreferenser för fjärrteckensnitt, kontroll av teckendata och hantering av kön för begäranden om teckensnittsnedladdning – och mekanismer på lägre nivå som hanterar faktisk nedladdning. Vissa appar kanske vill använda fjärrteckensnittsmekanismer på högre nivå, men kräver även anpassade nätverksinteraktioner, till exempel kommunikation med servrar med andra protokoll än HTTP. 

I det här fallet måste en app skapa en anpassad implementering av IDWriteRemoteFontFileLoader- gränssnitt som interagerar med andra gränssnitt på lägre nivå på de sätt som krävs. Appen måste också tillhandahålla anpassade implementeringar av dessa gränssnitt på lägre nivå: IDWriteRemoteFontFileStreamoch IDWriteAsyncResult. Dessa tre gränssnitt har motringningsmetoder som DirectWrite anropar under nedladdningsåtgärder. 

När IDWriteFontDownloadQueue::BeginDownload anropas, skickar DirectWrite frågor till filinläsaren för fjärrteckensnitt om datalokaliteten och begär fjärrströmmen. Om data inte är lokala anropas strömmens BeginDownload-metod. Dataströmimplementeringen bör inte blockeras för det anropet, men bör omedelbart returneras och skicka tillbaka ett IDWriteAsyncResult- objekt som tillhandahåller väntehandtaget DirectWrite använder för att vänta på den asynkrona nedladdningsåtgärden. Implementeringen av den anpassade dataströmmen ansvarar för att hantera fjärrkommunikationen. När slutförandehändelsen har inträffat anropar DirectWrite IDWriteAsyncResult::GetResult för att fastställa resultatet av åtgärden. Om resultatet lyckas förväntas efterföljande ReadFragment-anrop till dataströmmen för de nedladdade intervallen. 

Viktig

Säkerhets-/prestandaanteckning: När ett försök görs att hämta ett fjärrteckensnitt finns det i allmänhet en risk för att en angripare förfalskar den avsedda servern som anropas eller att servern kanske inte svarar. Om du implementerar anpassade nätverksinteraktioner kan du ha större kontroll över åtgärder än när du hanterar servrar från tredje part. Det är dock upp till dig att överväga lämpliga åtgärder för att undvika avslöjande av information eller överbelastning. Säkra protokoll som HTTPS rekommenderas. Du bör också skapa en timeout så att händelsehandtaget som returneras till DirectWrite så småningom ställs in. 

 

Stödscenarier i tidigare Windows-versioner

Scenarier som har beskrivits kan stödjas i DirectWrite i tidigare versioner av Windows, men skulle kräva mycket mer anpassad implementering från appens sida med hjälp av de mer begränsade API:er som var tillgängliga före Windows 10. Mer information finns i anpassade teckensnittssamlingar (Windows 7/8).