Bagikan melalui


Set Font Kustom

Topik ini menjelaskan berbagai cara untuk menggunakan font kustom di aplikasi Anda.

Perkenalan

Sebagian besar waktu, aplikasi menggunakan font yang diinstal secara lokal pada sistem. DirectWrite menyediakan akses ke font ini menggunakan IDWriteFactory3::GetSystemFontSet atau IDWriteFactory::GetSystemFontCollection metode. Dalam beberapa kasus, aplikasi mungkin juga ingin menggunakan font yang disertakan sebagai bagian dari Windows 10 tetapi saat ini tidak diinstal pada sistem saat ini. Font tersebut dapat diakses dari layanan font Windows dengan menggunakan metode GetSystemFontSet, atau dengan memanggil IDWriteFactory3::GetSystemFontCollection dengan includeDownloadableFonts diatur ke TRUE. 

Namun, dalam beberapa skenario aplikasi, aplikasi perlu menggunakan font yang tidak diinstal dalam sistem dan tidak disediakan oleh Layanan Font Windows. Berikut ini adalah contoh skenario tersebut:

  • Font disematkan sebagai sumber daya dalam biner aplikasi.
  • File font dibundel dalam paket aplikasi dan disimpan di disk di bawah folder penginstalan aplikasi.
  • Aplikasi ini adalah alat pengembangan font yang perlu memuat file font yang ditentukan pengguna. 
  • Font disematkan dalam file dokumen yang dapat dilihat atau diedit di aplikasi. 
  • Aplikasi ini menggunakan font yang diperoleh dari layanan font Web publik. 
  • Aplikasi ini menggunakan data font yang dialirkan melalui protokol jaringan privat. 

DirectWrite menyediakan API untuk bekerja dengan font kustom dalam skenario ini dan skenario serupa lainnya. Data font kustom mungkin berasal dari file dalam sistem file lokal; dari sumber berbasis cloud jarak jauh yang diakses menggunakan HTTP; atau dari sumber arbitrer setelah dimuat ke dalam buffer memori. 

Nota

Meskipun DirectWrite telah menyediakan API untuk bekerja dengan font kustom sejak Windows 7, API yang lebih baru ditambahkan di Windows 10 dan sekali lagi di Windows 10 Creators Update (pratinjau build 15021 atau yang lebih baru) yang memudahkan untuk menerapkan beberapa skenario yang disebutkan. Topik ini berfokus pada API yang tersedia di Jendela 10. Untuk aplikasi yang perlu bekerja pada versi Windows sebelumnya, lihat Koleksi Font Kustom (Windows 7/8)

 

Ringkasan API

Topik ini berfokus pada fungsionalitas yang disediakan oleh API berikut:

 

Konsep utama

Untuk memahami API DirectWrite untuk bekerja dengan font kustom, akan sangat membantu untuk memahami model konseptual yang mendasar API ini. Konsep utama akan dijelaskan di sini. 

Ketika DirectWrite melakukan tata letak atau penyajian teks aktual, DirectWrite perlu mengakses data font aktual. Objek wajah font menyimpan data font aktual, yang harus ada di sistem lokal. Tetapi untuk operasi lain, seperti memeriksa ketersediaan font tertentu, atau menyajikan pilihan font kepada pengguna, semua yang diperlukan adalah referensi ke font tertentu, bukan data font aktual itu sendiri. Di DirectWrite, objek referensi wajah font hanya menyimpan informasi yang diperlukan untuk menemukan dan membuat instans font. Karena referensi wajah font tidak menyimpan data aktual, DirectWrite dapat menangani referensi wajah font yang data aktualnya berada di lokasi jaringan jarak jauh serta ketika data aktual lokal.

Kumpulan font adalah sekumpulan referensi wajah font, bersama dengan properti informasi dasar tertentu yang dapat digunakan untuk merujuk ke font atau membandingkannya dengan font lain, seperti nama keluarga, atau nilai bobot font. Data aktual untuk berbagai font mungkin lokal, atau semuanya jarak jauh, atau beberapa campuran.

Kumpulan font dapat digunakan untuk mendapatkan objek koleksi font yang sesuai. Lihat Kumpulan font dan koleksi font di bawah ini untuk detail selengkapnya. 

Antarmuka IDWriteFontSet menyediakan metode yang memungkinkan kueri untuk nilai properti seperti nama keluarga atau bobot font, atau untuk referensi wajah font yang cocok dengan nilai properti tertentu. Setelah memfilter ke pilihan tertentu, instans antarmukaIDWriteFontFaceReferencedapat diperoleh, dengan metode untuk mengunduh (jika data font aktual saat ini jarak jauh), untuk mendapatkan objekIDWriteFontFace3 yang sesuai yang dapat digunakan untuk tata letak dan penyajian. 

Antarmuka IDWriteFontFile mendasar setiap wajah font atau referensi wajah font. Ini mewakili lokasi file font, dan memiliki dua komponen: pemuat file font, dan kunci file font. Pemuat file font (IDWriteFontFileLoader) digunakan untuk membuka file jika diperlukan, dan mengembalikan aliran dengan data (IDWriteFontFileStream). Bergantung pada loader, data mungkin terletak di jalur file lokal, URL jarak jauh, atau dalam buffer memori. Kuncinya adalah nilai yang ditentukan pemuat yang secara unik mengidentifikasi file dalam konteks pemuat, memungkinkan pemuat menemukan data dan membuat aliran untuknya. 

