Шрифты TrueType «изнутри».

26.03.2012

Пожалуй, самый распространённый на сегодняшний день формат шрифтов это TrueType и его расширение – OpenType. 
Стандарт TrueType разработан компанией Apple в конце 1980-х годов и представляет собой векторное описание символов шрифта, что позволяет их легко масштабировать. Файл шрифта состоит из нескольких двоичных таблиц, которые описывают различные свойства шрифта. 

Первые компьютеры Apple использовали процессоры Motorolla 68xxx, которые имели отличный от архитектуры x86 порядок байт в машинном слове. При работе непосредственно с файлом шрифтов необходимо учитывать этот факт. 

Формат OpenType обратно совместим с форматом TrueType и является его расширением. Одной из новых возможностей OpenType являются коллекции шрифтов (расширение .ttc). Коллекция описывает несколько шрифтов, при этом некоторые таблицы коллекции могут быть общими для всех шрифтов коллекции. 

Для чего может понадобиться знание внутреннего устройства шрифта? Например, некоторые форматы документов (pdf, xps) позволяют включать файл шрифта непосредственно в документ. Это делается для того, чтобы документ правильно отображался на системе, где не установлен шрифт, используемый в документе. Но даже внедрение шрифта не обязывает знать его структуру. Так зачем же может понадобиться знание внутреннего устройства шрифта? Дело в том, что внедрение даже одного шрифта способно увеличить размер документа во много раз. Это цена, которую приходится платить за возможность использования документа на любой платформе и любом устройстве. Стоит ли говорить, что внедрение нескольких шрифтов может на порядки увеличить размер документа? Именно поэтому возникает необходимость «обрезать» шрифт, оставив в нём только необходимую информацию, например, удалить из шрифта данные о начертаниях символов, не используемых в документе. 
  
Итак, настало время внимательно рассмотреть содержимое TTF файла. Посмотрим, из чего же состоит шрифт Arial из Windows 7. В нём обнаружены следующие таблицы: 





На рисунке представлены все таблицы, существующие в шрифте, их размер и позиция таблицы от начала файла шрифта. Как видно из рисунка, самая большая таблица – glyf. Именно она содержит векторное представление символов шрифта. Соответственно, сжатие этой таблицы позволит значительно сократить размер файла. Графическое представление любого используемого символа, будь то цифра, буква, знак или дальневосточный иероглиф, хранится в этой таблице. Принцип хранения информации о символе очень хорошо описан в статье Википедии: http://ru.wikipedia.org/wiki/TrueType 

Однако, здесь возникает проблема – таблица глифов содержит только описание глифов, но не содержит информацию об их позициях в таблице. Чтобы получить позицию глифа в таблице glyf, используется вспомогательная таблица loca. Структура этой таблицы исключительно проста – количество её элементов соответствует количеству символов в шрифте и каждый элемент этой таблицы указывает позицию символа в таблице glyf: 




Соответственно, при сжатии шрифта, вместе с перестройкой и сжатием таблицы глифов, перестраивается таблица loca. Помимо информации о позиции глифа, из этой таблицы можно получить информацию о количестве байт, занимаемые глифом. На приведённом выше рисунке можно увидеть, что элементы с номерами 1, 2, 3 и 4 имеют одинаковое значение. Дело в том, что количество байт, необходимых для отрисовки символа, можно получить вычитая текущую позицию из позиции следующего элемента таблицы. Например, из фрагмента вышеприведённой таблицы loca, видно, что информация, необходимая для изображения первого символа (элемент 0), занимает 42 байта. Если какой-то символ не имеет графического отображения в таблице глифов, то следующий элемент будет начинаться с той же самой позиции. Таким образом символы, определяемые элементами 1, 2 и 3 не имеют графического представления. Символ, определяемый четвёртым элементом, начинается со смещения 42 и занимает 172 байта. 

В мире используются множество языков, а любой шрифт формата TrueType может содержать различные комбинации различных шрифтов для различных языков. Для того, чтобы перейти от кода символа к его графическому представлению, используется дополнительная таблица cmap. Все символы шрифта разбиты на сегменты, где каждый сегмент соответствует набору символов какого-либо алфавита. 
Например, нам необходимо, используя файл шрифта, нарисовать русскую букву Ё. Для этого по коду символа находится сегмент в таблице cmap. Если соответствующий символу сегмент не найден, то шрифт не содержит описание символа. Если сегмент найден, то с помощью несложной формулы находится индекс, указывающий позицию этого символа в таблице loca. Элемент таблицы loca по найденному индексу указывает на данные символа в таблице glyf. 

Буква Ё неслучайно взята для примера, в найденной позиции таблицы glyf Вы не найдёте буквы Ё. Причина в том, что эта буква является составной из двух глифов – из глифа Е и глифа «комбинированный диарезис» (две точки над символом). Соответственно, в найденной позиции будет описание взаимного расположения и индексы простых глифов, из которого образован составно глиф. Этот момент необходимо учитывать, чтобы при упаковке таблицы по ошибке не удалить части составного глифа. 

Таким образом, при переходе от кода символа к его графическому представлению всегда используются три таблицы. А что же остальные таблицы? Часть из них необходима, а часть необязательна, но позволяют улучшить вид печатаемого документа. Например, некоторые шрифты могут содержать в себе тщательно нарисованные художниками графические образы символов, для их корректного отображения на устройствах с низким DPI (графическим разрешением, определяющим количество точек на 1 дюйм). В большинстве случаев можно исключить эту таблицу при сжатии шрифта. В этом случае документ будет иметь чуть худший вид на экране, но при этом хорошо выглядеть при печати на современных принтерах. 

Таблица name содержит текстовые описания шрифта – короткое и полное имя, автор шрифта, версия шрифта, лицензионная информация и другие параметры. Именно из этой таблицы черпают информацию различные программы для каталогизации, просмотра и выбора шрифтов. Например, на рисунке ниже показаны некоторые строки, содержащиеся в шрифте Arial. 


  
Базовые свойства шрифта определяются таблицей head. Её содержимое показано на рисунке ниже. 



Поля indexToLocFormat и glyphDataFormat таблицы head определяет формат таблиц loca и glyf, поэтому таблица head должна быть прочитана первой. Даты создания и модификации шрифта указаны в секундах, прошедших с 1 января 1904 года. Параметры xMax, xMin, yMax, yMin описывают прямоугольник, в который вписываются любой глиф шрифта. Важный параметр, использующийся при рисовании символов шрифта – untisPerEm. Он определяет, ширину заглавной латинской буквы M в условных единицах. Значение untisPerEm используется для масштабирования символов при их выводе на физические устройства – экран или принтер.

26 марта 2024

Как работать с FastReport Avalonia на .NET 8 в Visual Studio for Mac

В этой статье мы разберем, как запустить FastReport Avalonia на операционной системе MacOS с использованием IDE Visual Studio.
6 сентября 2022

Закончилась эпоха WinForms, началась FastReport.Core.Skia

Новый графический движок SkiaSharp для создания качественных отчётов и корректного экспорта в разные форматы доступен в FastReport .NET.
15 февраля 2022

Приватный NuGet-сервер Быстрые отчеты

Рассказываем о нашем собственном хранилище пакетов NuGet-сервер Быстрые отчеты с подключением через различные источники.