将TrueType字形转换为OpenGL多边形

15

我正在尝试创建一个转换库,可以将任何安装的TrueType字体转换为一系列多边形,用于在OpenGL中显示文本。我使用GetGlyphOutline函数将字形转换为一系列轮廓,然后使用glu库对这些轮廓进行三角剖分(tesselate)。

这通常有效,但并非总是如此,存在奇怪的例外情况。GetGlyphOutline应该首先以CW绕序返回外轮廓,然后以CCW绕序返回内轮廓(洞)。不幸的是,根据字体和字形,情况并非如此。有时外轮廓以CCW绕序排列,而孔(内轮廓)则以CW绕序排列;或者虽然绕序正确,但GetGlyphOutline返回的轮廓顺序错误(例如,我首先获取“洞”,然后才是外轮廓)。

我尝试调整转换,以检查这些奇怪的情况,并在必要时反转轮廓的顶点和绕序,但似乎没有规则,如果某个字符带有1个或2个孔且在几种字体中运行良好,我总能找到一个例外情况。例如,使用名为MinionPro-BoldCn的字体时,即使数字“8”的字形也会被GetGlyphOutline错误返回,结果我得到的只有一个孔而不是两个。

我还尝试使用GetPath函数将文本渲染成路径,然后使用GetPath函数获取该路径的轮廓。结果是相同的。有些字体会以错误的轮廓顺序和/或错误的绕序返回GetPath函数的特定字符。

有没有人有相关经验,可以做些什么呢?


你可以假设最外层区域是“空的”,然后在填充和不填充封闭区域之间交替。但是,这种方法在自相交的形状中会失效。 - ltjax
也许你的想法大多数时候都是可行的,我自己也有类似的经验,但并非总是如此。由于某种原因,当我将字符(TextOut)作为路径的一部分绘制时,然后使用GetPath读取此路径时,在某些字体的情况下,轮廓正确返回(即外部先以顺时针方向,然后内部以逆时针方向),但对于其他字体,轮廓则无序返回且其方向可能错误。 - aronsatie
绕组对我所建议的没有任何影响。为什么不行呢? - ltjax
由于您无法确定哪些轮廓形成字形的哪些部分。如果较小的轮廓完全位于较大的轮廓内,则它是一个孔,但有一些奇异的语言,其中轮廓可以重叠,并且在字形中有多个外部轮廓。 - aronsatie
这是一个老话题,但我想知道如何解决这个问题。我正在考虑类似的方法来制作我的OpenGL游戏。我还没有做任何事情,但我认为解析TTF或OTF比使用GetGlyphOutline()更好。如果你在线,请给我回电! - user1655141
2个回答

2
也许不是完美的解决方法,但有一个想法(没有想到任何反例):
  1. 忽略绕序
  2. 将所有字形绘制到模板缓冲区中,每次绘制片段时增加模板值1。
  3. 在场景上绘制一个四边形,填充任何模板缓冲区== 1的像素。
我的想法是,任何未被字形覆盖的区域将具有模板值== 0,任何字形内部的区域将具有模板值== 1,并且任何字形内部的孔将具有模板值== 2(因为它们被原始字形和“孔”覆盖)。然后,您可以通过这个来过滤,只绘制模板等于1的区域。

抱歉,在我的情况下那样做行不通。我需要使用多边形(三角形)从字形中创建3D对象。 - aronsatie

0
我已经找到了一条规则来确定轮廓是否限定了字形的外部或内部区域。 对于内部轮廓中的每条边,必须至少有一个点使得三角形呈顺时针顺序。 对于外部轮廓中的边缘,不能有任何点使得三角形呈顺时针顺序。 请参阅TrueType fundamentals中的轮廓部分。

1
链接已失效。https://learn.microsoft.com/en-us/typography/opentype/spec/ttch01#outlines 文档中提到,“黑色空间(填充区域)始终在右侧。” 这意味着轮廓始终是顺时针方向的。 - user1655141

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接