Delphi World - Дополнительное выравнивание пропорциональных шрифтов
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Дополнительное выравнивание пропорциональных шрифтов

Оформил: DeeCo

Автор: Михаил Рудаков

Введение

Одним из недостатков TTF-формата является то, что ширина каждого символа является фиксированной величиной. То есть, ширина задана создателем шрифта для каждого конкретного символа и не зависит от его положения в тексте.

Это неизбежно порождает эффект неравномерности при выводе текста на экран, которое не замечает большинство рядовых пользователей, но хорошо известный дизайнерам. Введите, например, в Word-е следующий текст:

"AVALLOOOOOLTLTLTL"

Обратите внимание, что видимое расстояние между буквами A и V заметно больше, чем между соседними O. С точки зрения компьютера все в порядке - грубо говоря, Windows считает межсимвольным расстоянием резницу между самой правой точкой предыдущего символа и самой левой текущего. Но с точки зрения дизайна - это помарка, которую стандартными средствами исправить невозможно или очень сложно (вручную регулировать межсимвольный интервал в Word-e).
К слову сказать, Adobe Photoshop пытается бороться с этим явлением (опция "Auto Kerning"), но не всегда у него получается то, что надо. Например, для Arial приведенный выше текст будет выглядеть хорошо, для Times - не очень и даже "очень не".

Как решить

В прикладных задачах неровности шрифта можно исправить хотя бы частично, если рассчитывать и запоминать расстояния между каждыми парами символов.

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

Примечание: компонент написан под библиотеку KOL (1.55), но может быть легко портирован и под VCL, так как разницы в их работе в данном случае немного.

Пример работы компонента:

Две верхние строчки напечатаны с дополнительны выравниванием, две нижние - стандартными средствами. Очевидно, что видимые расстояния между символами стали выглядеть гораздо лучше.

Объекты и процедуры модуля FineFont

TFineFont
- объект, в котором хранятся данные о межсимвольных расстояниях. Он же производит расчет расстояний и печать выравненного текста. Объект статический
SetMinDistance
- процедура установки межсимвольного расстояния. Может и должна вызываться перед инициализацией шрифта.
AssignFont
- настройка компонента на готовую канву. Шрифт канвы должен быть заранее проинициализирован. Внимание - шрифт канвы не должен быть растровым!

Надо заметить, что настройка компонента на новый шрифт происходит довольно медленно, несмотря на все оптимизации. Для символьного набора из 52 символов (английские заглавные + строчные буквы) инициализация идет 5 секунд на PII-233. Также очень сильно влияет и размер символов. Для ускорения работы следует как можно сильнее сжать символьный набор, исключить символы c вертикальными линиями по бокам - O, M, N, W и так далее.

Но есть и другой способ:
AssignFontEx
- настройка компонента с помощью сохраненных заранее параметров. Естественно, следует следить, чтобы настройки канвы в момент инициализации компонента совпадали с теми, которые вы сохранили когда-то с помощью процедуры SaveSettings.
SaveSettings
- сохраняет данные о символьном наборе и межсимвольных расстояниях в файл на диске.
TextOut
- печатает текст на заданной при вызове AssignFont канве. Аналог соответствующей функции TCanvas. Отличие в том, что эта функция не очищает фон перед печатью. В передаваемой строке могут содержаться символы, не входящие в символьный набор, заданный при вызове AssignFont. Они будут выводиться стандартным способом.
CloseFont
- освобождение занятой памяти. Процедура должна быть вызвана перед следующим вызовом AssignFont.

P.S.
Что касается развития компонента. Можно подумать о том, чтобы при настройке отсеивать несколько крайних точек символа, поскольку засечки на буквах в шрифтах типа Times "мешаются под ногами" и увеличивают видимое расстояние между символами.

Скачать пример: Fonts.zip (35K)
Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования