Подтвердить что ты не робот

Преобразование глифов truetype в полигоны OpenGL

Я пытаюсь создать библиотеку преобразования для любого установленного шрифта truetype в ряд полигонов, которые могут использоваться для отображения текста в OpenGL. Я использую функцию GetGlyphOutline для преобразования глифов в ряд контуров, а затем триангуляцию (tesselate) этих контуров с помощью библиотеки glu.

Обычно это работает, но не всегда, и есть странные исключения. Предполагается, что GetGlyphOutline должен возвращать внешние контуры сначала в порядке намотки CW и внутренних контурах (отверстиях) в порядке намотки CCW. В зависимости от шрифта и глифа, к сожалению, это не так. Иногда внешний контур находится в порядке намотки CCW, а отверстия находятся в CW, или хотя порядок намотки верен, порядок контуров, возвращаемых GetGlyphOutline, неверен (например, я сначала получаю "отверстия", а затем внешний контур).

Я попытался настроить преобразование, чтобы проверить эти странные случаи и, если необходимо, перевернуть вершины и порядок намотки контура, но, похоже, нет правила, и если символ с 1 или 2 отверстиями в нем в порядке с несколькими шрифтами, Я всегда нахожу исключение. Например. с шрифтом MinionPro-BoldCn даже глиф для числа "8" неверно возвращается GetGlyphOutline, и я получаю только одно отверстие внутри вместо двух.

Я также попытался использовать другой метод вместо GetGlyphOutline. Я использую GDI для рендеринга текста в путь, а затем получаю контуры этого пути, используя функцию GetPath. Результат тот же. Существуют шрифты, в которых определенные символы возвращаются GetPath с неправильным порядком контуров и/или с неправильной обмоткой.

Есть ли у кого-нибудь опыт в этом и есть ли что-нибудь, что я могу сделать?

4b9b3361

Ответ 1

Возможно, это не идеальное решение, но одна идея (не подумайте о каких-либо контрпримерах):

  • Игнорировать порядок намотки
  • Нарисуйте все глифы в буфер трафарета, увеличивая значение трафарета на 1 каждый раз при рисовании фрагмента.
  • Нарисуйте квад по сцене, заполнив любой пиксель, где буфера трафарета == 1.

Мое мышление состоит в том, что любая область, не покрытая глифом, будет иметь значение трафарета == 0, любая область внутри глифа будет иметь значение трафарета == 1, и любые дыры внутри глифа будут иметь значение трафарета == 2 (поскольку они покрыты оригинальным глифом и "отверстием" ). Затем вы можете фильтровать, чтобы рисовать области, где трафарет равен 1.

Ответ 2

Я выяснил правило, определяющее, что контур ограничивает внешнюю или внутреннюю область глифа. Для каждого ребра во внутреннем контуре должна быть хотя бы одна точка, такая, что треугольник находится в порядке по часовой стрелке. Для края во внешнем контуре не должно быть такой точки, чтобы треугольник находился в порядке по часовой стрелке. см. раздел "Контуры" в Основы TrueType.