Общие сведения о DWriteCore
DWriteCore — это Windows App SDK реализация DirectWrite (DirectWrite — это API DirectX для высококачественной отрисовки текста, шрифтов структуры, не зависящих от разрешения, а также полной поддержки текста и макета в Юникоде). DWriteCore — это форма DirectWrite, которая выполняется в версиях Windows до Windows 10, версия 1809 (10.0; Сборка 17763). DWriteCore реализует тот же API, что и DirectWrite, с несколькими дополнениями, как описано в этом разделе.
В этом вводном разделе описывается, что такое DWriteCore, а также показано, как установить его в среде разработки и программировать с ним.
Для приложения, которое уже использует DirectWrite, переключение на DWriteCore требует минимальных изменений:
- Добавьте ссылку на пакет Windows App SDK.
- Включите
dwrite_core.h
вместоdwrite_3.h
. - Ссылка
DWriteCore.lib
вместоDWrite.lib
. - Вызовите DWriteCoreCreateFactory вместо DWriteCreateFactory.
В свою очередь, приложение получает преимущества Windows App SDK, а именно доступ к новейшим API и функциональным возможностям независимо от того, какая версия Windows используется вашим клиентом.
Совет
Описание и ссылки на компоненты DirectX в активной разработке см. в записи блога Целевая страница DirectX.
Ценностное предложение DWriteCore
DirectWrite поддерживает широкий набор функций, что делает его средством отрисовки шрифтов в Windows для большинства приложений, будь то через прямые вызовы или Direct2D. DirectWrite включает в себя не зависят от устройства систему разметки текста, высококачественную субпиксельную отрисовку текста Microsoft ClearType, аппаратное ускорение текста, многоформатный текст, расширенные функции типографии OpenType®, широкую языковую поддержку, а также макет и отрисовку, совместимые с GDI. DirectWrite была доступна с windows Vista с пакетом обновления 2 (SP2) и на протяжении многих лет развивалась и включала в себя более сложные функции, такие как переменные шрифты, которые позволяют применять стили, весы и другие атрибуты к шрифту только с одним ресурсом шрифта.
Однако из-за длительного срока существования DirectWrite прогресс в разработке, как правило, оставляет старые версии Windows позади. Кроме того, статус DirectWrite в качестве технологии отрисовки текста в высшей степени ограничен Только Windows, в результате чего кроссплатформенные приложения могут создавать собственные стеки отрисовки текста или полагаться на сторонние решения.
DWriteCore решает фундаментальные проблемы, связанные с отсутствием функций версии и кроссплатформенной совместимостью, путем удаления библиотеки из системы и нацеливания на все возможные поддерживаемые конечные точки. Для этого мы интегрировали DWriteCore в Windows App SDK.
Основное значение, которое DWriteCore предоставляет вам как разработчику в Windows App SDK, заключается в том, что он предоставляет доступ ко многим (и, в конечном итоге, ко всем) DirectWrite функциям. Все функции DWriteCore будут работать одинаково во всех версиях нижнего уровня без каких-либо различий в том, какие функции могут работать с теми или иными версиями.
Демонстрационное приложение DWriteCore — DWriteCoreGallery
DWriteCore демонстрируется с помощью примера приложения DWriteCoreGallery , которое доступно для скачивания и изучения.
Начало работы с DWriteCore
DWriteCore является частью Windows App SDK. В этом разделе описывается настройка среды разработки для программирования с помощью DWriteCore.
Установка инструментов для Windows App SDK
См. статью Установка инструментов для Windows App SDK.
Создание проекта
В Visual Studio создайте проект на основе шаблона проекта Пустое приложение, упакованной (WinUI 3 в классической версии). Этот шаблон проекта можно найти, выбрав язык C++; платформа: Windows App SDK; тип проекта: Desktop.
Дополнительные сведения см. в разделе Шаблоны проектов для WinUI 3.
Установка пакета NuGet Microsoft.ProjectReunion.DWrite
В Visual Studio щелкните Проект>Управление пакетами NuGet...>Найдите, введите или вставьте Microsoft.ProjectReunion.DWrite в поле поиска, выберите элемент в результатах поиска и нажмите кнопку Установить , чтобы установить пакет для этого проекта.
Кроме того, начните с примера приложения DWriteCoreGallery.
Кроме того, вы можете программируйте с помощью DWriteCore, начав с примера проекта приложения DWriteCoreGallery и основываясь на этом проекте. Затем вы можете удалить любой существующий исходный код (или файлы) из этого примера проекта и добавить любой новый исходный код (или файлы) в проект.
Использование DWriteCore в проекте
Дополнительные сведения о программировании с помощью DWriteCore см. в разделе Программирование с помощью DWriteCore далее в этом разделе.
Этапы выпуска DWriteCore
Перенос DirectWrite в DWriteCore достаточно большой проект для нескольких циклов выпуска Windows. Этот проект разделен на этапы, каждый из которых соответствует блоку функциональных возможностей, предоставляемых в выпуске.
Функции в текущем выпуске DWriteCore
DWriteCore является частью Windows App SDK. Он содержит основные средства, необходимые разработчику для использования DWriteCore, включая следующие функции.
- Перечисление шрифтов.
- API шрифтов.
- Формировании.
- Низкоуровневые API отрисовки. Это частично на текущем этапе. DWriteCore не взаимодействует с Direct2D, но вы можете использовать IDWriteGlyphRunAnalysis и IDWriteBitmapRenderTarget.
- Основные функции разметки текста.
- API-интерфейсы отрисовки текста.
- Целевой объект отрисовки точечного рисунка.
- Цветные шрифты.
- Прочие оптимизации (очистка кэша шрифтов, загрузчик шрифтов в памяти и т. д.).
- Поддержка подчеркивания см. в разделах IDWriteTextLayout::GetUnderline и IDWriteTextLayout::SetUnderline.
- Поддержка зачеркиваний — см . в разделах IDWriteTextLayout::GetStrikethrough и IDWriteTextLayout::SetStrikethrough.
- Поддержка вертикального текста с помощью IDWriteTextLayout — см. раздел Вертикальный текст.
- Реализованы все методы интерфейсов IDWriteTextAnalyzer и IDWriteTextAnalyzer1 .
Функция баннера — цветные шрифты. Цветовые шрифты позволяют визуализировать шрифты с более сложной цветовой функциональностью, чем простые одинарные цвета. Например, цветные шрифты позволяют визуализировать шрифты эмодзи и значков панели инструментов (например, последний из которых используется Office). Цветовые шрифты впервые появились в Windows 8.1, но эта функция была значительно расширена в Windows 10 версии 1607 (юбилейное обновление).
Работа по очистке кэша шрифтов и загрузчика шрифтов в памяти позволяют ускорить загрузку шрифтов и улучшить память.
С помощью этих функций вы можете сразу же приступить к использованию некоторых современных основных функций DirectWrite, таких как переменные шрифты. Переменные шрифты являются одной из наиболее важных функций для клиентов DirectWrite.
Наше приглашение вам в качестве разработчика DirectWrite
DWriteCore вместе с другими компонентами Windows App SDK будет разрабатываться с готовностью к отзывам разработчиков. Мы приглашаем вас начать изучение DWriteCore и предоставить аналитические сведения или запросы о разработке функций в нашем репозитории Windows App SDK GitHub.
Программирование с помощью DWriteCore
Как и в случае с DirectWrite, вы программируете с помощью DWriteCore через ИНТЕРФЕЙС COM-light через интерфейс IDWriteFactory.
Чтобы использовать DWriteCore, необходимо включить файл заголовка dwrite_core.h
.
// pch.h
...
// DWriteCore header file.
#include <dwrite_core.h>
Файл dwrite_core.h
заголовка сначала определяет DWRITE_CORE маркера, а затем включает файл заголовка dwrite_3.h
. Маркер DWRITE_CORE важен, так как он направляет все последующие включенные заголовки, чтобы сделать все DirectWrite API доступными для вас. После включения dwrite_core.h
в проект можно написать код, выполнить сборку и запуск.
Api, которые являются новыми или отличными для DWriteCore
Поверхность API DWriteCore в значительной степени такая же, как и для DirectWrite. Но есть небольшое количество новых API, которые в настоящее время находятся только в DWriteCore.
Создание объекта фабрики
Функция DWriteCoreCreateFactory free создает объект фабрики, который используется для последующего создания отдельных объектов DWriteCore.
Функция DWriteCoreCreateFactory совпадает с функцией DWriteCreateFactory, экспортируемой системной версией DirectWrite. Функция DWriteCore имеет другое имя, чтобы избежать неоднозначности.
Создание объекта ограниченной фабрики
Перечисление DWRITE_FACTORY_TYPE имеет новую константу — DWRITE_FACTORY_TYPE_ISOLATED2, указывающую на ограниченную фабрику. Ограниченная фабрика больше заблокирована, чем изолированная фабрика. Он никак не взаимодействует с межпроцессным или постоянным кэшем шрифтов. Кроме того, системная коллекция шрифтов, возвращенная этой фабрикой, включает только хорошо известные шрифты. Вот как можно использовать DWRITE_FACTORY_TYPE_ISOLATED2 для создания объекта ограниченной фабрики при вызове функции DWriteCoreCreateFactory free.
// 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())
)
);
Если вы передаете DWRITE_FACTORY_TYPE_ISOLATED2 в более раннюю версию DirectWrite, которая не поддерживает ее, DWriteCreateFactory возвращает E_INVALIDARG.
Рисование глифов в растровом рисунке системной памяти
DirectWrite имеет интерфейс целевого объекта отрисовки растрового рисунка, который поддерживает отрисовку глифов в растровом рисунке в системной памяти. Однако в настоящее время единственный способ получить доступ к базовым пиксельным данным — пройти через GDI, поэтому API не может использоваться на разных платформах. Это легко исправить, добавив метод для получения данных о пикселях.
Поэтому DWriteCore представляет интерфейс IDWriteBitmapRenderTarget2 и его метод IDWriteBitmapRenderTarget2::GetBitmapData. Этот метод принимает параметр типа (указатель на) DWRITE_BITMAP_DATA_BGRA32, который является новой структурой.
Приложение создает целевой объект отрисовки растрового изображения, вызвав IDWriteGdiInterop::CreateBitmapRenderTarget. В Windows целевой объект отрисовки точечного рисунка инкапсулирует контроллер памяти GDI с выбранным аппаратно-независимым растровым рисунком (DIB) GDI. IDWriteBitmapRenderTarget::D rawGlyphRun отрисовывает глифы в DIB. DirectWrite отрисовывает сами глифы, не проходя через GDI. Затем приложение может получить HDC из целевого объекта отрисовки растрового изображения и использовать BitBlt для копирования пикселей в окно HDC.
На платформах, отличных от Windows, приложение по-прежнему может создавать целевой объект отрисовки точечных изображений, но просто инкапсулирует системный массив памяти без HDC и DIB. Без HDC приложение должно иметь другой способ получить пиксели растрового изображения, чтобы скопировать их или использовать иным образом. Даже в Windows иногда полезно получить фактические пиксельные данные, и мы покажем, как это сделать в приведенном ниже примере кода.
// 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);
}
Другие различия API между DWriteCore и DirectWrite
Существует несколько API, которые являются либо только заглушками, либо они ведут себя несколько иначе на платформах, отличных от Windows. Например, IDWriteGdiInterop::CreateFontFaceFromHdc возвращает E_NOTIMPL на платформах, отличных от Windows, так как без GDI не существует такого понятия, как HDC.
И, наконец, существуют некоторые другие API Windows, которые обычно используются вместе с DirectWrite (примечаемым примером является Direct2D). Однако в настоящее время Direct2D и DWriteCore не взаимодействуют. Например, если создать IDWriteTextLayout с помощью DWriteCore и передать его В D2D1RenderTarget::D rawTextLayout, вызов завершится ошибкой.