zoukankan      html  css  js  c++  java
  • 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~~

     

     

  • 相关阅读:
    【cocos2d-js公文】十七、事件分发机制
    UVA它11292
    定义自己的仪表板DashBoard
    ufldl学习笔记和编程作业:Feature Extraction Using Convolution,Pooling(卷积和汇集特征提取)
    互联网和移动互联网怎么赚钱?
    android布局margin和padding差异!
    解决ORA-28000: the account is locked
    网络编程基本知识
    10个优秀的 HTML5 &amp; CSS3 下拉菜单制作教程
    Codeforces554A:Kyoya and Photobooks
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167782.html
Copyright © 2011-2022 走看看