Формат файла растрового шрифта
В этом разделе подробно описан формат файла шрифта, который использует объект lcd.. Файл шрифта - это файл ресурсов, добавляемый в проект Tibbo BASIC/C. Как и все остальные «прикреплённые» к проекту файлы ресурсов, файлы шрифтов доступны через объект romfile.. Но использование и интерпретация данных шрифта лежат на объекте lcd.; объект romfile. лишь хранит эти файлы.
Файлы шрифтов Tibbo имеют расширение «TRF» (Tibbo Raster Font). Формат TRF разрабатывался с учётом следующих соображений:
- Возможность работы с большими наборами символов (например, нужными для поддержки китайского языка). Поэтому используются 16-битные коды символов.
- В 16-битных наборах символов обычно есть большие «пропуски» (то есть области неиспользуемых кодов). Формат TRF предлагает эффективный способ определить, какие символы входят в файл шрифта, и позволяет очень быстро искать символы в файле.
- Поддержка пропорциональных шрифтов. Поэтому ширина каждого символа задаётся отдельно.
- Поддержка шрифтов со сглаживанием. Сглаживание достигается регулировкой «интенсивности» (яркости) отдельных пикселей. В сглаженном шрифте каждый пиксель растра символа представлен 2 или более битами данных. Шрифтам без сглаживания достаточно 1 бита данных на пиксель, поскольку пиксель может быть только включён или выключен. TiOS сейчас поддерживает только шрифты с 1 битом на пиксель.
- Поддержка вертикальной и горизонтальной кодировки растра символов. У дисплеев с lcd.bitsperpixel = 1, 2 или 4 в одном байте памяти дисплея упаковано 8, 4 или 2 пикселя. Проблема в том, что одни дисплеи объединяют пиксели по вертикали (рисунок A ниже), а другие - по горизонтали (рисунок B). Вывод текста на таких дисплеях эффективнее, если растры символов в файле TRF упакованы в том же направлении.