Font kustom dapat dengan mudah ditambahkan ke kumpulan font kustom, yang pada gilirannya dapat digunakan untuk memfilter atau mengatur informasi font untuk tujuan seperti membuat antarmuka pengguna pemilih font. Kumpulan font juga dapat digunakan untuk membuat koleksi font untuk digunakan dalam API tingkat yang lebih tinggi seperti IDWriteTextFormat dan IDWriteTextLayout. AntarmukaIDWriteFontSetBuilderdapat digunakan untuk membuat kumpulan font kustom yang menyertakan beberapa font kustom. Ini juga dapat digunakan untuk membuat kumpulan font kustom yang mencampur font kustom dan font yang disediakan sistem; atau yang mencampur font dengan sumber yang berbeda untuk data aktual - penyimpanan lokal, URL jarak jauh, dan memori. 

Seperti disebutkan, referensi wajah font dapat merujuk ke data font di sumber jarak jauh, tetapi data harus lokal untuk mendapatkan objek wajah font yang dapat digunakan untuk tata letak dan penyajian. Pengunduhan data jarak jauh ditangani oleh antrean unduhan font. Aplikasi dapat menggunakan antarmukaIDWriteFontDownloadQueueuntuk mengantrekan permintaan untuk mengunduh font jarak jauh untuk memulai proses pengunduhan, dan untuk mendaftarkan objekIDWriteFontDownloadListener untuk mengambil tindakan ketika proses pengunduhan telah selesai. 

Untuk sebagian besar antarmuka yang dijelaskan di sini, DirectWrite menyediakan implementasi sistem. Satu pengecualian adalah antarmukaIDWriteFontDownloadListener, yang diterapkan aplikasi untuk mengambil tindakan khusus aplikasi ketika font jarak jauh telah diunduh secara lokal. Aplikasi mungkin memiliki alasan untuk menyediakan implementasi kustom mereka sendiri untuk antarmuka lain tertentu, meskipun itu hanya akan diperlukan dalam skenario tertentu yang lebih canggih. Misalnya, aplikasi perlu menyediakan implementasi kustom antarmukaIDWriteFontFileLoaderuntuk menangani file font di penyimpanan lokal yang menggunakan format kontainer WOFF2. Detail tambahan akan diberikan di bawah ini. 

Font dan format file font

Konsep kunci lain yang berguna untuk dipahami adalah hubungan antara wajah font individu dan file font yang berisinya. Gagasan file font OpenType (.ttf atau .otf) yang berisi satu font sudah tidak asing lagi. Tetapi format font OpenType juga memungkinkan Koleksi Font OpenType (.ttc atau .otc), yang merupakan satu file yang berisi beberapa font. File Koleksi OpenType sering digunakan untuk font besar yang terkait erat dan memiliki nilai yang identik untuk data font tertentu: dengan menggabungkan font dalam satu file, data umum dapat diduplikasi. Untuk alasan ini, wajah font atau referensi wajah font perlu merujuk tidak hanya ke file font (atau sumber data yang setara), tetapi juga harus menentukan indeks font dalam file tersebut, untuk kasus umum di mana file mungkin merupakan file Koleksi. 

Untuk font yang digunakan di Web, data font sering dikemas ke dalam format kontainer tertentu, WOFF atau WOFF2, yang menyediakan beberapa pemadatan data font dan beberapa tingkat perlindungan terhadap pembajakan dan pelanggaran lisensi font. Secara fungsional, file WOFF atau WOFF2 setara dengan font OpenType atau file Koleksi Font, tetapi data dikodekan dalam format berbeda yang memerlukan pembongkaran sebelum dapat digunakan. 

API DirectWrite tertentu dapat menangani wajah font individual, sementara API lain dapat menangani file yang mungkin menyertakan file Koleksi OpenType yang berisi beberapa wajah. Demikian pula, API tertentu hanya menangani data berformat OpenType mentah, sementara API lain dapat menangani format kontainer yang dikemas, WOFF, dan WOFF2. Detail ini disediakan dalam diskusi di bawah ini. 

Kumpulan font dan koleksi font

Beberapa aplikasi dapat diimplementasikan untuk bekerja dengan font menggunakan antarmukaIDWriteFontCollection. Ada korespondensi langsung antara koleksi font dan kumpulan font. Masing-masing dapat menyimpan font yang sama, tetapi mereka menyajikannya dengan organisasi yang berbeda. Dari koleksi font apa pun, kumpulan font yang sesuai dapat diperoleh, dan sebaliknya.

Saat bekerja dengan sejumlah font kustom, paling mudah menggunakan antarmuka penyusun kumpulan font untuk membuat kumpulan font kustom, lalu mendapatkan koleksi font setelah kumpulan font dibuat. Proses untuk membuat kumpulan font kustom akan dijelaskan secara rinci di bawah ini. Untuk mendapatkan antarmukaIDWriteFontCollection1dari set font, metode IDWriteFactory3::CreateFontCollectionFromFontSet digunakan.

Jika aplikasi memiliki objek koleksi dan perlu mendapatkan kumpulan font yang sesuai, ini dapat dilakukan menggunakan metode IDWriteFontCollection1::GetFontSet

Skenario umum

Bagian ini menjelaskan beberapa skenario paling umum yang melibatkan kumpulan font kustom:

  • Membuat kumpulan font kustom menggunakan font arbitrer di jalur dalam sistem file lokal.
  • Membuat kumpulan font kustom menggunakan font yang diketahui (mungkin dibundel dengan aplikasi) yang disimpan dalam sistem file lokal.
  • Membuat kumpulan font kustom menggunakan font jarak jauh yang diketahui di Web.
  • Membuat kumpulan font kustom menggunakan data font yang dimuat ke dalam memori.

