Инструментарий для шрифтов OpenType / TrueType; текстовый рендеринг в целом
TLDR:
Примечание . Это относится только к возможностям загрузки / рисунка TTF / OTF. Пользовательский формат шрифта по -прежнему остается тодо. Смотрите дорожную карту для состояния проекта
В настоящее время API очень прост, но обеспечивает большую гибкость благодаря конфигурации Comptime.
Первым шагом является создание типа шрифта, который принимает бэкэнд в качестве параметра конфигурации Comptime. Варианты: fontana , freetype и freetype_harfbuzz . В приведенном ниже примере мы используем настраиваемый бэкэнд fontana :
const font_backend: fontana.Backend = .fontana;
const Font = fontana.Font(font_backend);
var font = try Font.initFromFile(allocator, font_path);
defer font.deinit(allocator); Тип Font имеет 3 публичных функций, initFromFile() , deinit() и createPen() . Первые два работают, как и ожидалось, поэтому давайте перейдем к типу Pen .
Тип Pen содержит атлас, размер шрифта и сбор кодепоинтов. Указанные кодепоины будут преобразованы в глифы и растеряны в текстуру. При работе с приложением, которое будет отображать текст в разных размерах, вы можете генерировать больше Pens из одного Font .
ПРИМЕЧАНИЕ . Атлас шрифта, управляемый ручкой, может поделиться текстурой поддержки с другими частями приложения, он принадлежит только метадатам о том, что хранятся с глифами, где хранятся.
Вот подпись функции:
pub fn createPen (
self : * @ This ( ) ,
comptime PixelType : type ,
allocator : std . mem . Allocator ,
size : Size ,
points_per_pixel : f64 ,
codepoints : [ ] const u8 ,
texture_size : u32 ,
texture_pixels : [ * ] PixelType ,
) ! Pen Продолжая приведенный выше пример, здесь из нашего шрифта создается Pen .
const PixelType = graphics . RGBA ( f32 ) ;
const points_per_pixel = 100 ;
const font_size = fontana . Size { . point = 24 . 0 } ;
const pen = try font . createPen (
PixelType ,
allocator ,
font_size ,
points_per_pixel ,
atlas_codepoints ,
texture . dimensions . width ,
texture . pixels ,
) ;Примечание . Атлас поддерживает только квадратные текстуры, следовательно, Texture_size в отличие от Texture_dimensions
ПРИМЕЧАНИЕ . Pixeltype передается клиентом, и его свойства обнаруживаются автоматически во время расчищения. Если это не очень нерегулярный тип, он должен просто работать.
Тип Pen имеет одну цель, чтобы генерировать квадраты текстуры в вершин -буфер, который может использоваться графическим API для рисования текста на экране. У него есть только единственная публичная функция:
pub fn write (
self : * @ This ( ) ,
codepoints : [ ] const u8 ,
placement : geometry . Coordinates2D ( f64 ) ,
screen_scale : geometry . Scale2D ( f64 ) ,
writer_interface : anytype ,
) !voidКлиент указывает, какой текст рендеринг, где его отображать на экране, масштабирование экрана и интерфейс Comptime, используемый для направления вывода.
screen_scale преобразует пиксели в систему координат графического API, в Вулкане это можно рассчитать следующим образом:
fn scaleFromScreenDimensions ( width : f64 , height : f64 ) Scale2D ( f64 ) {
return . {
. vertical = 2.0 / height ,
. horizontal = 2.0 / width ,
} ;
}Это связано с тем, что Vulkan использует систему правой координаты NDC, которая переходит от -1,0 до +1,0 (общая длина 2,0) на оси x и y.
writer_interface имеет оцениваемый тип Comptime и должен удовлетворить следующий интерфейс:
pub fn write (
self : * @ This ( ) ,
screen_extent : fontana . geometry . Extent2D ( f32 ) ,
texture_extent : fontana . geometry . Extent2D ( f32 ) ,
) !voidВсе, что это делает, это карта значения текстуры в местоположениях на выводе, определяемой в системе координат базового графического API.
Просто добавьте src/fontana.zig в качестве нового пакета в вашем build.zig.
const fontana_path = "your_project/deps/fontana" ;
exe . addPackage ( . {
. name = "fontana" ,
. source = . { . path = fontana_path ++ "/src/fontana.zig" } ,
} ) ;Фонтана синхронизируется с последним релизом Zig. В последний раз он был проверен с версией 0.12.0-Dev.3180 .
Заводящий пример можно найти в примере репозитория Fontana-Examples. Несоответствующие активы, включая большое количество кода, не проверяются в главном репо, чтобы сохранить его минимальным и удобным для автоматизации.
Чтобы увидеть приведенный выше пример в полной форме, см. Этот файл конкретно
Тодо: Добавить дорожную карту
Грань