GTK+(基于DirectFB)的字体处理

GTK+(基于DirectFB)的字体处理

 

转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

作者联系方式:Li XianJing <xianjimli at hotmail dot com>

更新时间:2006-12-19

 

GTK+(基于DirectFB)的字体绘制是通过pango+freetype+fontconfig三者协作来完成的,其中,fontconfig负责字体的管理和配置,freetype负责单个字符的绘制,pango则完成对文字的排版布局。这几天花了点时间研究GTK+的字体处理,这里记录一些笔记。

 

pango排版文字,首先要创建一个PangoLayout对象。一般来说,不必直接调用pango_layout_new函数创建,而是调用gtk提供的包装函数gtk_widget_create_pango_layout。在该函数又调用gtk_widget_get_pango_context函数获得PangoContext对象。

 

什么是PangoContext呢?顾名思义,PangoContext就是用来保存Pango上下文信息的。其中最重要的是PangoFontMap对象,从字面上讲PangoFontMap是从字体描述到字体之间的映射,它的实际功能就是加载字体。它根据字体的描述,调用fontconfig的函数找到对应的字体文件,然后调用freetype的函数加载该字体。

 

l         字体的初始化。

字体的初始化并不是在gtk_init函数完成中,而是在实际使用字体时才初始化。调用路径为

u       gtkwidget.c: gtk_widget_get_pango_context

u       gtkwidget.c: gtk_widget_create_pango_context

u       gdkpango-directfb.c: gdk_pango_context_get

u       pangoft2-fontmap.c: pango_ft2_get_context

u       pangoft2-fontmap.c: pango_ft2_font_map_for_display

u       pangoft2-fontmap.c: pango_ft2_font_map_new

u       ftinit.c: FT_Init_FreeType

 

初始化并不加载任何字体,字体的加载是根据需要,要任何时候都可以加载。在初始化时,主要是加载freetype的后端。内置的Freetype后端是在ftmodule.h里定义的,可以在此进行裁减,默认内置的后端有:

FT_USE_MODULE(autofit_module_class)

FT_USE_MODULE(tt_driver_class)

FT_USE_MODULE(t1_driver_class)

FT_USE_MODULE(cff_driver_class)

FT_USE_MODULE(t1cid_driver_class)

FT_USE_MODULE(pfr_driver_class)

FT_USE_MODULE(t42_driver_class)

FT_USE_MODULE(winfnt_driver_class)

FT_USE_MODULE(pcf_driver_class)

FT_USE_MODULE(psaux_module_class)

FT_USE_MODULE(psnames_module_class)

FT_USE_MODULE(pshinter_module_class)

FT_USE_MODULE(ft_raster1_renderer_class)

FT_USE_MODULE(sfnt_module_class)

FT_USE_MODULE(ft_smooth_renderer_class)

FT_USE_MODULE(ft_smooth_lcd_renderer_class)

FT_USE_MODULE(ft_smooth_lcdv_renderer_class)

FT_USE_MODULE(otv_module_class)

FT_USE_MODULE(bdf_driver_class)

 

l         字体的加载。

程序第一次显示文字或者后面改变文字的字体,都可能会导致字体加载。在pango排版时,若对应的字体没有加载,它会调用pango_fc_font_map_load_fontset函数去加载该字体。

 

函数pango_fc_font_map_get_patterns会根据字体的描述,调用FcPatternBuild创建一个patternpatternfontconfig的一个术语,fontconfig根据pattern的描述,在配置文件中查找最接近要求的字体,这是一种模糊查询,不必定义精确的查找条件, 它通常始终会返回一种相近的字体。

 

如果pattern对应的字体没有加载,则调用pango_fc_font_map_new_font加载该字体。转了N道弯之后,来到了pango_ft2_font_get_face函数,该函数从pattern中取出一些参数,其中最重要的是字体文件名,然后调用FT_New_Face真正加载字体。

 

l         字体的匹配。

如果没有fontconfig的帮助,要精确的指定字体参数是件痛苦的事情。那些神秘的参数很容易把人搞晕了,即使指定了正确的字体参数,换一个系统如果没有该字体,程序可能就完全不能运行了。而在fontconfig的帮助下,你只要说明对字体的要求,fontconfig总是可以帮你找到最接近要求的字体。

 

Fontconfig的主配置文件在/etc/fonts/目录里,也可以在~/.fonts目录下存放用户自己的配置信息。/etc/fonts/fonts.conf文件是默认的配置,一般不要修改它,但可以修改/etc/fonts/local.conffonts.conf包含了local.conf

 

配置文件里的dir段指明了字体文件存放的路径,在小机上,字体的存放路径一般与PC上不同,所以可能要修改dir段,加入实际字体文件所在的路径。其它配置一般不用修改,使用默认的即可。

 

要注意,字体有三类,SerifSans serifMonospacesans”来源于古法语, 意为“without, 即“非”。 而“serif”来源于荷兰语, 译为衬线, 指字母的拐角或端点位置的修饰线。SerifSans serif是非等宽字体,而Monospace是等宽字体。通过下面的实际效果可以看出它们的差异。

 

Serif : E