Implementasi lengkap untuk skenario ini disediakan dalam sampel Set Font Kustom DirectWrite. Sampel itu juga menggambarkan satu skenario tingkat lanjut lagi untuk menangani data font yang dikemas dalam format kontainer WOFF atau WOFF2, yang akan dibahas di bawah ini. 

Membuat kumpulan font menggunakan font arbitrer dalam sistem file lokal

Saat berhadapan dengan sekumpulan file font arbitrer di penyimpanan lokal, metode IDWriteFontSetBuilder1::AddFontFile nyaman karena, dalam satu panggilan, ia dapat menangani semua wajah font dalam file Koleksi Font OpenType, serta semua instans untuk font variabel OpenType. Ini tersedia di Pembaruan Pembuat Windows 10 (pratinjau build 15021 atau yang lebih baru), dan direkomendasikan setiap kali tersedia. 

Untuk menggunakan metode ini, gunakan proses berikut.

1. Mulailah dengan membuat antarmuka IDWriteFactory5:
IDWriteFactory5* pDWriteFactory; 
HRESULT hr = DWriteCreateFactory( 
  DWRITE_FACTORY_TYPE_SHARED, 
  __uuidof(IDWriteFactory5), 
  reinterpret_cast<IUnknown**>(&pDWriteFactory) 
); 

 
2. Gunakan pabrik untuk mendapatkan antarmukaIDWriteFontSetBuilder1 :

IDWriteFontSetBuilder1* pFontSetBuilder; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder); 
}  
                
  1. Untuk setiap file font dalam sistem file lokal, buatIDWriteFontFileyang mengacu padanya:
IDWriteFontFile* pFontFile; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile); 
} 

 
4. Tambahkan objekIDWriteFontFile ke penyusun set font menggunakan metodeAddFontFile:

hr = pFontSetBuilder->AddFontFile(pFontFile); 

Jika jalur file yang ditentukan dalam panggilan ke CreateFontFileReference merujuk ke sesuatu selain file OpenType yang didukung, maka panggilan ke AddFontFile akan mengembalikan kesalahan, DWRITE_E_FILEFORMAT.

  1. Setelah semua file ditambahkan ke penyusun kumpulan font, kumpulan font kustom dapat dibuat:
IDWriteFontSet* pFontSet; 
hr = pFontSetBuilder->CreateFontSet(&pFontSet); 

 

Jika aplikasi perlu berjalan pada versi Windows 10 yang lebih lama dari Pembaruan Pembuat Windows 10, maka metode AddFontFile tidak akan tersedia. Ketersediaan dapat dideteksi dengan membuat antarmukaIDWriteFactory3lalu menggunakan QueryInterface untuk mencoba mendapatkan antarmukaIDWriteFactory5: jika ini berhasil, maka antarmuka IDWriteFontSetBuilder1 dan metode AddFontFile juga akan tersedia.

Jika metode AddFontFile tidak tersedia, maka metodeIDWriteFontSetBuilder::AddFontFaceReference harus digunakan untuk menambahkan wajah font individual. Untuk memungkinkan file Koleksi Font OpenType yang berisi beberapa wajah, metode IDWriteFontFile::Analyze dapat digunakan untuk menentukan jumlah wajah yang terkandung dalam file. Prosesnya adalah sebagai berikut.

1. Mulailah dengan membuat antarmuka IDWriteFactory3:
IDWriteFactory3* pDWriteFactory; 
HRESULT hr = DWriteCreateFactory( 
DWRITE_FACTORY_TYPE_SHARED, 
  __uuidof(IDWriteFactory5), 
  reinterpret_cast<IUnknown**>(&pDWriteFactory) 
); 
  1. Gunakan pabrik untuk mendapatkan antarmukaIDWriteFontSetBuilder:
IDWriteFontSetBuilder* pFontSetBuilder; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder); 
} 
  1. Untuk setiap file font, buatIDWriteFontFile, seperti di atas:
IDWriteFontFile* pFontFile; 
if (SUCCEEDED(hr)) 
{ 
  hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile); 
} 

Alih-alih menambahkan file langsung ke penyusun kumpulan font, kita perlu menentukan jumlah wajah dan membuat objekIDWriteFontFaceReference individual. 
4. Gunakan metode Analyze untuk mendapatkan jumlah wajah dalam file. 

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

Metode Analyze juga akan mengatur nilai untuk parameter isSupported dan fileType. Jika file bukan format yang didukung, maka isSupported akan FALSE, dan tindakan yang sesuai, seperti mengabaikan file, dapat diambil. 
5. Perulangan atas jumlah font yang ditetapkan dalam parameter numberOfFonts. Dalam perulangan, buatIDWriteFontFaceReferenceuntuk setiap pasangan file/indeks, dan tambahkan ke penyusun kumpulan font. 

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. Setelah semua wajah ditambahkan ke penyusun kumpulan font, buat kumpulan font kustom, seperti yang ditunjukkan di atas.

Aplikasi dapat dirancang sehingga akan menggunakan metodeAddFontFilepilihan saat berjalan pada Windows 10 Creators Update, tetapi kembali menggunakan metode AddFontFaceReference saat berjalan pada versi Windows 10 sebelumnya. Uji ketersediaan antarmukaIDWriteFactory5, seperti yang dijelaskan di atas, lalu cabang yang sesuai. Pendekatan ini diilustrasikan dalam sampel Set Font Kustom DirectWrite

Membuat kumpulan font menggunakan font yang diketahui dalam sistem file lokal

