FreeType 英文字体显示问题。

时间:2021-06-23 06:10:11
我现在正在使用 FreeType 进行字体显示,现在已经能成功显示文字。但奇怪的是,当我使用 SIMSUN.TTC 即宋体的 TTF Windows 系统字库时,显示出来的英文字和在 Windows 下显示的不一样。尤其是在字体比较小(16 像素,12 号字左右),使用点阵字时更加明显。这个时候,FreeType 渲染的汉字是使用点阵字库,而英文却好像始终为矢量的渲染结果,哪怕关闭反锯齿(即灰度渲染模式)仍然如此,跟在 Windows 中使用 TextOut 函数的渲染结果完全不一样。

后来我找了几篇文章,上面说大部分平台都使使用一个叫 TAHOMA 的字体代替显示中文字体的英文部分,我试试了试,字体果然一样了,但是仍然不是点阵字体,不像 Windows 中那么好看,请问这个问题该如何解决?

还有,顺带问一下,FreeType 中怎样比较快速的进行文字对齐?

13 个解决方案

#1


没人回答吗?我顶!!

#2


没有这方面的经验,只能帮你up

#3


freetype得到的位图是有灰度级别的吧.
不过我在13--16下的汉字显示根本一团糟,为何?

#4


现在已知的信息有:
1. 在某些字体中(TrueType),小号字体将会自动使用点阵字,此时用 FreeType 得到的渲染位图为 1bit per pixel 单色数据,否则就为 8bit per pixel 256 级灰度数据。但奇怪的是当我使用宋体小于 16 像素字体(12 号或以下)时,中文是点阵字,但英文却不是,渲染效果没有 TextOut 好。
2. FreeType 渲染的图像仅仅为字形,也那 . 来说,他渲染的图像为 3x3 像素,然后用户需要自己进行移动,FreeType 给的值有 BearingX 和 BearingY,并且该尺寸是基于基线的,,通过这两个值还无法将其转换为合适的 例如 16x16 像素的位图。(就和 TextOut 的结果一样)。就拿16像素宋体字'宋'举例,它的 BearingX 为 0,BearingY 为 14,渲染位图为 16x16。也就是说,如果想将该字体的所有字符对齐,那么需要将它移动到基线以下,如果我们想将该字体所有字符都转换到 16x16 像素的位图内,那么就需要将所有字符都以基线距离为标准向上移动。接下来有一个好消息,和一个坏消息。好消息是,该字体的最大基线上距离和基线下距离我可以通过 Ascender 和 Descender 得到,我便可以使用这两个值计算出通用位图最大尺寸,即 Ascender - Descender 。然后是坏消息,例如当我使用 16 像素的 Tahoma 字体时,Ascender 为 17,Descender 为 -3 ………好像传说中我使用 FT_Set_Pixel_Sizes 将字体设定为 16 像素了,极其郁闷中~~~

恳请大侠能帮助我,或是给些相关资料的链接。谢谢。

#5


哦,对了,血精灵同志,你的那个问题是当字体很小时,FreeType 将使用 1bit Per Pixel 数据。此类型可以通过 FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 判断。

是不是你该给我点分啊~~嘻嘻。 ^_^

#6


你如果是用于opengl,网上有个FTGL库.包装了它的使用方法.你可以学习一下.

你说的"FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 判断"有啥用?字体
还是一团糟啊.除非有什么参数控制.

#7


-_- 我这里字体显示已经没问题了,主要是排版计算,也就是字体最大范围的计算。

FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 就是告诉你~~存储在 FT_Bitmap.buffer 中的数据不是 1byte per pixel 的灰度数据,而是 1bit per pixel 的点阵数据,因此你需要使用不同的方法将它转换成位图~~

还有你说的 FTGL 我看过了,NeHe 的最新 OpenGL 教程中更是包含了详细的解释~~可惜,它是用改变渲染矩阵来解决问题的,并没有计算字体的最大范围,这在实际的游戏应用中是不可能的。1. 速度太慢 2. 你必须确定字体的最大范围以确定你的背景图是否合适。

#8


