Bagikan melalui


Gambaran umum DWriteCore

DWriteCore adalah implementasi SDK Aplikasi Windows DirectWrite (DirectWrite adalah DIRECTX API untuk penyajian teks berkualitas tinggi, font kerangka independen resolusi, dan dukungan teks dan tata letak Unicode lengkap). DWriteCore adalah bentuk DirectWrite yang berjalan pada versi Windows hingga Windows 10, versi 1809 (10.0; Bangun 17763). DWriteCore menerapkan API yang sama dengan DirectWrite, dengan beberapa penambahan seperti yang dijelaskan dalam topik ini.

Topik pengantar ini menjelaskan apa itu DWriteCore, dan menunjukkan cara menginstalnya ke lingkungan pengembangan dan program Anda dengannya.

Untuk aplikasi yang sudah menggunakan DirectWrite, beralih ke DWriteCore memerlukan perubahan minimal:

Sebagai imbalannya, aplikasi mendapatkan manfaat dari SDK Aplikasi Windows—yaitu, akses ke API dan fungsionalitas terbaru terlepas dari versi Windows apa yang dijalankan pelanggan Anda.

Tip

Untuk deskripsi dan tautan ke komponen DirectX dalam pengembangan aktif, lihat posting blog DirectX Landing Page.

Proposisi nilai DWriteCore

DirectWrite sendiri mendukung berbagai fitur yang menjadikannya alat penyajian font pilihan di Windows untuk sebagian besar aplikasi—baik itu melalui panggilan langsung, atau melalui Direct2D. DirectWrite mencakup sistem tata letak teks independen perangkat, penyajian teks Microsoft ClearType sub-piksel berkualitas tinggi, teks yang dipercepat perangkat keras, teks multiformat, fitur tipografi OpenType® tingkat lanjut, dukungan bahasa luas, serta tata letak dan penyajian yang kompatibel dengan GDI. DirectWrite telah tersedia sejak Windows Vista SP2, dan telah berevolusi selama bertahun-tahun untuk menyertakan fitur yang lebih canggih seperti font variabel, yang memungkinkan Anda menerapkan gaya, bobot, dan atribut lainnya ke font hanya dengan satu sumber daya font.

Namun, karena umur panjang DirectWrite, kemajuan dalam pengembangan cenderung meninggalkan versi Windows yang lebih lama. Selain itu, status DirectWrite sebagai teknologi penyajian teks premier hanya terbatas pada Windows, meninggalkan aplikasi lintas platform untuk menulis tumpukan penyajian teks mereka sendiri, atau untuk mengandalkan solusi pihak ketiga.

DWriteCore memecahkan masalah mendasar dari fitur versi tanpa induk dan kompatibilitas lintas platform dengan menghapus pustaka dari sistem, dan menargetkan semua titik akhir yang didukung. Untuk itu, kami telah mengintegrasikan DWriteCore ke dalam SDK Aplikasi Windows.

Nilai utama yang diberikan DWriteCore kepada Anda, sebagai pengembang, dalam SDK Aplikasi Windows adalah menyediakan akses ke banyak (dan akhirnya semua) DirectWrite fitur. Semua fitur DWriteCore akan berfungsi sama pada semua versi tingkat bawah tanpa perbedaan apa pun mengenai fitur mana yang mungkin berfungsi pada versi mana.

Aplikasi demo DWriteCore—DWriteCoreGallery

DWriteCore ditunjukkan dengan cara aplikasi sampel DWriteCoreGallery , yang tersedia untuk Anda unduh dan pelajari sekarang.

Mulai menggunakan DWriteCore

DWriteCore adalah bagian dari SDK Aplikasi Windows. Bagian ini menjelaskan cara menyiapkan lingkungan pengembangan Anda untuk pemrograman dengan DWriteCore.

Menginstal alat untuk SDK Aplikasi Windows

Lihat Menginstal alat untuk SDK Aplikasi Windows.

Membuat proyek baru

Di Visual Studio, buat proyek baru dari templat proyek Blank App, Packaged (WinUI 3 in Desktop). Anda dapat menemukan templat proyek tersebut dengan memilih bahasa: C++; platform: SDK Aplikasi Windows; jenis proyek: Desktop.

Untuk informasi selengkapnya, lihat Templat proyek untuk WinUI 3.

Menginstal paket NuGet Microsoft.ProjectReunion.DWrite

Di Visual Studio, klik Proyek>Kelola Paket NuGet...>Telusuri, ketik atau tempel Microsoft.ProjectReunion.DWrite di kotak pencarian, pilih item di hasil pencarian, lalu klik Instal untuk menginstal paket untuk proyek tersebut.

Atau, mulailah dengan aplikasi sampel DWriteCoreGallery