Формат файла TRF
Файл TRF состоит из четырёх областей данных:
| Область данных | Описание |
| Заголовок | Содержит различные сведения: общее число символов в этом шрифте, высоту символов и т. д. Также содержит число групп кодов в таблице групп кодов (см. ниже). |
| Таблица групп кодов | Содержит описатели «групп кодов». Каждая группа кодов содержит сведения о диапазоне кодов без «пропусков» (то есть без неиспользуемых кодов посередине). В файле шрифта может быть сколько угодно групп кодов. |
| Таблица смещений растров | Содержит адреса (смещения) всех растров символов в файле TRF. Вместе с таблицей групп кодов позволяет найти растр любого символа. |
| Растры | Содержит все растры каждого символа, включённого в файл шрифта. Ширина каждого растра задаётся отдельно и хранится вместе с растром. |
Формат заголовка
Заголовок имеет фиксированную длину 16 байт и хранит следующие сведения:
| Смещение* | Байт | Данные | Комментарий |
| +0 | 2 | Num_of_chars | Общее число символов в этом файле шрифта |
| +2 | 1 | Pixels_per_byte |
Режимы 1, 2 и 3 сейчас не поддерживаются; они предназначены для сглаживания и будут поддерживаться в будущем. |
| +3 | 1 | Orientation |
|
| +4 | 1 | Height | Максимальная высота символа в этом шрифте, в пикселях. |
| +5 | 9 | <Reserved> | Зарезервировано для будущего использования |
| +14 | 2 | Num_of_groups | Число записей в таблице групп кодов |
*Относительно начала файла
Таблица групп кодов
В этой таблице переменное число записей. Оно хранится в поле num_of_groups заголовка. Каждая группа кодов - это диапазон кодов без пропусков (без неиспользуемых кодов символов посередине). Например, пусть шрифт содержит только символы «0»~«9» и «A»~«Z»; тогда в файле шрифта будет две группы кодов: от 0030H до 0039H («0»~«9») и от 0041H до 005AH («A»~«Z»).
Каждая запись в таблице групп кодов имеет длину 8 байт и следующий формат:
| Смещение* | Байт | Данные | Комментарий |
| +0 | 2 | Start_code | Первый код в группе |
| +2 | 2 | Num_codes | Число отдельных кодов символов в этой группе |
| +4 | 4 | Bitmap_addr_offset | Адрес (попадающий в таблицу смещений растров и отсчитываемый от начала файла), по которому хранится адрес растра первого символа группы кодов. |
* Относительно начала конкретной записи таблицы
Для приведённого примера в таблице групп кодов будет две записи:
| Start_code | Num_codes | Bitmap_offset |
| 0030H | 000AH | 00000020H |
| 0041H | 001AH | 00000048H |
Вот как рассчитаны эти данные. Начальные коды очевидны. Первая группа начинается с кода 0030H, потому что это код символа «0». Вторая группа начинается с кода символа «A». Число кодов в каждой группе тоже легко заполнить: 10 (000AH) для «0»~«9» и 26 (001AH) для «A»~«Z». Расчёт bitmap_addr_offset объясняется в следующем разделе.
Таблица смещений растров
В этой таблице столько же записей, сколько всего символов включено в файл шрифта. Каждая запись состоит из одного поля - 32-битного смещения конкретного растра относительно начала файла шрифта. Теперь видно, как удалось рассчитать данные для поля bitmap_addr_offset таблицы групп кодов. Заголовок файла шрифта имеет фиксированную длину 16 байт. В нашем примере две группы кодов, поэтому таблица групп кодов занимает 8 x 2 = 16 байт. Значит, таблица смещений растров начинается с адреса 16 + 16 = 32 (0020H). Поэтому первая запись в таблице групп кодов указывает на адрес 0020H. Первая группа кодов содержит 10 символов («0»~«9»). Они «займут» 10 записей в таблице смещений растров, то есть 10 x 4 = 40 байт. Поэтому поле bitmap_addr_offset для второй группы кодов равно 32 + 40 = 72 (0048H).
Растры
Каждый растр начинается с одного байта, в котором закодирована ширина растра в пикселях, а за ним следует необходимое число байт самого растра. В зависимости от поля pixels_per_byte заголовка каждый байт данных может кодировать один пиксель или несколько. Кроме того, при кодировании с более чем одним пикселем в байте поле orientation заголовка определяет, объединяются пиксели по горизонтали или по вертикали.
На рисунках ниже показано, как растры символов хранятся в файле шрифта. В качестве примера взяты символы размером 10x14 пикселей. Рисунок A - для кодирования с одним пикселем в байте, рисунок B - для 8 пикселей в байте с вертикальной ориентацией, а C - для 8 пикселей в байте с горизонтальной ориентацией. Обратите внимание: в случаях B и C часть некоторых байтов, используемых для хранения растров, не задействована. Смещения байтов относительно начала данных растра показаны со знаком «+».
Растр A занимает 140 байт. Первый байт (+0) представляет пиксель в левом верхнем углу растра. Следующие байты представляют все остальные пиксели в порядке «слева направо, сверху вниз».
Растр B занимает 20 байт. Первый байт кодирует 8 вертикально расположенных пикселей в левом верхнем углу растра. Следующие байты представляют все остальные группы пикселей в порядке «слева направо, сверху вниз». Здесь две строки байт, и биты 6 и 7 каждого байта во второй строке не используются.
Растр C занимает 28 байт. Первый байт кодирует 8 горизонтально расположенных пикселей в левом верхнем углу растра. Следующие байты представляют все остальные группы пикселей в порядке «сверху вниз, слева направо». Здесь два столбца байт, и биты 2~7 каждого байта во втором столбце не используются.

Поиск растра символа
Вот как искомый растр символа находится в файле шрифта. Снова возьмём пример файла шрифта с символами «0»~«9» и «A»~«Z».
Допустим, нужно найти растр символа «C» (код 0043H). Сначала нужно определить, к какой группе кодов относится код 004AH. Читаем поле num_of_groups заголовка, чтобы узнать, сколько групп кодов содержится в файле шрифта. Поле сообщает, что групп две.
Далее читаем таблицу групп кодов (она находится по смещению +00000010H в файле) запись за записью, чтобы определить, к какой группе кодов относится искомый символ. Первая группа начинается с кода 0030H и содержит 10 символов. Значит, искомый символ в неё не входит. Вторая группа начинается с кода 0041H и содержит 26 символов. Искомый код - 0043H. Следовательно, искомый символ принадлежит второй группе.
Затем находим соответствующую запись в таблице смещений растров. Для этого делаем простой расчёт:
bitmap_offset + (desired_code - start_code) * 4: 00000048H + (0043H - 0041H) * 4 = 00000050H.
Далее читаем 32-битное значение по смещению 00000050H в файле. Оно сообщит смещение в файле, по которому хранится искомый растр.
По этому смещению первый байт будет шириной растра в пикселях. Исходя из этой ширины, а также из полей height, pixels_per_byte и orientation заголовка, можно вычислить число байт в растре. Например, пусть height = 14, pixels_per_byte = 0 (8 пикселей в байте), а orientation = 0 (пиксели сгруппированы по вертикали). Пусть также ширина искомого символа равна 10 пикселей. Тогда растр займёт 20 байт, как показано на рисунке B выше. Два бита каждого байта во второй строке байт не используются.