Найти тему
ZDG

Однобитный шрифт

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

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

Обычно шрифты оформляются в виде картинки, типа:

Чтобы вывести какую-то букву на экран, нужно скопировать прямоугольную область с этой буквой из картинки на экран.

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

Я использовал такой способ в этом проекте:

И шрифт выглядел так:

-2

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

В то же время часто есть нужда в обычном выводе текста, без наворотов, но разных цветов.

В этом случае и делается 1-битный шрифт. Он кодируется не с помощью картинки, а с помощью набора байт, где биты внутри байтов обозначают, есть пиксел или нет.

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

Такой подход применялся в этом проекте:

Тетрис размером 5 килобайт: 20 лет спустя
ZDG10 июня 2020
-3

Выше – представление шрифта в байтовом виде. Каждый символ занимает один байт в ширину и 15 байтов в высоту.

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

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

Я вспомнил о том, что мне нравился шрифт на компьютере Yamaha MSX. Да, там были разные игры, но у них часто был одинаковый шрифт, как бы "системный".

Я попробовал поискать и вроде бы нашёл именно его:

-4

Использовать его в исходном виде не удалось из-за того, что в картинке присутствовали артефакты. Поэтому я просто перерисовал его:

-5

А потом подготовил непосредственно для конвертации:

-6

Для Тетриса я писал программу, которая переводит картинку с изображением шрифта в байтовый формат. Но эту программу я потерял :) Поэтому пришлось писать новую.

Я использовал язык PHP, потому что он у меня всегда установлен. Скрипт принимает на вход имя картинки, ширину и высоту символа (чтобы вычислять границы символов), и координаты (x, y) любого пиксела, в котором содержится цвет шрифта. Скрипт отличает, где есть бит, а где нет, по цвету, поэтому он должен знать, какой из цветов какой.

Между прочим, реальный размер этого шрифта всего 7*7 пикселов. Вся картинка имеет размер 70*28 пикселов.

-7

Но при рисовании можно делать пикселы любого размера.

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

Исходник скрипта тут:

convert raster font image to array of bitmask bytes