ttf-parser — это библиотека для разбора TrueType/OpenType шрифтов. В новой версии появилась полноценная поддержка переменных шрифтов (variable fonts) и C API, вследствие чего я решил прорекламировать её на лоре.
До недавнего времени, если была необходимость работы с TrueType шрифтами, было ровно два варианта: FreeType и stb_truetype. Первый является огромным комбайном, второй поддерживает довольно небольшое количество функций.
ttf-parser
находится где-то посредине. Он поддерживает все те же TrueType таблицы (формат TrueType состоит из множества отдельных бинарных таблиц) что и FreeType, но не занимается отрисовкой самих глифов.
При этом, ttf-parser
содержит множество других значительных отличий:
ttf-parser
написан на Rust без использования unsafe. FreeType и stb_truetype написаны на C.ttf-parser
является единственной безопасной (memory-safe) реализацией. Чтение произвольной памяти невозможно. Во FreeType постоянно исправляют уязвимости, а stb_truetype в принципе не предназначен для чтения произвольных шрифтов.ttf-parser
является единственной thread-safe реализацией. Все методы парсинга константны. Единственным исключением является задание координат для переменных шрифтов, но эта функция reentrant. FreeType в принципе однопоточный. stb_truetype - reentrant (можно использовать отдельные копии в разных потоках, но не одну из множества).ttf-parser
является единственной реализацией не использующей аллокации в «куче». Это позволяет ускорить разбор и избежать проблем при OOM.- Также, почти все арифметические операции и приведение числовых типов проверяются (в том числе статически).
- В самом худшем случае библиотека может бросить исключение. При этом в C API исключения будут перехвачены и функция вернёт ошибку, но не упадёт.
И несмотря на все гарантии безопасности, ttf-parser
также является и самой быстрой реализацией. Например разбор CFF2 в 3.5 раза быстрее чем в FreeType. Разбор glyf
тем временем на 10% медленнее чем в stb_truetype, но это из-за того, что он не поддерживает переменные шрифты, для реализации которых требуется хранить доп. информацию. Больше подробностей в README.
>>> Подробности