Expertus metuit
Шрифты в Linux: растеризация шрифтов и библиотека Freetype
2009-03-04 19:03
Теги: linux, freetype, fonts

Эта часть посвящена библиотеке растеризации шрифтов FreeType, а также базовым принципам растеризации, в том числе субпиксельной.

Растеризация шрифтов и библиотека Freetype

Глифы (символы) в векторном шрифте хранятся не в виде набора изолированных точек, а в виде математического описания контуров. Однако монитор является дискретным устройством, и чтобы отобразить на нём шрифт, его сперва следует преобразовать в растровое изображение, этот процесс называется растеризацией. Основная трудность в растеризации шрифта для отображения его на экране заключается в том, что монитор имеет довольно низкое разрешение, т.е. количество элементарных единиц изображения (пикселов) на одну единицу длины. Экран моего ноутбука имеет, например, разрешение примерно 100 пикселов на дюйм (dpi; dots per inch), разрешение же лазерного принтера составляет примерно 600 dpi. На отображение буквы высотой два миллиметра на таком экране отводится всего около восьми пикселов по ширине и высоте! И в эти шестьдесят четыре пиксела нужно смасштабировать векторное изображение глифа с наименьшими искажениями!

Рассмотрим подробно изображение одного глифа, в данном случае для символа «a» шрифта Liberation Serif, в разном разрешении.

Рис. 1

Как вы видите, глиф имеет достаточно сложную форму, высота первого символа 78 пикселов, при таком разрешении форма буквы хорошо заметна и передана сравнительно качественно. Высота последнего символа 6 пикселов, и что именно там нарисовано, разобрать практически невозможно. Хорошо видно, как с понижением количества использованных для растеризации пикселов падает общее качество картинки и «узнаваемость» формы символа. Чем больше элементов участвует в построении растрового приближения векторной картинки, тем выше качество этого самого приближения.

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

Хинты

На рисунке ниже показан фрагмент растровой сетки, а также контур ((а), круг) который нужно на этой сетке отобразить. Наложим контур на сетку и закрасим каждый пиксел, который более чем наполовину покрывается контуром (Пример взят из книги Питера Карова «Шрифтовые Технологии»).

Рис. 2

На фрагменте (б) видно, что контур очень точно наложен на сетку, в результате чего получаем симметричное и сравнительно качественное приближённое изображение круга. Но на третьем фрагменте (в) контур смещён относительно растровой сетки примерно на треть ширины пиксела вправо и вверх, что приводит к совершенно иной картине. Рассмотрим теперь другой пример — угол в 90°.

Рис. 3

На фрагменте (а) контур угла расположен так, что соответствующие пикселы образуют достаточно приличное изображение. На фрагменте (б) вместо острой вершины получилось совершенно не то, что ожидалось, хотя контур был смещён на очень незначительное расстояние.

Если теперь представить вместо круга или угла какой-нибудь сложный контур одного глифа шрифта, можно понять, почему так сложно получить на экране с небольшим разрешением достойно выглядящий образ контура глифа. В разных глифах (или даже в разных элементах одного глифа) могут встречаться повторяющиеся элементы (прямые, кривые линии, штрихи). Но эти одинаковые элементы по только что описанным причинам могут рендериться совершенно по-разному в разных местах экрана. Для улучшения ситуации в векторные шрифты добавляются специальные инструкции, позволяющие более «интеллектуально» выполнять растеризацию. Эти инструкции называются хинтами (от английского hintsподсказка). Программа растеризации может считывать хинты и использовать содержащуюся в них информацию для коррекции полученного растрового изображения.

Вот пример использования хинтов при растеризации глифа символа «а».

Рис. 4

Глиф взят из TrueType шрифта Verdana версии 2.43, отрисован размером в 21 пункт и увеличен в пять раз. Видно, что при бесхинтовой отрисовке символ содержит разнообразные артефакты, штрих неровный. При использовании хинтов картинка значительно яснее, артефактов практически нет и в целом результат растеризации отличный.