Atau, Anda dapat memprogram dengan DWriteCore dengan memulai dengan proyek aplikasi sampel DWriteCoreGallery , dan mendasarkan pengembangan Anda pada proyek tersebut. Anda kemudian dapat merasa bebas untuk menghapus kode sumber (atau file) yang ada dari proyek sampel tersebut, dan untuk menambahkan kode sumber baru (atau file) ke proyek.

Menggunakan DWriteCore dalam proyek Anda

Untuk informasi selengkapnya tentang pemrograman dengan DWriteCore, lihat bagian Pemrograman dengan DWriteCore nanti dalam topik ini.

Fase rilis DWriteCore

Porting DirectWrite ke DWriteCore adalah proyek yang cukup besar untuk menjangkau beberapa siklus rilis Windows. Proyek tersebut dibagi menjadi beberapa fase, yang masing-masing sesuai dengan potongan fungsionalitas yang dikirimkan dalam rilis.

Fitur dalam rilis DWriteCore saat ini

DWriteCore adalah bagian dari SDK Aplikasi Windows. Ini berisi alat dasar yang Anda, sebagai pengembang, perlu menggunakan DWriteCore, termasuk fitur-fitur berikut.

Fitur banner adalah font warna. Font warna memungkinkan Anda merender font Anda dengan fungsionalitas warna yang lebih canggih di luar warna tunggal sederhana. Misalnya, font warna adalah yang mendukung kemampuan untuk merender font ikon emoji dan toolbar (yang terakhir digunakan oleh Office, misalnya). Font warna pertama kali diperkenalkan di Windows 8.1, tetapi fitur ini sangat diperluas di Windows 10, versi 1607 (Pembaruan Hari Jadi).

Pekerjaan pembersihan cache font, dan pemuat font dalam memori, memungkinkan pemuatan font yang lebih cepat, dan peningkatan memori.

Dengan fitur-fitur ini, Anda dapat segera mulai memanfaatkan beberapa fungsi inti modern DirectWrite—seperti font variabel. Font variabel adalah salah satu fitur terpenting bagi pelanggan DirectWrite.

Undangan kami kepada Anda sebagai pengembang DirectWrite

DWriteCore, bersama dengan komponen SDK Aplikasi Windows lainnya, akan dikembangkan dengan kebukaan terhadap umpan balik pengembang. Kami mengundang Anda untuk mulai menjelajahi DWriteCore, dan untuk memberikan wawasan atau permintaan ke dalam pengembangan fitur di repositori GitHub SDK Aplikasi Windows kami.

Pemrograman dengan DWriteCore

Sama seperti DirectWrite, Anda memprogram dengan DWriteCore melalui API COM-light-nya, melalui antarmuka IDWriteFactory.

Untuk menggunakan DWriteCore, perlu menyertakan dwrite_core.h file header.

// pch.h
...
// DWriteCore header file.
#include <dwrite_core.h>

File dwrite_core.h header pertama-tama menentukan DWRITE_CORE token, lalu menyertakan dwrite_3.h file header. Token DWRITE_CORE penting, karena mengarahkan header yang kemudian disertakan untuk membuat semua API DirectWrite tersedia untuk Anda. Setelah proyek Anda menyertakan dwrite_core.h, Anda kemudian dapat melanjutkan dan menulis kode, membangun, dan menjalankan.

API yang baru, atau berbeda, untuk DWriteCore

Permukaan API DWriteCore sebagian besar sama dengan untuk DirectWrite. Tetapi ada sejumlah kecil API baru yang hanya ada di DWriteCore saat ini.

Membuat objek pabrik

Fungsi gratis DWriteCoreCreateFactory membuat objek pabrik yang digunakan untuk pembuatan objek DWriteCore individual berikutnya.

DWriteCoreCreateFactory secara fungsional sama dengan fungsi DWriteCreateFactory yang diekspor oleh versi sistem DirectWrite. Fungsi DWriteCore memiliki nama yang berbeda untuk menghindari ambiguitas.

Membuat objek pabrik terbatas

Enumerasi DWRITE_FACTORY_TYPE memiliki konstanta baru—DWRITE_FACTORY_TYPE_ISOLATED2, menunjukkan pabrik terbatas. Pabrik terbatas lebih terkunci daripada pabrik yang terisolasi. Ini tidak berinteraksi dengan silang proses atau cache font persisten dengan cara apa pun. Selain itu, koleksi font sistem yang dikembalikan dari pabrik ini hanya mencakup font terkenal. Berikut cara menggunakan DWRITE_FACTORY_TYPE_ISOLATED2 untuk membuat objek pabrik terbatas saat Anda memanggil fungsi gratis DWriteCoreCreateFactory .

// Create a factory that doesn't interact with any cross-process nor
// persistent cache state.
winrt::com_ptr<::IDWriteFactory7> spFactory;
winrt::check_hresult(
  ::DWriteCoreCreateFactory(
    DWRITE_FACTORY_TYPE_ISOLATED2,
    __uuidof(spFactory),
    reinterpret_cast<IUnknown**>(spFactory.put())
  )
);

Jika Anda meneruskan DWRITE_FACTORY_TYPE_ISOLATED2 ke versi DirectWrite yang lebih lama yang tidak mendukungnya, maka DWriteCreateFactory mengembalikan E_INVALIDARG.

Menggambar glyph ke bitmap memori sistem

DirectWrite memiliki antarmuka target render bitmap yang mendukung rendering glyph ke bitmap dalam memori sistem. Namun, saat ini satu-satunya cara untuk mendapatkan akses ke data piksel yang mendasar adalah dengan melalui GDI, sehingga API tidak dapat digunakan lintas platform. Ini mudah diperbaiki dengan menambahkan metode untuk mengambil data piksel.

Sehingga DWriteCore memperkenalkan antarmuka IDWriteBitmapRenderTarget2 , dan metodenya IDWriteBitmapRenderTarget2::GetBitmapData. Metode itu mengambil parameter jenis (penunjuk ke) DWRITE_BITMAP_DATA_BGRA32, yang merupakan struktur baru.

Aplikasi Anda membuat target render bitmap dengan memanggil IDWriteGdiInterop::CreateBitmapRenderTarget. Di Windows, target render bitmap merangkum DC memori GDI dengan bitmap independen perangkat GDI (DIB) yang dipilih ke dalamnya. IDWriteBitmapRenderTarget::D rawGlyphRun merender glyph ke DIB. DirectWrite merender glyph itu sendiri tanpa melalui GDI. Aplikasi Anda kemudian bisa mendapatkan HDC dari target render bitmap, dan menggunakan BitBlt untuk menyalin piksel ke jendela HDC.

Pada platform non-Windows, aplikasi Anda masih dapat membuat target render bitmap, tetapi hanya merangkum array memori sistem tanpa HDC dan tanpa DIB. Tanpa HDC, perlu ada cara lain bagi aplikasi Anda untuk mendapatkan piksel bitmap sehingga dapat menyalinnya, atau menggunakannya. Bahkan di Windows, terkadang berguna untuk mendapatkan data piksel aktual, dan kami menunjukkan cara saat ini untuk melakukannya dalam contoh kode di bawah ini.

// pch.h
#pragma once

#include <windows.h>
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>

// WinMain.cpp
#include "pch.h"
#include <dwrite_core.h>
#pragma comment(lib, "Gdi32")

class TextRenderer
{
    DWRITE_BITMAP_DATA_BGRA32 m_targetBitmapData;

public:
    void InitializeBitmapData(winrt::com_ptr<IDWriteBitmapRenderTarget> const& renderTarget)
    {
        // Query the bitmap render target for the new interface. 
        winrt::com_ptr<IDWriteBitmapRenderTarget2> renderTarget2;
        renderTarget2 = renderTarget.try_as<IDWriteBitmapRenderTarget2>();

        if (renderTarget2)
        {
            // IDWriteBitmapRenderTarget2 exists, so we can get the bitmap the easy way. 
            winrt::check_hresult(renderTarget2->GetBitmapData(OUT & m_targetBitmapData));
        }
        else
        {
            // We're using an older version that doesn't implement IDWriteBitmapRenderTarget2, 
            // so we have to get the bitmap by going through GDI. First get the bitmap handle. 
            HDC hdc = renderTarget->GetMemoryDC();
            winrt::handle dibHandle{ GetCurrentObject(hdc, OBJ_BITMAP) };
            winrt::check_bool(bool{ dibHandle });

            // Call a GDI function to fill in the DIBSECTION structure for the bitmap. 
            DIBSECTION dib;
            winrt::check_bool(GetObject(dibHandle.get(), sizeof(dib), &dib));

            m_targetBitmapData.width = dib.dsBm.bmWidth;
            m_targetBitmapData.height = dib.dsBm.bmHeight;
            m_targetBitmapData.pixels = static_cast<uint32_t*>(dib.dsBm.bmBits);
        }
    }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
    TextRenderer textRenderer;
    winrt::com_ptr<IDWriteBitmapRenderTarget> renderTarget{ /* ... */ };
    textRenderer.InitializeBitmapData(renderTarget);
}

Perbedaan API lainnya antara DWriteCore dan DirectWrite

Ada beberapa API yang hanya merupakan stub, atau bersifat agak berbeda pada platform non-Windows. Misalnya, IDWriteGdiInterop::CreateFontFaceFromHdc mengembalikan E_NOTIMPL pada platform non-Windows, karena tidak ada yang namanya HDC tanpa GDI.

Dan, akhirnya, ada API Windows tertentu lainnya yang biasanya digunakan bersama dengan DirectWrite (Direct2D menjadi contoh penting). Namun, saat ini, Direct2D dan DWriteCore tidak beroperasi. Misalnya, jika Anda membuat IDWriteTextLayout menggunakan DWriteCore, dan meneruskannya ke D2D1RenderTarget::D rawTextLayout, maka panggilan tersebut akan gagal.