Триангулируйте данные пути из OpenType.js, используя Earcut - PullRequest
0 голосов
/ 27 мая 2018

У меня есть сценарий использования, когда мне нужно визуализировать значительное количество (~ 50 000 глифов) четких, масштабируемых текстовых строк на элементе canvas.Лучшее решение , которое я пробовал до сих пор, включает триангуляцию текста, нарисованного на элементе canvas (текст был нарисован с использованием метода fillText), загрузку матричной формы и Float32Array из треугольников, представляющих эту строку, в графический процессор через WebGL.Используя этот метод, я смог отобразить 100 000 глифов со скоростью около 30 кадров в секунду.Символы становятся блочными при очень высоких уровнях масштабирования, но это хорошо для моего случая использования.

Однако этот метод требует около 250 мс на строку, так как я сначала рисую строку в элементе canvas в памяти, читаю данные пикселей, превращаю растровое изображение в вектор, а затем триангулирую векторные данные.В поисках решений в Интернете я наткнулся на два интересных проекта с открытым исходным кодом:

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

Моя проблема в том, Я не могу понять, как получить данные, которые предоставляет OpenType, и преобразовать их в формат, который принимает Earcut.Может ли кто-нибудь оказать помощь в этом?

Подробнее:

Этот вопрос StackOverflow содержал некоторую полезную информацию, но в нем отсутствуют некоторые детали реализации: Текст лучшего качествав WebGL .Я полагаю, что я пытаюсь выполнить подход «Шрифт как геометрия», описанный в первом ответе.

1 Ответ

0 голосов
/ 29 мая 2018

Вы можете создать путь, используя Font.getPath.Путь состоит из инструкций перемещения, линии, кривой и четырехугольника и закрытия, доступ к которым осуществляется через path.commands.Конечно, сначала вам нужно будет преобразовать инструкции кривой Безье в маленькие сегменты.

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

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

Вот рабочий пример: https://jsbin.com/gecakub/edit?html,js,output

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

Редактировать: это решение будет работать только для шрифтов TTF, хотя может быть легкос поправкой на CCF (.otf), игнорируя ориентацию пути и используя более точную проверку «путь А находится внутри пути B», если только шрифт не имеет пересекающихся путей.

...