Pull to refresh

Comments 15

При рендеринге векторных шрифтов крайне важно, насколько хорошо выглядит текст маленького размера. TTF файлы содержат специальные инструкции для выравнивания контура глифов маленького размера по пиксельной сетке (хинтинг). Учитывает ли ваша библиотека этот момент и может ли она подойти для рендеринга надписей в GUI или текта в браузере?
Здравствуйте. Вы абсолютно правы касательно хинтинга, это полезная технология для повышения в первую очередь отчётливости шрифта малого размера. К сожалению, вывод сеточного шрифта будет страдать тем же, чем и вывод обычной векторной графики — мелкоразмерные символы будут размываться.
В последней анимации видно, что текст читабелен при высоте символа меньше 6 пикселей, однако размывание контуров, несомненно, выше чем у хинтового вывода.
Сама scalable-технология едва ли допускает хинтинг. Но возможно ли применение хинтов в частном случае (ортогональная проекция с определённым масштабом) — над этим попробую подумать. Также интересно подумать можно ли поправить ситуацию с использованием пиксельного шейдера.
Для GUI и браузера сеточные шрифты потенциально подходят, хотя первичное применение представлялось другим. Опять же, с оговоркой, что отчётливось мелких символов теряется быстрее, чем у шрифтов с хинтом. На сколько это критично сегодня с учётом высоких дисплейных разрешений — надо исследовать.

Спасибо автору за статью.
Напомнила студенческие годы.
В библиотеке OpenGL для Windows лет этак 20 назад была функция wglUseFontOutlines. Когда-то даже игрался с ней году в 2003м. Исходный код может быть есть в Wine, тесселятор там из GLU.

Здравствуйте. Большое спасибо за информацию.
На opengl.org пишут «This is specifically for the Windows platform». Работаю под linux в основном, поэтому, видимо, не сталкивался с wglUseFontOutlines.
Непременно загляну в wine — было бы интересно посмотреть на опыт предшественников. Особенно интересно то как обходятся проблемы с контурными дефектами, т.к. вижу этот вопрос весьма не тривиальным. В следующей статье обязательно обозначу результаты поиска.
Стандартное API операционной системы позволяет получать контур любого шрифта. Поэтому контуру можно легко триангулировать либо очень простым самописным алгоритмом, либо стандартными средствами еще 90-x годов. В других случаях есть фреймворки со встроенными средствами, которые выполняют это автоматически. Это достаточно тривиальная задача не для того чтобы создавать для нее целую библиотеку. Я не совсем понимаю вашу проблему и какие тяжеловесные решения вы находили. Но адаптировать под это дело триангуляцию Делоне не целесообразно и не производительно, по крайней мере в вашем исполнении и требует очень большой оптимизации. Если вы хотели продемонстрировать это в качестве примера то это вполне интересно, но не больше.

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

В рамках какого либо фреймворка с уже объявленными базовыми математическими типами, контейнерами и стандартными операциями с 3D, решение обычно съеживается до одного заголовочного файла.
Linux и Ubuntu — стандартное API используется в X11
MacOs — также для ios.
qnx — Pf модуль в комплекте ОС.
win — стандартная gdi библиотека.