Seperti disebutkan di atas, setiap referensi wajah font dalam kumpulan font dikaitkan dengan properti informasi tertentu, seperti nama keluarga dan bobot font. Saat font kustom ditambahkan ke penyusun kumpulan font menggunakan panggilan API yang tercantum di atas, properti informasi ini diperoleh langsung dari data font aktual, yang dibaca saat font ditambahkan. Namun, dalam beberapa situasi, jika aplikasi memiliki sumber informasi lain tentang font, aplikasi mungkin ingin memberikan nilai kustomnya sendiri untuk properti ini. 

Sebagai contoh bagaimana ini mungkin berguna, misalkan aplikasi menggabungkan beberapa font yang digunakan untuk menyajikan elemen antarmuka pengguna tertentu dalam aplikasi. Terkadang, seperti dengan versi aplikasi baru, font tertentu yang digunakan aplikasi untuk elemen-elemen ini mungkin perlu diubah. Jika aplikasi memiliki referensi yang dikodekan ke font tertentu, maka penggantian satu font dengan font lainnya akan memerlukan perubahan setiap referensi tersebut. Sebagai gantinya, jika aplikasi menggunakan properti kustom untuk menetapkan alias fungsional berdasarkan jenis elemen atau teks yang dirender, memetakan setiap alias ke font tertentu di satu tempat lalu menggunakan alias dalam semua konteks tempat font dibuat dan dimanipulasi, lalu mengganti satu font dengan yang lain hanya memerlukan perubahan satu tempat di mana alias dipetakan ke font tertentu. 

Nilai kustom untuk properti informasi dapat ditetapkan saat metode IDWriteFontSetBuilder::AddFontFaceReference dipanggil. Metode untuk melakukan ini adalah sebagai berikut; ini dapat digunakan pada versi Windows 10 apa pun. 

Seperti yang ditunjukkan di atas, mulailah dengan mendapatkan antarmuka IDWriteFactory3 dan IDWriteFontSet. Agar setiap wajah font kustom ditambahkan, buat IDWriteFontFaceReference, seperti yang ditunjukkan di atas. Sebelum ini ditambahkan ke penyusun set font (dalam perulangan di langkah 5, ditunjukkan di atas), namun, aplikasi menentukan nilai properti kustom yang akan digunakan. 

Sekumpulan nilai properti kustom didefinisikan menggunakan array struktur DWRITE_FONT_PROPERTY. Masing-masing mengidentifikasi properti tertentu dari enum DWRITE_FONT_PROPERTY_ID, dan nilai properti terkait yang akan digunakan.  

Perhatikan bahwa semua nilai properti ditetapkan sebagai string. Jika ini nantinya dapat ditampilkan kepada pengguna, maka nilai alternatif untuk properti tertentu untuk bahasa yang berbeda dapat diatur, tetapi ini tidak diperlukan. Perhatikan juga bahwa jika ada nilai properti kustom yang ditetapkan oleh aplikasi, maka hanya nilai yang ditentukan yang akan digunakan dalam kumpulan Font; DirectWrite tidak akan memperoleh nilai apa pun langsung dari font untuk properti informasi yang digunakan dalam kumpulan font. 

Contoh berikut menentukan nilai kustom untuk tiga properti informasi: nama keluarga, nama lengkap, dan bobot font. 

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 } 
}; 
               
            

Setelah menentukan array nilai properti yang diinginkan untuk font, lakukan panggilan ke AddFontFaceRefence, meneruskan array properti serta referensi wajah font. 

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

 

Setelah semua wajah font kustom ditambahkan ke penyusun kumpulan font, bersama dengan properti kustomnya, buat kumpulan font kustom, seperti yang ditunjukkan di atas. 

Membuat kumpulan font kustom menggunakan font jarak jauh yang diketahui di Web

Properti kustom penting untuk bekerja dengan font jarak jauh. Setiap referensi wajah font harus memiliki beberapa properti informasi untuk mencirikan font dan membedakannya dari font lain. Karena data font untuk font jarak jauh tidak lokal, DirectWrite tidak dapat memperoleh properti langsung dari data font. Oleh karena itu, properti harus disediakan secara eksplisit saat menambahkan font jarak jauh ke penyusun kumpulan font.

Urutan panggilan API untuk menambahkan font jarak jauh ke kumpulan font mirip dengan urutan yang dijelaskan untuk skenario sebelumnya. Karena data font bersifat jarak jauh, namun, operasi yang terlibat untuk membaca data font aktual akan berbeda dari saat bekerja dengan file di penyimpanan lokal. Untuk situasi ini, antarmuka tingkat bawah baru, IDWriteRemoteFontFileLoader, telah ditambahkan dalam Pembaruan Pembuat Windows 10. 

Untuk menggunakan pemuat file font jarak jauh, harus terlebih dahulu didaftarkan ke pabrik DirectWrite. Loader harus dipegang oleh aplikasi selama font yang terkait dengannya digunakan. Setelah font tidak lagi digunakan, dan pada titik tertentu sebelum pabrik dihancurkan, loader harus tidak terdaftar. Ini dapat dilakukan di destruktor untuk kelas yang memiliki objek loader. Langkah-langkah ini akan ditunjukkan di bawah ini. 

Metode untuk membuat kumpulan font kustom menggunakan font jarak jauh adalah sebagai berikut; ini memerlukan Pembaruan Pembuat Windows 10.  

