LINUX.ORG.RU

ttf-parser 0.5 — новая библиотека для работы с TrueType шрифтами

 ,


3

8

ttf-parser — это библиотека для разбора TrueType/OpenType шрифтов. В новой версии появилась полноценная поддержка переменных шрифтов (variable fonts) и C API, вследствие чего я решил прорекламировать её на лоре.

До недавнего времени, если была необходимость работы с TrueType шрифтами, было ровно два варианта: FreeType и stb_truetype. Первый является огромным комбайном, второй поддерживает довольно небольшое количество функций.

ttf-parser находится где-то посредине. Он поддерживает все те же TrueType таблицы (формат TrueType состоит из множества отдельных бинарных таблиц) что и FreeType, но не занимается отрисовкой самих глифов.

При этом, ttf-parser содержит множество других значительных отличий:

  1. ttf-parser написан на Rust без использования unsafe. FreeType и stb_truetype написаны на C.
  2. ttf-parser является единственной безопасной (memory-safe) реализацией. Чтение произвольной памяти невозможно. Во FreeType постоянно исправляют уязвимости, а stb_truetype в принципе не предназначен для чтения произвольных шрифтов.
  3. ttf-parser является единственной thread-safe реализацией. Все методы парсинга константны. Единственным исключением является задание координат для переменных шрифтов, но эта функция reentrant. FreeType в принципе однопоточный. stb_truetype - reentrant (можно использовать отдельные копии в разных потоках, но не одну из множества).
  4. ttf-parser является единственной реализацией не использующей аллокации в «куче». Это позволяет ускорить разбор и избежать проблем при OOM.
  5. Также, почти все арифметические операции и приведение числовых типов проверяются (в том числе статически).
  6. В самом худшем случае библиотека может бросить исключение. При этом в C API исключения будут перехвачены и функция вернёт ошибку, но не упадёт.

И несмотря на все гарантии безопасности, ttf-parser также является и самой быстрой реализацией. Например разбор CFF2 в 3.5 раза быстрее чем в FreeType. Разбор glyf тем временем на 10% медленнее чем в stb_truetype, но это из-за того, что он не поддерживает переменные шрифты, для реализации которых требуется хранить доп. информацию. Больше подробностей в README.

>>> Подробности

★★★★★

Проверено: Satori ()

Ответ на: комментарий от AP

Поиск ошибок в созданных шрифтах. Классика жанра: глифы без точек экстремума и с самопересечениями.

А поиском ошибок не должно заниматься ПО, которое позволяет создать этот шрифт?

andreyu ★★★★★ ()
Ответ на: комментарий от red75prim

Помочь мазиле добавить поддержку SFTP в браузер вместо FTP.

Поддерживать и собирать билды Ungoogled Chromium для Android. Впилить туда же расширения.

Адаптировать существующие наработки по нейросеткам в качественное open source решение, где все было бы в одном месте и не хуже чем закрытое и платное у корпов.

Много есть реальных потребностей. Но они переписывают какие-то пыльные залежалые библиотечки.

anonymous ()
Ответ на: комментарий от anonymous

Да, это трагедия С++: когда человек не может нормально написать чтение из файла, а вместо этого пишет какую-то х-ню которую уже 3 страницы обсуждают и на каждой странице каждый художник описывает свое видение. Если не получается чтение из файла, то и управление памятью или многопоточность тоже не получатся, поэтому и нужен Руст - для того чтобы человек мог ощутить как он занимается системным программированием, но чтобы Руст как-то все это за него сделал. Теперь я понимаю. Должно быть неплохая штука для терапевтических целей.

anonymous ()
Ответ на: комментарий от anonymous

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

anonymous ()
Ответ на: комментарий от RazrFalcon

Если вы не можете себе представить зачем нужен парсер без отрисовки - я вам не доктор.

Можно было просто ответить «я написал парсер, а какой от него прок я не знаю».

andreyu ★★★★★ ()
Последнее исправление: andreyu (всего исправлений: 1)
Ответ на: комментарий от dinama

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

anonymous ()
Ответ на: комментарий от dinama

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

anonymous ()
Ответ на: комментарий от anonymous

Доооо… Вместо реализации спецификации переменных шрифтов, которой всего пару лет, будем реализовывать мёртвый протокол для умирающего браузера. Ну вы там это - держитесь.

RazrFalcon ★★★★★ ()

А кернинг ты как разруливаешь? Мне в конверторе пришлось тянуть opentype.js ради устаревшей kern. Во фритайпе пишут, что композинг глифов не их пролема и надо юзать harfbuzz.

Vit ★★★★★ ()
Ответ на: комментарий от andreyu

А поиском ошибок не должно заниматься ПО, которое позволяет создать этот шрифт?

Может (FontForge, например), но это не гарантирует того, что автор шрифта — адекват.

AP ★★★★★ ()
Ответ на: комментарий от RazrFalcon

О, ты-то мне и нужен :). Можешь оценить, насколько реалистично полноценный кернинг в мелкий эмбед засунуть?

Или юзать kern - потолок, и на арабские языки проще забить?

Надо сюда https://github.com/littlevgl/lv_font_conv, спека на фонт там есть.

Vit ★★★★★ ()
Ответ на: комментарий от Vit

Я сам только погружаюсь в эту тему, поэтому не могу сказать достоверно.

kern определяет расстояние между глифами. Но он бесполезен для всяких умлаутов и прочих mark glyphs. Для этого есть GDEF/GSUB/GPOS. И они не только для арабского. Фактически, kern - объявлен устаревшим и нужно использовать GSUB/GPOS, ну или morx/trak если мы про Apple шрифты.