哈哈,无奈之下研究了一下 Windows 2000 和 FreeType 的源代码,看明白了它们的算法,我的问题也迎刃而解了!! Oh,Yeah,今儿个老百姓,真呀个真高兴。散分,散分!!

#9


Windows 2000源代码?你吓死我了......

#10


就是前一段泄漏出来的啊,从它的 TextOut 函数开始看,不远就找到了,呵呵~~

#11


我没有.
你找到了什么有趣的?说来听听....

#12


mark

#13


mark

#1


没人回答吗?我顶!!

#2


没有这方面的经验,只能帮你up

#3


freetype得到的位图是有灰度级别的吧.
不过我在13--16下的汉字显示根本一团糟,为何?

#4


现在已知的信息有:
1. 在某些字体中(TrueType),小号字体将会自动使用点阵字,此时用 FreeType 得到的渲染位图为 1bit per pixel 单色数据,否则就为 8bit per pixel 256 级灰度数据。但奇怪的是当我使用宋体小于 16 像素字体(12 号或以下)时,中文是点阵字,但英文却不是,渲染效果没有 TextOut 好。
2. FreeType 渲染的图像仅仅为字形,也那 . 来说,他渲染的图像为 3x3 像素,然后用户需要自己进行移动,FreeType 给的值有 BearingX 和 BearingY,并且该尺寸是基于基线的,,通过这两个值还无法将其转换为合适的 例如 16x16 像素的位图。(就和 TextOut 的结果一样)。就拿16像素宋体字'宋'举例,它的 BearingX 为 0,BearingY 为 14,渲染位图为 16x16。也就是说,如果想将该字体的所有字符对齐,那么需要将它移动到基线以下,如果我们想将该字体所有字符都转换到 16x16 像素的位图内,那么就需要将所有字符都以基线距离为标准向上移动。接下来有一个好消息,和一个坏消息。好消息是,该字体的最大基线上距离和基线下距离我可以通过 Ascender 和 Descender 得到,我便可以使用这两个值计算出通用位图最大尺寸,即 Ascender - Descender 。然后是坏消息,例如当我使用 16 像素的 Tahoma 字体时,Ascender 为 17,Descender 为 -3 ………好像传说中我使用 FT_Set_Pixel_Sizes 将字体设定为 16 像素了,极其郁闷中~~~

恳请大侠能帮助我,或是给些相关资料的链接。谢谢。

#5


哦,对了,血精灵同志,你的那个问题是当字体很小时,FreeType 将使用 1bit Per Pixel 数据。此类型可以通过 FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 判断。

是不是你该给我点分啊~~嘻嘻。 ^_^

#6


你如果是用于opengl,网上有个FTGL库.包装了它的使用方法.你可以学习一下.

你说的"FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 判断"有啥用?字体
还是一团糟啊.除非有什么参数控制.

#7


-_- 我这里字体显示已经没问题了,主要是排版计算,也就是字体最大范围的计算。

FT_Bitmap->pixel_mode == FT_PIXEL_MODE_MONO 就是告诉你~~存储在 FT_Bitmap.buffer 中的数据不是 1byte per pixel 的灰度数据,而是 1bit per pixel 的点阵数据,因此你需要使用不同的方法将它转换成位图~~

还有你说的 FTGL 我看过了,NeHe 的最新 OpenGL 教程中更是包含了详细的解释~~可惜,它是用改变渲染矩阵来解决问题的,并没有计算字体的最大范围,这在实际的游戏应用中是不可能的。1. 速度太慢 2. 你必须确定字体的最大范围以确定你的背景图是否合适。

#8


哈哈,无奈之下研究了一下 Windows 2000 和 FreeType 的源代码,看明白了它们的算法,我的问题也迎刃而解了!! Oh,Yeah,今儿个老百姓,真呀个真高兴。散分,散分!!

#9


Windows 2000源代码?你吓死我了......

#10


就是前一段泄漏出来的啊,从它的 TextOut 函数开始看,不远就找到了,呵呵~~

#11


我没有.
你找到了什么有趣的?说来听听....

#12


mark

#13


mark