1. Buat antarmuka IDWriteFactory5, seperti yang ditunjukkan di atas.  2. Buat antarmuka IDWriteFontSetBuilder, seperti yang ditunjukkan di atas.  3. Gunakan pabrik untuk mendapatkan IDWriteRemoteFontFileLoader
IDWriteRemoteFontFileLoader* pRemoteFontFileLoader; 
if (SUCCEEDED(hr)) 
{ 
    hr = pDWriteFactory->CreateHttpFontFileLoader( 
        /* referrerURL */ nullptr, 
        /* extraHeaders */ nullptr, 
        &pRemoteFontFileLoader 
    ); 
} 

Ini mengembalikan implementasi antarmuka pemuat file font jarak jauh yang disediakan sistem yang dapat menangani interaksi HTTP untuk mengunduh data font atas nama aplikasi. URL perujuk atau header tambahan dapat ditentukan jika diperlukan oleh layanan font atau layanan yang merupakan sumber untuk font.  

Penting

Catatan keamanan: Ketika upaya dilakukan untuk mengambil font jarak jauh, potensi ada bagi penyerang untuk memalsukan server yang dimaksudkan yang akan dipanggil. Dalam hal ini, URL target dan perujuk dan detail header akan diungkapkan kepada penyerang. Pengembang aplikasi bertanggung jawab untuk mengurangi risiko ini. Penggunaan protokol HTTPS, bukan HTTP, disarankan. 

 

Pemuat file font jarak jauh tunggal dapat digunakan untuk beberapa font, meskipun pemuat yang berbeda dapat digunakan jika font diperoleh dari beberapa layanan yang memiliki persyaratan berbeda untuk URL perujuk atau header tambahan. 
4. Daftarkan pemuat file font jarak jauh dengan pabrik. 

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

Dari titik ini, langkah-langkah untuk membuat kumpulan font kustom mirip dengan yang dijelaskan untuk file font lokal yang diketahui, dengan dua pengecualian penting. Pertama, objekIDWriteFontFile dibuat menggunakan antarmuka pemuat file font jarak jauh daripada menggunakan pabrik. Kedua, metode Analisis tidak dapat digunakan karena data font tidak lokal. Sebaliknya, aplikasi harus tahu apakah file font jarak jauh adalah file Koleksi Font OpenType, dan jika demikian, maka harus mengetahui font mana dalam koleksi yang akan digunakannya, dan indeks untuk masing-masing. Oleh karena itu, langkah-langkah yang tersisa adalah sebagai berikut. 
5. Untuk setiap file font jarak jauh, gunakan antarmuka pemuat file font jarak jauh untuk membuat IDWriteFontFile, menentukan URL yang diperlukan untuk mengakses file font. 

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

Perhatikan bahwa URL lengkap dapat ditentukan dalam parameter fontFileUrl, atau dapat dibagi menjadi bagian dasar dan relatif. Jika URL dasar ditentukan, maka penggabungan nilai baseUrl dan fontFileUrl harus menyediakan URL lengkap — DirectWrite tidak akan menyediakan pemisah tambahan apa pun.

Penting

Catatan keamanan / performa: Ketika upaya dilakukan untuk mengambil font jarak jauh, tidak ada jaminan bahwa Windows akan menerima respons dari server. Dalam beberapa kasus, server dapat merespons dengan kesalahan file yang tidak ditemukan untuk URL relatif yang tidak valid, tetapi berhenti merespons jika menerima beberapa permintaan yang tidak valid. Jika server tidak merespons, Windows pada akhirnya akan kehabisan waktu, meskipun ini mungkin memakan waktu beberapa menit jika beberapa pengambilan dimulai. Anda harus melakukan apa yang Anda bisa untuk memastikan bahwa URL akan valid saat panggilan dilakukan. 

 

Perhatikan juga bahwa URL dapat menunjuk ke file font OpenType mentah (.ttf, .otf, .ttc, .otc), tetapi juga dapat menunjuk ke font dalam file kontainer WOFF atau WOFF2. Jika file WOFF atau WOFF2 direferensikan, implementasi DirectWrite dari pemuat file font jarak jauh akan secara otomatis membongkar data font dari file kontainer. 
6. Untuk setiap indeks wajah font dalam file font jarak jauh yang akan digunakan, buat IDWriteFontFaceReference

 IDWriteFontFaceReference* pFontFaceReference; 
 hr = pDWriteFactory->CreateFontFaceReference(pFontFile, /* faceIndex */ 0, DWRITE_FONT_SIMULATIONS_NONE, &pFontFaceReference);
  1. Tentukan properti kustom untuk wajah font, seperti yang ditunjukkan di atas. 
  2. Tambahkan referensi wajah font bersama dengan properti kustom ke penyusun kumpulan font, seperti yang ditunjukkan di atas. 
  3. Setelah semua font ditambahkan ke penyusun kumpulan font, buat kumpulan font, seperti yang ditunjukkan di atas. 
  4. Pada titik tertentu ketika font jarak jauh tidak akan lagi digunakan, batalkan pendaftaran pemuat file font jarak jauh. 
hr = pDWriteFactory->UnregisterFontFileLoader(pRemoteFontFileLoader); 

Setelah font kustom diatur dengan font jarak jauh kustom dibuat, kumpulan font berisi referensi dan properti informasi untuk font jarak jauh, tetapi data aktual masih jarak jauh. Dukungan DirectWrite untuk font jarak jauh memungkinkan referensi wajah font dipertahankan dalam kumpulan font, dan agar font dipilih untuk digunakan dalam tata letak dan penyajian, tetapi bahwa data aktual tidak diunduh sampai ada kebutuhan aktual untuk menggunakannya, seperti ketika tata letak teks akan dilakukan.  