К сожалению, изготовление хинтов к TrueType шрифту — это чрезвычайно трудоёмкая операция, поэтому хинты присутствуют далеко не во всех файлах шрифтов. Это приводит к тому, что подобный шрифт отлично выглядит при печати на принтере и очень неаккуратно на экране.

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

Многие алгоритмы обработки хинтов запатентованы крупными фирмами, таким как Microsoft или Apple. В некоторых странах возможность реализации этих алгоритмов в программах ограничена и требует отчислений владельцу патента. Чтобы избежать возможных юридических проблем, в библиотеке freetype был реализован метод обработки хинтов, не затрагивающий эти патенты. От этого он, естественно, не выиграл и шрифты, отрисованные «безпатентными» алгоритмами, выглядят несколько хуже, чем «патентованными». Однако в процессе компиляции freetype эти патентованные алгоритмы можно включить, а во многих странах патенты на алгоритмы не действуют, поэтому этот процесс вполне легален. В бинарных сборках freetype из состава многих современных дистрибутивов эти алгоритмы уже включены.

Другим способом разрешить проблему с патентами на алгоритмы обработки хинтов является так называемый автохинтинг (по-английски autohint) — метод исправления дефектов растеризации без использования встроенных в шрифт инструкций. Обычно результат действия автохинтинга не намного лучше стандартного рендеринга:

Рис. 5

Монохромное сглаживание

Другим способом улучшения качества растеризации является так называемое сглаживание (по-английски anti-aliasing, также по-русски называется антиалиасингом). Как видно из названия, в этом методе используется сглаживание резких переходов от контура шрифта к фоновому цвету, в результате чего в картинке сглаживаются и маскируются ошибки растеризации. Сравните результат растеризации с использованием простого сглаживания и без оного:

Рис. 6

Такое сглаживание также называют монохромным (по-английски grayscale antialiasing), поскольку для создания эффекта плавного перехода используется цвет самого шрифта, но различной степени яркости. Как вы могли заметить, в сглаженной версии растеризованного глифа используется значительно большее количество пикселов растровой сетки, чем для растеризации глифа без сглаживания. Вернёмся немного назад, к правилам выбора пикселов, которые нужно закрасить на растровой сетке, чтобы получить образ векторного контура. Как вы помните, мы закрашивали чёрным цветом только те клетки, которые более, чем наполовину покрывались контуром глифа. Теперь же в нашем распоряжении есть множество градаций серого цвета — от белого до чёрного — и мы можем выбирать цвет пиксела в заивисимости от процента его площади, покрытой векторным контуром глифа. Следующий рисунок иллюстрирует механизм растеризации глифа с использованием сглаживания и без (на примере глифа «a», увеличенного в 20 раз).

Рис. 7

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

Логичным шагом является объединение двух упомянутых методов: использования хинтов и сглаживания. Вот как это выглядит.

Рис. 8

Субпиксельное сглаживание

Принципы формирования цветного изображения на мониторе

Цветное изображение на дисплее монитора формируется из пикселов, а каждый пиксел состоит из компонентов трёх цветов — красного, зелёного и синего (red, green, blue), каждый из таких компонентов называется субпикселом. Существует несколько различных вариантов геометрии субпикселов, самые главные из них — это: ЭЛТ телевизора, ЭЛТ монитора, жидкокристаллический экран. Субпикселы на них располагаются следующим образом:

Рис. 9

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

На LCD-экране пикселы и субпикселы располагаются в строгом геометрическом порядке: каждый пиксел имеет прямоугольную форму и состоит в свою очередь из трёх вертикально расположенных субпикселов прямоугольной формы. Таким образом, на экране размером 1024×768 пикселов физически располагается 3072×768 раздельно управляемых светящихся элементов. Во всей оставшейся части статьи мы будем говорить именно об LCD-экранах.

Изображения в данном разделе предназначены для просмотра только на LCD-мониторах, на CRT-мониторах эффект не будет совпадать с описанным!

