Каков самый быстрый способ рисования форматированного текста в Win32 API?

Я использую текстовый редактор на С++, используя API-интерфейс Vanilla Win32, и я пытаюсь найти лучший способ реализовать подсветку синтаксиса. Я знаю, что существуют существующие элементы управления, такие как сцинтилля, но я делаю это для удовольствия, поэтому я хочу сам сделать большую часть работы. Я также хочу, чтобы он был быстрым и легким.

Из того, что я узнал до сих пор, похоже, что самый низкий уровень для рисования текста в GDI - это функция TextOut. Однако, если мне нужно продолжать менять цвет шрифта, значит, мне нужно будет сделать много звонков на TextOut, чтобы нарисовать один текст со смешанным форматированием. Это неэффективно? Когда реализованы подсветка синтаксиса и расширенные текстовые элементы управления, могут ли они использовать TextOut за кулисами или есть какой-то другой способ? Является ли каждый другой метод рисования текста в GDI только оболочкой более высокого уровня вокруг TextOut?

Ответ 1

Оба DrawText и TextOut являются оболочками для ExtTextOut, поэтому ExtTextOut является низкоуровневым API. По моему опыту, ExtTextOut довольно быстро, поэтому я сомневаюсь, что вы увидите проблемы с производительностью с самим ExtTextOut. Однако создание/выбор шрифтов может быть источником проблем с производительностью, поэтому, если вы переключаетесь между шрифтами, вы можете добиться значительного прироста производительности за счет кеширования и повторного использования шрифтов (HFONT), а не CreateFont/SelectObject/DeleteObject каждый раз. В принципе, при первом вызове SelectObject после создания нового шрифта Windows выполнит процесс сопоставления шрифтов, чтобы найти лучший физический шрифт для запрошенного логического шрифта. Это довольно сложный процесс, поэтому вы хотите свести к минимуму количество раз, которое происходит в ситуациях, когда производительность важна.

Я много лет назад разработал богатый редактор для редактирования, который по сути был мини-версией Microsoft Word. Я использовал ExtTextOut как основную рабочую лошадь для всего вывода текста. Элемент управления будет хранить кеш шрифта из последних используемых шрифтов (размер кеша по умолчанию - 10 шрифтов). Он поддерживал макет WYSIWYG, поэтому он фактически выполнял всю компоновку с использованием DC и шрифтов принтера, а затем отображал совместимую с экраном версию с использованием экрана DC и подобных шрифтов, поэтому было много дополнительной работы, которая, вероятно, не применима к ваша ситуация. Несмотря на это, производительность была отличной работой на типичном аппаратном обеспечении того времени (например, 266 МГц Pentium).

Ответ 2

Вместо того, чтобы рассматривать, какая функция "рисовать текст" является самой быстрой, вероятно, гораздо более выгодно рассмотреть "Как я могу свести к минимуму объем текста, который я должен отображать вообще", будучи умным о том, что нужно перерисовать/аннулировать как текстовые изменения, или как можно кэшировать выделенный текст для прокрутки.

Ответ 3

Для сложного использования вы, вероятно, хотите DrawText, поскольку он дает вам больше контроля, чем TextOut. Он имеет некоторую базовую поддержку форматирования, но меньше, чем вам понадобится для редактора. Следующим шагом будет редактор расширенного текста из общей библиотеки управления, который в значительной степени позаботится обо всем этом для вас.