Aplikasi dapat mengambil pendekatan di muka dengan meminta DirectWrite mengunduh data font dan kemudian menunggu konfirmasi unduhan yang berhasil sebelum pemrosesan apa pun dengan font dimulai. Tetapi unduhan jaringan menyiratkan beberapa latensi durasi yang tidak dapat diprediksi, dan keberhasilan juga tidak pasti. Untuk alasan ini, biasanya akan lebih baik untuk mengambil pendekatan yang berbeda, memungkinkan tata letak dan penyajian dilakukan awalnya menggunakan font alternatif atau fallback yang sudah lokal, sambil meminta unduhan font jarak jauh yang diinginkan secara paralel, dan kemudian memperbarui hasilnya setelah font yang diinginkan diunduh. 

Untuk meminta agar seluruh font diunduh sebelum digunakan, metodeIDWriteFontFaceReference::EnqueueFontDownloadRequest dapat digunakan. Jika font sangat besar, hanya sebagian data yang mungkin diperlukan untuk memproses string tertentu. DirectWrite menyediakan metode tambahan yang dapat digunakan untuk meminta bagian data font yang diperlukan untuk konten tertentu, EnqueueCharacterDownloadRequest dan EnqueueGlyphDownloadRequest.  

Misalkan pendekatan yang akan diambil dalam aplikasi adalah memungkinkan pemrosesan dilakukan awalnya menggunakan font lokal, alternatif, atau fallback. MetodeIDWriteFontFallback::MapCharacters dapat digunakan untuk mengidentifikasi font fallback lokal, dan juga akan secara otomatis mengantrekan permintaan untuk mengunduh font pilihan. Selain itu, jika IDWriteTextLayout digunakan dan beberapa atau semua teks dalam tata letak diformat menggunakan referensi font jarak jauh, maka DirectWrite akan secara otomatis menggunakan metode MapCharacters untuk mendapatkan font fallback lokal dan untuk mengantrekan permintaan untuk mengunduh data font jarak jauh. 

DirectWrite mempertahankan antrean unduhan font untuk setiap pabrik, dan permintaan yang dibuat menggunakan metode yang disebutkan di atas ditambahkan ke antrean tersebut. Antrean unduhan font dapat diperoleh menggunakan metode IDWriteFactory3::GetFontDownloadQueue

Jika permintaan unduhan dibuat tetapi data font sudah lokal, ini akan menghasilkan no-op: Tidak ada yang akan ditambahkan ke antrean unduhan. Aplikasi dapat memeriksa apakah antrean kosong atau ada permintaan unduhan yang tertunda dengan memanggil metode IDWriteFontDownloadQueue::IsEmpty

Setelah permintaan font jarak jauh ditambahkan ke antrean, proses pengunduhan harus dimulai. Ketika font jarak jauh digunakan di IDWriteTextLayout, unduhan akan dimulai secara otomatis ketika aplikasi memanggil metode IDWriteTextLayout yang memaksa operasi tata letak atau penyajian, seperti metode GetLineMetrics atau Draw. Dalam skenario lain, aplikasi harus memulai unduhan secara langsung dengan memanggil IDWriteFontDownloadQueue::BeginDownload.  

Ketika pengunduhan selesai, terserah aplikasi untuk mengambil tindakan yang sesuai — melanjutkan operasi yang tertunda, atau operasi berulang yang dilakukan awalnya dengan font fallback. (Jika tata letak teks DirectWrite sedang digunakan, maka IDWriteTextLayout3::InvalidateLayout dapat digunakan untuk menghapus hasil sementara yang dihitung menggunakan font fallback.) Agar aplikasi diberi tahu ketika proses pengunduhan telah selesai dan untuk mengambil tindakan yang sesuai, aplikasi harus memberikan implementasi antarmukaIDWriteFontDownloadListener, dan meneruskan ini ke dalam panggilan BeginDownload. 

Penting

Catatan keamanan / performa: Ketika upaya dilakukan untuk mengambil font jarak jauh, tidak ada jaminan bahwa Windows akan menerima respons dari server. Jika server tidak merespons, Windows pada akhirnya akan kehabisan waktu, meskipun ini mungkin memakan waktu beberapa menit jika beberapa font jarak jauh diambil tetapi gagal. Panggilan BeginDownload akan segera kembali. Aplikasi tidak boleh memblokir UI saat menunggu IDWriteFontDownloadListener::D ownloadCompleted dipanggil. 

 

Contoh implementasi interaksi ini dengan antrean unduhan font DirectWrite dan antarmukaIDWriteFontDownloadListener dapat dilihat dalam sampel DirectWrite Custom Font Sets, dan juga dalam sampel DirectWrite Downloadable Fonts

Membuat kumpulan font kustom menggunakan data font yang dimuat ke dalam memori

Sama seperti operasi tingkat rendah untuk membaca data dari file font berbeda untuk file pada disk lokal versus file jarak jauh di Web, hal yang sama juga berlaku untuk data font yang dimuat ke dalam buffer memori. Antarmuka tingkat rendah baru untuk menangani data font dalam memori telah ditambahkan di Windows 10 Creators Update, IDWriteInMemoryFontFileLoader

Seperti halnya pemuat file font jarak jauh, pemuat file font dalam memori harus terlebih dahulu didaftarkan dengan pabrik DirectWrite. Loader harus dipegang oleh aplikasi selama font yang terkait dengannya digunakan. Setelah font tidak lagi digunakan, dan pada titik tertentu sebelum pabrik dihancurkan, loader harus tidak terdaftar. Ini dapat dilakukan di destruktor untuk kelas yang memiliki objek loader. Langkah-langkah ini akan ditunjukkan di bawah ini. 