Каждый цвет отдельного пиксела получается путём «смешивания» трёх цветов субпикселов в разных пропорциях. Пропорция задаётся уровнем яркости субпиксела. Чёрный цвет получается при полностью погашенных субпикселах, белый — при полностью включенных, чистый красный цвет получается при полностью погашенных синем и зелёном субпикселе (уровень яркости красного субпиксела при этом определяет яркость итогового красного цвета), а жёлтый цвет получается смешиванием красного и зелёного в равных пропорциях.

Рис. 10

При выбранном подходе серый цвет получается смешиванием в равных долях красного, зелёного и синего цветов субпикселов и при использовании монохромного сглаживания экран LCD-монитора при большом увеличении выглядит приблизительно так:

Рис. 11

Такой способ формирования цветного изображения позволяет добиваться интересных эффектов. Рассмотрим следующую иллюстрацию (её нужно обязательно рассматривать на LCD-мониторе):

Рис. 12

На рисунке изображены шесть параллельных линий. Первые три линии красного, зелёного и синего цвета соответственно, четвёртая белого цвета, а пятая и шестая состоят из сегментов разных цветов. В построении первых трёх линий задействовано только по одному из субпикселов, в четвёртой линии — все субпикселы, по этой причине четвёртая линия кажется визуально шире, чем первые три, хотя все они одинаковой ширины — один пиксел. Пятая линия также шириной в один пиксель, однако в каждом сегменте задействован только один субпиксел, в результате чего линия кажется неровной (физически так и есть, линия состоит из трёх сегментов, каждый из которых сдвинут вправо относительно предыдущего на один пиксель). Шестая линия имеет ширину два пиксела и состоит из двух трёхсегментных линий.

Давайте рассмотрим этот рисунок в масштабе 8:1.

Рис. 13

Вы можете сами проделать эту операцию в любом графичесок редакторе, чтобы убедиться, что на этих двух иллюстрациях представлено одинаковое изображение. Теперь рассмотрим, как это избражение рисуется на экране LCD-монитора.

Рис. 14

В верхней правой части видно, что смежными сегментами оказываются субпиксели, принадлежащие двум соседним пикселам: слева синий, справа красный. Для глаза эти два соседних сегмента сливаются в один цвет, в результате чего на экране получается линия пурпурного цвета. Также видно, откуда берётся пустой промежуток между двумя соседними линиями.

Основы субпиксельного рендеринга

Субпиксельным рендерингом в общем случае называется тип рендеринга, использующий особенности физического формирования изображения из субпикселов. А субпиксельное сглаживание базируется на особенностях человеческого зрения: на маленьких объектах глаз лучше различает контраст яркостей, чем контраст цветов. На практике это выражается в том, что экран рассматривается не как набор пикселов (как это происходит, например, в графическом редакторе), а как набор субпикселов; при этом горизонтальное разрешение экрана увеличивается втрое. После «субпиксельного» отрисовывания производится коррекция яркости субпикселов, чтобы максимально подавить видимые глазу цветные переходы.

Субпиксельное сглаживание вполне удовлетворительно работает для большинства людей, однако люди с повышенным чувством цвета могут видеть яркие цветные точки на границах отрендеренных областей.

Изначально алгоритм субпиксельного рендеринга был разработан и запатентован IBM, позднее был использован фирмой Microsoft в операционной системе Windows XP под названием ClearType. Подробнее о принципах работы субпиксельного сглаживания можно прочитать в статье википедии о ClearType.

О том, как использовать тот или иной режим сглаживания, я расскажу в последующих статьях.

Комментарии

невзоров алексей | 2009-05-30 в 13:42

Отличная статья.Прекрасные пояснения.Автор очень доступно объясняет.

Текст комментария (разметка: *курсив*, **полужирная**, [ссылка](http://example.com) или <http://example.com> ещё)
Имя (обязательно, 50 символов или меньше)
Email, на который получать ответы (не будет опубликован)
Веб-сайт
© 2006—2016 Sergey Stolyarov | Работает на Pyrone