Мне нужно преобразовать некоторые подпрограммы рендеринга текста в растровые изображения в существующем коде C ++, использующем GDI и GDI + для использования DirectWrite (требуется поддержка CFF и поддержка OTF-функций).
Я новичок в DirectWrite. Потратив некоторое время на исследование того, что требуется для миграции существующей функциональности и создания прототипов, я столкнулся с проблемой:
Моя проблема в том, что DirectWrite (из коробки) не поддерживает интервал между символами настройка (которая является обязательной для существующего приложения), по крайней мере, не для Windows 7. Я знаю, что она поставляется с Windows 8, но другое требование для этого существующего приложения — это, к сожалению, запуск на Windows 7.
Что я обнаружил в своих исследованиях, так это то, что путь к реализации, по-видимому, заключается в реализации собственного текстового макета DirectWrite, но я не нашел хорошего руководства о том, как это сделать, особенно в отношении расстояния между символами (документация / примеры по MSDN в отношении того, как создать пользовательский текстовый макет, немного расплывчаты на мой вкус).
Как я полагаю, это должно было быть сделано раньше, прежде чем потратить дни и / или недели исследований и разработок на повторное изобретение колеса, кто-нибудь здесь знает пример реализации текстового макета DirectWrite с пользовательским межсимвольным интервалом, который я мог бы использовать в качестве начального точка или учебник?
Update1: Не ответ, но — я обнаружил, что интерфейс IDWriteTextLayout1 (который поддерживает настройку символьных пространств) поставляется не только с Windows 8, но также с «Обновлением платформы Windows 7 для SP1» (KB 2670838) в Windows 7., как я могу требует, чтобы приложение работало правильно, это решает мою проблему, хотя и не отвечает на мой вопрос.
Пользовательский макет довольно сложен из-за биди и переноса строк, а также необходимости вызывать API более низкого уровня, но пример здесь [https://msdn.microsoft.com/en-us/library/windows/desktop/dd941711(v=vs.85).aspx]. Что касается межсимвольного интервала, как только вы получите массив глифов, продвигающихся назад от процесса формирования (IDWriteTextAnalyzer :: GetGlyphs), просто добавьте дельту ко всем авансам. В связанном примере SDK вы бы добавили for
петля внутри FlowLayout::ShapeGlyphRuns
так что это происходит перед переносом строки и рисованием.
STDMETHODIMP FlowLayout::ShapeGlyphRuns(IDWriteTextAnalyzer* textAnalyzer)
{
...
hr = ShapeGlyphRun(textAnalyzer, runIndex, glyphStart);
...
// Add additional character spacing to each trailing edge of each glyph.
for (auto& advance : glyphAdvances_)
{
advance += 5.0f;
}
...
}
Обратите внимание на API ApplyCharacterSpacing
был также добавлен в Windows 8, что более надежно, чем добавление его вручную, потому что он рассматривает более сложные сценарии с несколькими глифами на кластер (но, конечно, если у вас есть этот API, то у вас уже есть IDWriteTextLayout::SetCharacterSpacing
).