То есть всё зависит от самого шрифта, требуемых языков и нужных глифов.

На самом деле, если мы говорим про эмбед, то первой проблемой является работа с unicode, для которого нужно будет натащить прилично таблиц.

Ну или вообще сваять свой шрифт, в котором всё уже будет как нужно. UPD: А, так вы это и делаете.

RazrFalcon ★★★★★ ()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Фактически, kern - объявлен устаревшим и нужно использовать GSUB/GPOS.

Я себе мозг сломал, пытаясь понять и прикинуть апи. kern тупой как пробка - для любой пары глифов выдает коррекцию смещения. А в GSUB/GPOS столько фич, что я сдался, пытаясь осилить всю картину.

На самом деле, если мы говорим про эмбед, то первой проблемой является работа с unicode, для которого нужно будет натащить прилично таблиц.

Скажем так, это уже не моя печаль :). Я только проверил, что все юникодные атрибуты при продвинутой упаковке вписываются в 10К, и успокоился.

Мое дело - предоставить конвертор фонтов, такой чтобы потом не бегали толпами с просьбами добавить новых фич.

Ну или вообще сваять свой шрифт, в котором всё уже будет как нужно. UPD: А, так вы это и делаете.

Ага :). Взял за основу трутайповские таблички, втащил подходящие куски с минимумом изменений, а глифы заменил битмапами.

Vit ★★★★★ ()
Ответ на: комментарий от anonymous
  1. В конце, по той ссылке, «GPOS not supported»
  2. Эта функция у многих шрифтов реально кернинг не читает. Проверено. Пришлось доставать через opentype.js и создавать подобие kern у себя.
Vit ★★★★★ ()
Ответ на: комментарий от Vit

мне так трудно судить о чём речь, по ссылке на гитхаб написано ttf. вот так gpos и kern обрабатываются в stb_truetype: https://github.com/nothings/stb/blob/master/stb_truetype.h#L2623

если у вас скрипт который делает битмап-шрифт, то какая разница чем читать исходник? вы всё равно преобразуете все эти таблицы в расстояние между глифами и храните в каком-то представлении, разве нет?

если вам нужны более продвинутые фичи, то я слышал краем уха, что они зависят на контекст (конкретную строку которая рендерится), и как это представить в битмап-шрифте я себе слабо представляю. предполагаю, что если вам нужен gpos и информацию из него надо скопировать без потерь, то придётся создать у себя некоторое подобие gpos.

anonymous ()
Ответ на: комментарий от Vit

Ну GSUB/GPOS будет в следующей версии ttf-parser. У меня уже есть более-менее работающая реализация.

а глифы заменил битмапами

А зачем свой формат шрифта, если можно было в sbix таблицу растры запихать?

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

А зачем свой формат шрифта, если можно было в sbix таблицу растры запихать?

Невыгодно. Куча всякого легаси говна и отсутствие поддержки легкого для эмбедов сжатия.

С какого-то момента, если проц жирный, выгоднее фритайп с ttf напрямую втащить. А до этого порога ничего приличного к сожалению не было, в том числе и на уровне спек. Я ж не дурной с NIH синдромом.

Vit ★★★★★ ()
Ответ на: комментарий от anonymous

Спасибо за ссылку. Ну вот у меня примерно для того же юзается opentype.js. ХЗ как он данные для пар подшаманивает из таблиц, но работает.

Но надо иметь в виду, что расстояние между парами - очень небольшое подмножество из реально поддерживаемых фич. И меня как раз интересовала более полноценная поддержка, которой в stb похоже тоже нет.

Vit ★★★★★ ()
Ответ на: комментарий от Vit

ХЗ как он данные для пар подшаманивает из таблиц, но работает.

Он поддерживает базовые GPOS фичи, которые и являются современной заменой kern. FreeType такое не умеет.

И если JS, то можно посмотреть в сторону fontkit. Это почти полноценный порт harfbuzz, пусть и заброшенный.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

которой всего пару лет

мёртвый протокол для умирающего браузера

Так вы специально за всем модным гоняетесь? И на полном серьёзе готовы доказывать, что сырые плохо оттестированные поделки, никем кроме сотни звезданутых (stargazers) с гитхаба не используемые, во всем лучше стабильных протоколов и реализаций? Ну-ну. Знаком с таким мировоззрением. К сожалению, современная психиатрия лекарства от этого не знает.

Ну вы там это - держитесь

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

anonymous ()
Ответ на: комментарий от RazrFalcon

У фонткита другие проблемы. Юзали в предыдущей версии, потом выпилили. Самое удачное оказалось юзать фритайп (через webassembly) и сбоку подклеить кернинг от opentype.js.

В общем, если ты по ходу своих метаний обнаружишь как кернинг под эмбеды улучшишь - пни меня пожалуйста. Допилю спеку, она к языку не привязана. Мне не обязательно 100% фич. Покрыть 99% потребностей - тоже очень хорошо.


Минутка рекламы :). https://github.com/puzrin/dispenser/blob/master/doc/assembly.md#pcb-assembly - там фоточка, как шрифты на эмбеде выглядят, с субпиксельным сглаживанием.

Vit ★★★★★ ()
Ответ на: комментарий от red75prim

Какие 50 лет? Эта свалка, которую невозможно забутстрапить не обматерившись и в которой уже сами авторы запутались, помрёт и разложится значительно раньше.

anonymous ()