Yoksel: 20071208ЧемПлохаФункцияDrawText ...
SourceForge.net Logo

Home Page | Изменения / НовыеКомментарии / Справка / Помочь проекту | Вход:  Пароль:  

Блог Чем плоха функция DrawText?


Есть в Win API? такая замечательная функция Draw Text?. Замечательная без кавычек. Дает возможность отрисовать целый блок текста с учетом различных параметров: горизонтальное и вертикальное выравнивание, перенос по словам, с учетом табуляций и т.д. Еще эта функция позволяет рассчитать ширину/высоту прямоугольника, в который влезает переданный текст.


Чем же она плоха? Как ни странно, плоха она малым количеством предоставляемых возможностей. Казалось бы, реализуем недостающие возможности, а для всего остального будем использовать Draw Text?. На практике получается так, что, реализуя недостающие возможности, приходим к тому, что необходимость использования Draw Text? вообще отпадает.


Все началось с необходимости реализовать режим вывода текста с горизонтальным выравниванием «по ширине» («justified»). Draw Text? здесь нам помочь не может – такой режим вывода не предусмотрен. Значит приходим к тому, что текст надо вручную разбивать на строки и выводить каждую строку отдельно при помощи сочетаний функций SetTextJustification/ExtTextOut. На этом этапе отваливается необходимость использования Draw Text? для вычисления высоты прямоугольника с текстом.


Как раньше работала загрузка mxl-файла? Конвертером создаем документ Йокселя. Далее происходит обход всех строк документа и вычисление высоты каждой строки при помощи Draw Text?. Таким образом вычислялась высота документа в целом и это позволяло реализовать «умную» прокрутку – корректное отображение размера ползунка и плавное перемещение по документу (а не рывками по несколько строк как в Мокселе). Впрочем прокрутка – это отдельная тема, про которую напишу как-нибудь позже. Как происходит загрузка теперь? Раз мы все равно бьем текст на строки вручную, то высоту строки табличного документа мы можем рассчитать очень просто: умножить количество строк на высоту одной строки. Что это дало? Это дало ускорение обсчета листа в три раза. Раньше документ размером 80Мб и 136 тыс. строк загружался за 29 секунд: 8 секунд – парсинг файла, 21 секунда – расчет высоты документа. Теперь документ загружается за 15 секунд: 8 секунд – парсинг файла, 7 секунд – расчет высоты.


Далее. Есть определенная сложность с отрисовкой текста с горизонтальным выравниванием по центру. Рассмотрим, например, такую табличку:
CentredText.png


Здесь в первой строке в третьей ячейке расположен центрированный текст. Как должен рисоваться центрированный текст? Мы должны найти свободные места слева и справа от ячейки и использовать все доступные свободные ячейки. Проблема здесь в том, что слева и справа длина свободного места может быть различной. Что мы и видим во второй строке, где слева от центрированной ячейки добавлена непустая ячейка. Поэтому для отрисовки центрированного текста Draw Text? использовать проблематично. Draw Text? будет рисовать текст с центрированием по тому прямоугольнику, что мы ей передадим. А у нас центр текста находится совсем не в центре прямоугольника. В примере выше этот центр «смещен влево». Зато отрисовка подобных вещей прекрасно ложится на Ext Text Out? с клиппингом.


Остальные возможности, которые может дать Draw Text? (выравнивание слева/справа, например), просто элементарно реализуются с использованием тех примитивов, которые пришлось создать для решения вышеуказанных проблем. А впихивание Draw Text? «любой ценой» приводит только к усложнению кода.


В общем, в Йокселе Draw Text? больше не используется. Это, конечно, не значит, что эту функцию вообще никогда не надо использовать. Просто это означает, что как только требуются более-менее сложные алгоритмы отрисовки текста, Draw Text? становится бесполезной. К сожалению, «волшебной» функции, которая сделает все, что надо за один вызов в Win API? не оказалось...


Ссылок на эту страницу нет


 
Файлов нет. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]