С калибри не работал. Какая то еще ОС требуется? Или у вас есть свой парсер fft файлов?
Спасибо за статью. Больше всего понравилась в ней описание алгоритма триангуляции. С этим методом я не был знаком. Вы случайно не сравнивали этот метод с другими алгоритмами триангуляции? Например, с методом монотонных полигонов. Интересуют полный процесс триангуляции от построения базовой к последующему приведению Делоне. Как я сам вижу оба алгоритма имеют асимптотику базовой триангуляции (без Делоне) n*Log(n). Но возможно у вашего алгоритма базовая триангуляция ближе к Делоне. Плюс у монотонного метода есть шаг с разбиением на полигоны. С другой стороны в вашем алгоритме присутствует излишняя триангуляция «вспомогательных» треугольников. Но это все в теории, а хотелось бы практическую скорость сравнения. Еще из плюсов вашего подхода, как вы сами отметили устойчивость алгоритма к петлям.
Здравствуйте. Спасибо за отзыв.
Описанный метод, на сколько я понимаю, достаточно свежий (2008 года). В моей версии книги Скворцова от 2002 года, например, о нём не говорится. Есть только 2 абзаца о прототипном алгоритме (см. 5.3. Линейный алгоритм).
К слову, описанный метод применён был в одной известной библиотеке poly2tri. Для изучения — очень рекомендую на неё обратить внимание.
На монотонный метод смотрел с надеждой. Но, к своему стыду, так и не понял как его можно прикрутить. Например, не ясно как триангулируя «8» получить за линейное или O(N logN) время набор y-монотонных многоугольников. Этот самый набор, очевидно, триангулировать после было бы не сложно. Преимущество монотонного метода в том, что не нужно решать потом задачу вставки структурных отрезков (ограничения уже добавлены).
Текущая версия триангуляция, как отмечал, вынуждена работать в два этапа. Первый — триангуляция без ограничений (описанным методом). Второй — вставка структурных отрезков (планируется описать во второй статье). Вот вставка как раз чувствительна к петлям (с петлями борюсь до триангуляции) и по сути на этом этапе возникает триангуляция монотонных многоугольников, которые образуются после удаления мешающих рёбер.
В связи со сказанным, буду очень признателен за ценные указания касательно возможных способов первичного разбиения на монотонные многоугольники (можно в личку).
С книгой Скорцова я конечно же знаком, во многих вещах она для меня стала путеводителем.
Да я сам хорошо разобрался с методом монотонного разбиения. И могу вам с ним помочь. По сути там та же идея, что и в вашей имплементации. Вы движетесь вдоль оси заметающей прямой и делаете суждение заканчивается, начинается или продолжается монотонный полигон. Сортировка начальных вершин и порождает N*log(N). Далее идет триангуляция, которая на практике в подавляющем случаи идет за линейное время и в очень редком случаи с откатом к предыдущей или далее вершине. Я к сожалению не могу оценить эту асимптотику (наверное это N*log(N), но доказать не могу). Для дальнейшего приведения к Делоне так же потребуется связать между собой треугольники, те что лежат на ребре разделяющем один монотонный полигон от другого.

У меня есть две имлементации swift и СSharp. Обе написаны в Data-oriented design, что делает их не много громоздкими для понимания. Так же мне почему то было проще рассуждать двигая заметающую прямую по оси oX. Swift версия использует ARC (умный подсчет ссылок), а СSharp версия полагается на ручной механизм управления памятью. Еще стоит наверное сказать, что в swift версии я начал добавлять поддержку дополнительных точек. Точки которые лежат внутри полигона, и обычно нужны для более «красивой» триангуляции.

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

Добрый день. Шикарная статья, читалась на одном дыхании. Спасибо!
А поддерживаются ли в каком-нибудь виде emoji?
Например, есть Noto Color Emoji. Можно ли как-нибудь подружить?
У библиотеки очень богатый простор для использования.

Добрый день. Спасибо за отзыв!
Рецепта для Emoji пока, к сожалению, нет.
Проверка чтения файла NotoColorEmoji.ttf показала, что в нём отсутствует таблица 'glyf', которая содержит контурную информацию. Но есть таблица CBDT (Color Bitmap Data Table) и судя по описанию Microsoft — это всё растры разных размеров.
Вопрос понятен и актуален. Попробую поискать информацию о векторном представлении Emoji в известных шрифтах! Судя по первому знакомству, в Noto такое не сделано.

UFO just landed and posted this here

Интересно. Думаю, у растеризатора есть шанс обработать 1 глиф быстрее, возможно, даже на порядок. Но стоит учесть, что вопрос скорости растеризации (либо тесселяции) на CPU особо остро не стоит. Оба подхода имеют приемлемую производительность, учитывая, что применяемый при отображении алфавит (несколько десятков глифов) достаточно растеризировать (либо триангулировать) один раз. Следующие разы — пользоваться готовыми результатами. Правда в случае растеризации нужно хранить назависимый кеш для символов разных размеров и если отображается символ большооой, то это неприятно, т.к. нужно "залить" и хранить слишком много пикселей.
Кстати, интересное наблюдение… Когда текст в редакторе увеличиваешь до гигантских глифов — то могут ощущаться тормоза. Видимо, набредаем на непосредственную работу растеризатора.
Про "видеокарты любят треугольники" — тут двойственно. Далеко не факт, что сеточный шрифт будет выведен быстрее чем текстурный шрифт. Скорее наоборот, учитывая, что текстурка может быть маленькой, а сеточный эквивалент — содержать массу треугольников. В действительности выводы сделать сложно, оба подхода — они не конкурируют, они разные.
По поводу формата, текущий формат — он не плох, вектор рулит. Разве что контурные дефекты доставляют неприятности. Вот если бы дизайнеров контролировали получше… :)

Sign up to leave a comment.

Articles