Jika aplikasi memiliki informasi terpisah tentang wajah font yang diwakili oleh data, aplikasi dapat menambahkan referensi wajah font individual ke penyusun kumpulan font dengan properti kustom yang ditentukan. Karena data font berada dalam memori lokal, namun, ini tidak diperlukan; DirectWrite akan dapat membaca data secara langsung untuk mendapatkan nilai properti. 

DirectWrite mengasumsikan data font dalam format mentah, OpenType, setara dengan file OpenType (.ttf, .otf, .ttc, .otc), tetapi dalam memori daripada pada disk. Data tidak boleh dalam format kontainer WOFF atau WOFF2. Data dapat mewakili Koleksi Font OpenType. Jika properti kustom tidak digunakan, maka metode IDWriteFontSetBuilder1::AddFontFile dapat digunakan untuk menambahkan semua wajah font dalam data dalam satu panggilan. 

Pertimbangan penting untuk skenario dalam memori adalah masa pakai data. Jika penunjuk ke buffer disediakan untuk DirectWrite tanpa indikasi yang jelas bahwa ada pemilik, maka DirectWrite akan membuat salinan data ke dalam buffer memori baru yang akan dimilikinya. Untuk menghindari penyalinan data dan alokasi memori tambahan, aplikasi dapat meneruskan objek pemilik data yang mengimplementasikan IUnknown, dan yang memiliki buffer memori yang berisi data font. Dengan menerapkan antarmuka ini, DirectWrite dapat menambahkan ke jumlah ref objek, sehingga memastikan masa pakai data yang dimiliki. 

Metode untuk membuat kumpulan font kustom menggunakan data font dalam memori adalah sebagai berikut; ini memerlukan Pembaruan Pembuat Windows 10. Ini akan mengasumsikan objek pemilik data yang diimplementasikan aplikasi, yang mengimplementasikan IUnknown dan juga memiliki metode yang mengembalikan penunjuk ke buffer memori dan ukuran buffer. 

1. Buat antarmuka IDWriteFactory5, seperti yang ditunjukkan di atas. 2. Buat antarmuka [**IDWriteFontSetBuilder1**](/windows/win32/api/dwrite_3/nn-dwrite_3-idwritefontsetbuilder1), seperti yang ditunjukkan di atas. 3. Gunakan pabrik untuk mendapatkan IDWriteInMemoryFontFileLoader. 
 IDWriteInMemoryFontFileLoader* pInMemoryFontFileLoader; 
if (SUCCEEDED(hr)) 
{ 
    hr = pDWriteFactory->CreateInMemoryFontFileLoader(&pInMemoryFontFileLoader); 
}

Ini mengembalikan implementasi yang disediakan sistem dari antarmuka pemuat file font dalam memori. 
4. Daftarkan pemuat file font dalam memori dengan pabrik. 

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

 
5. Untuk setiap file font dalam memori, gunakan pemuat file font dalam memori untuk membuat 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. Tambahkan objekIDWriteFontFile ke penyusun set font menggunakan metodeaddFontFile, seperti yang ditunjukkan di atas.  Jika ada kebutuhan, aplikasi dapat membuat objekIDWriteFontFaceReferenceindividu berdasarkan IDWriteFontFile, secara opsional menentukan properti kustom untuk setiap referensi wajah font, lalu menambahkan referensi wajah font dengan properti kustom ke kumpulan font menggunakan metode AddFontFaceReference, seperti yang ditunjukkan di atas. 
7. Setelah semua font ditambahkan ke penyusun kumpulan font, buat kumpulan font kustom, seperti yang ditunjukkan di atas. 
8. Pada titik tertentu ketika font dalam memori tidak akan lagi digunakan, batalkan pendaftaran pemuat file font dalam memori. 

hr = pDWriteFactory->UnregisterFontFileLoader(pInMemoryFontFileLoader);

 

Skenario tingkat lanjut

Beberapa aplikasi mungkin memiliki persyaratan khusus yang memerlukan pemrosesan yang lebih canggih daripada yang dijelaskan di atas. 

Menggabungkan kumpulan font

Beberapa aplikasi mungkin perlu membuat kumpulan font yang terdiri dari beberapa kombinasi item dari kumpulan font lainnya. Misalnya, aplikasi mungkin ingin membuat kumpulan font yang menggabungkan semua font yang diinstal pada sistem dengan pilihan font kustom, atau yang menggabungkan font yang diinstal yang cocok dengan kriteria tertentu dengan font lain. DirectWrite memiliki API untuk mendukung manipulasi dan menggabungkan kumpulan font. 

Untuk menggabungkan dua set font atau lebih, metode IDWriteFontSetBuilder::AddFontSet menambahkan semua font dalam font tertentu yang diatur untuk ditambahkan ke penyusun kumpulan font dalam satu panggilan. Jika hanya font tertentu dari kumpulan font yang ada yang diinginkan dalam kumpulan font baru, metode IDWriteFontSet::GetMatchingFonts dapat digunakan untuk mendapatkan objek kumpulan font baru yang telah difilter untuk menyertakan hanya font yang cocok dengan properti yang ditentukan. Metode ini menyediakan cara mudah untuk membuat kumpulan font kustom yang menggabungkan font dari dua atau beberapa set font yang ada

Menggunakan data font WOFF atau WOFF2 lokal

Jika aplikasi memiliki file font di sistem file lokal atau di buffer memori, tetapi mereka menggunakan format kontainer WOFF atau WOFF2, DirectWrite (Pembaruan Pembuat Windows 10 atau yang lebih baru) menyediakan metode untuk membongkar format kontainer, IDWriteFactory5::UnpackFontFile, yang mengembalikan IDWriteFontFileStream