Sans serif : E

Monospace: Courier

 

l         字体的显示。

pango_ft2_font_render_glyph函数调用了FT_Load_Glyph去加载字模数据,我想当然的       认为字体是在pangoft2-render.c中绘制的,而且GTK/GDK都不应该知道freetype的细节信息,否则两者之间的耦合就太死了。

 

但是事实是,Pango排版完成后,并没有管字体显示的问题。字体真正显示是在gdk_directfb_draw_glyphs函数里完成的,它调用_glyph_surface_cache_get_surface函数把freetype的字模bitmap拷贝到一个surface里,然后把该surface中的内容blit到窗口的surface上。

 

l         修改widget的字体。

修改widget的字体很简单,调用gtk_widget_modify_font函数即可。如:

PangoFontDescription *desc = pango_font_description_from_string("Serif 12");

gtk_widget_modify_font(widget, desc);

pango_font_description_free(desc);

 

l         GTK+2.6 + DirectFB-0.9.22关于字体问题的BUG

字体无法显示Fontconfig配置正确,对应的字体文件也存在,但是字体就是显示不出来。原因在于,字体显示实际上中调用的函数gdk_draw_glyphs_transformed而不是gdk_draw_glyphs,而函数gdk_draw_glyphs_transformedgdk-directfb中并没有实现,这导致了字体无法显示。解决方法:若不存在旋转字体,可以直接用gdk_draw_glyphs来实现gdk_draw_glyphs_transformed

 

大部文字都带有下划线,界面显得很怪异。原因在于,glyphsurfacecache.c中的函数surface_new创建surface后没有把surface清理一下,里面有些垃圾数据,而字模又并不一定完全占满整个surface,所以这些垃圾数据也被Blit到窗口上了。解决方法:这可以在调用CreateSurface成功后,再调用一下Clear函数。

 

参考资料:

http://jorux.com/archives/property-2-if-you-love-css/

http://fontconfig.org

http://www.gtk.org/

 

~~end~~

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
交叉编译libx加GTK+2.1时候用到库各个库文件的集合,不用花费时间网上一个一个下载,已经经过本人亲测试实测,还可以编译GTK+directFB 1.1 libs_for_gtk Dir: atk-1.25.2.tar.gz atk-1.26.0.tar.gz bigreqsproto-1.1.2.tar.bz2 cairo-1.8.6.tar.gz CPAN-1.94.tar.gz DirectFB-1.1.1.tar.gz expat-2.0.1.tar.gz expat-2.1.0.tar.gz ExtUtils-MakeMaker-6.20.tar.gz fontconfig-2.4.2.tar.gz fontconfig-2.6.0.tar.gz fontconfig-2.7.3.tar.gz freetype-2.3.5.tar.bz2 freetype-doc-2.3.6.tar.bz2 glib-2.12.1.tar.bz2 glib-2.14.4.tar.gz glib-2.18.2.tar.bz2 glibc-2.2.5.tar.bz2 gtk+-2.10.14.tar.bz2 gtk+-2.10.7.tar.bz2 gtk+-2.12.12.tar.bz2 inputproto-2.2.tar.bz2 jpegsrc.v6b.rar jpegsrc.v6b.tar.gz kbproto-1.0.6.tar.bz2 libpng-1.2.10.tar.bz2 libpng-1.2.32.tar.lzma libpthread-stubs_0.1.orig.tar.gz libtool-1.5.22.tar.gz libtool-2.4.2.tar.xz libX11-1.0.3.tar.bz2 libX11-1.2.2.tar.bz2 libX11-1.3.2.tar.gz libX11-1.5.0.tar.bz2 libXau-1.0.7.tar.bz2 libXau-1.0.8.tar.bz2 libxcb-1.3.tar.bz2 libxcb-1.4.tar.bz2 libxcb-1.8.1.tar.bz2 libXdmcp-1.0.3.tar.gz libXdmcp-1.1.2.tar.bz2 libXext-1.0.1.tar.bz2 libXfont-1.4.4.tar.bz2 libXft-2.1.12.tar.bz2 libXft-2.1.13.tar.bz2 libxml2-2.6.30.tar.gz libxml2-2.6.32.tar.gz libxslt-1.1.29.tar.gz libXt-1.0.6.tar.bz2 pango-1.16.4.tar.bz2 pango-1.18.2.tar.gz pango-1.22.1.tar.bz2 pango-1.24.4.tar.bz2 pixman-0.24.0.tar.bz2 poky-pinky-3.1.1.tgz stubs-soft.h tiff-3.8.2.tar.gz tiff-4.0.7.tar.gz tslib-1.4.tar.gz xcb-proto-1.7.1.tar.bz2 xcmiscproto-1.1.2.tar.bz2 xcmiscproto-1.2.2.tar.bz2 xextproto-7.2.1.tar.bz2 xorg-server-1.3.0.0.tar.bz2 xorg-server-1.4.2.tar.bz2 xproto-7.0.23.tar.bz2 xtrans-1.2.7.tar.bz2 zlib-1.2.3.rar zlib-1.2.3.tar.gz zlib-1.2.5.tar.gz
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值