Namun, aplikasi akan membutuhkan cara untuk mendapatkanIDWriteFontFileStreamke dalam objek pemuat file font. Salah satu cara untuk melakukan ini adalah dengan membuat implementasi IDWriteFontFileLoader kustom yang membungkus aliran. Seperti halnya pemuat file font lainnya, ini harus didaftarkan sebelum digunakan, dan tidak terdaftar sebelum pabrik keluar dari cakupan.  

Jika loader kustom juga akan digunakan dengan file font mentah (tidak dikemas), aplikasi juga perlu memberikan implementasi kustom antarmuka IDWriteFontFileStream untuk menangani file-file tersebut. Namun, ada cara lebih mudah yang menggunakan API yang dibahas di atas untuk menangani file font mentah. Kebutuhan akan implementasi aliran kustom dapat dihindari dengan menggunakan jalur kode terpisah untuk file font yang dikemas versus file font mentah. 

Setelah objek pemuat file font kustom dibuat, data file font yang dikemas ditambahkan ke loader dengan cara khusus aplikasi. Loader dapat menangani beberapa file font, yang masing-masing diidentifikasi menggunakan kunci yang ditentukan aplikasi yang buram ke DirectWrite. Setelah file font yang dikemas ditambahkan ke loader, metode IDWriteFactory::CreateCustomFontFileReference digunakan untuk mendapatkanIDWriteFontFileberdasarkan loader tersebut untuk data font yang diidentifikasi oleh kunci tertentu.  

Pembongkaran aktual data font dapat dilakukan karena font ditambahkan ke loader, tetapi juga dapat ditangani di IDWriteFontFileLoader::CreateStreamFromKey metode, yang akan dipanggil DirectWrite ketika pertama kali perlu membaca data font. 

Setelah objek IDWriteFontFile dibuat, langkah-langkah yang tersisa untuk menambahkan font ke kumpulan font kustom akan seperti yang dijelaskan di atas. 

Implementasi menggunakan pendekatan ini diilustrasikan dalam sampel DirectWrite Custom Font Sets

Menggunakan mekanisme font jarak jauh DirectWrite dengan implementasi jaringan tingkat rendah kustom

Mekanisme DirectWrite untuk menangani font jarak jauh dapat dibagi menjadi mekanisme tingkat yang lebih tinggi — memiliki set font yang mencakup referensi wajah font untuk font jarak jauh, memeriksa lokalitas data font, dan mengelola antrean untuk permintaan unduhan font — dan mekanisme tingkat bawah yang menangani unduhan aktual. Beberapa aplikasi mungkin ingin menggunakan mekanisme font jarak jauh tingkat lebih tinggi, tetapi juga memerlukan interaksi jaringan kustom, seperti berkomunikasi dengan server menggunakan protokol selain HTTP. 

Untuk situasi ini, aplikasi perlu membuat implementasi kustom antarmuka IDWriteRemoteFontFileLoader yang berinteraksi dengan antarmuka tingkat bawah lainnya dengan cara yang diperlukan. Aplikasi ini juga perlu menyediakan implementasi kustom antarmuka tingkat bawah ini: IDWriteRemoteFontFileStream, dan IDWriteAsyncResult. Ketiga antarmuka ini memiliki metode panggilan balik yang akan dipanggil DirectWrite selama operasi pengunduhan. 

Ketika IDWriteFontDownloadQueue::BeginDownload dipanggil, DirectWrite akan membuat kueri ke pemuat file font jarak jauh tentang lokalitas data, dan akan meminta aliran jarak jauh. Jika data tidak lokal, maka data akan memanggil metode BeginDownload aliran. Implementasi aliran tidak boleh memblokir panggilan tersebut, tetapi harus segera kembali, meneruskan kembali objekIDWriteAsyncResultyang menyediakan handel tunggu yang akan digunakan DirectWrite untuk menunggu operasi pengunduhan asinkron. Implementasi aliran kustom bertanggung jawab untuk menangani komunikasi jarak jauh. Ketika peristiwa penyelesaian telah terjadi, maka DirectWrite akan memanggil IDWriteAsyncResult::GetResult untuk menentukan hasil operasi. Jika hasilnya berhasil, maka diharapkan bahwa ReadFragment berikutnya memanggil ke aliran untuk rentang yang diunduh akan berhasil. 

Penting

Catatan keamanan/ performa: Ketika upaya dilakukan untuk mengambil font jarak jauh, potensi ada secara umum bagi penyerang untuk meniru server yang dimaksudkan yang dipanggil, atau bahwa server mungkin tidak merespons. Jika Anda menerapkan interaksi jaringan kustom, Anda mungkin memiliki kontrol yang lebih besar atas mitigasi daripada saat berhadapan dengan server pihak ketiga. Namun, terserah Anda untuk mempertimbangkan mitigasi yang sesuai untuk menghindari pengungkapan informasi atau penolakan layanan. Protokol aman seperti HTTPS disarankan. Selain itu, Anda harus membangun dalam beberapa waktu habis sehingga handel peristiwa yang dikembalikan ke DirectWrite akhirnya diatur. 

 

Skenario pendukung pada versi Windows sebelumnya

Skenario yang telah dijelaskan dapat didukung di DirectWrite pada versi Windows sebelumnya, tetapi akan memerlukan lebih banyak implementasi kustom pada bagian aplikasi menggunakan API yang lebih terbatas yang tersedia sebelum Windows 10. Untuk informasi selengkapnya, lihat Koleksi Font Kustom (Windows 7/8).