齐白石画:AGG 使用字体引擎(Font Engine)

来源:百度文库 编辑:九乡新闻网 时间:2024/04/27 08:24:23
AGG 使用字体引擎(Font Engine)2010-07-11 22:08

方式二、使用字体引擎(Font Engine)

AGG的字体引擎利用WinAPI:GetGlyphOutline或FreeType库得到字体数据(字模),它可以处于 “Scanline Rasterizer”层或“顶点源”层。要使用字体引擎,要把相应的字体引擎源码(agg_font_win32_tt.cpp或 agg_font_freetype.cpp)加入项目一起编译。

头文件

  1. #include
  2. #include

注意,它们都有自己的文件夹,不是在agg的include文件夹里。

类型

agg::font_engine_win32_tt_int16agg::font_engine_win32_tt_int32agg::font_engine_freetype_int16agg::font_engine_freetype_int32

显然,前两个利用WinAPI实现,后两个利用FreeType库实现。类型后面的_int16或_int32后缀用于指定坐标单位, 一般int16已经可以满足要求。

成员类型定义:

typedef path_adaptor_type把字体数据包装成顶点源的类typedef gray8_adaptor_type把字体数据包装成Scanline Rasterizer的类typedef mono_adaptor_type把字体数据包装成Scanline Rasterizer的类,但无AA效果

成员属性:

double: height字体高度,单位为Point(和Word里的单位一样)double: width字体宽度,单位为Point*2.4。0表示规则大小(height/2.4)bool: italic斜体bool: flip_y上下翻转bool: hinting字体修正unsigned: resolution字体解析度,单位为dpi

成员方法:

void transform(const trans_affine& affine);按矩阵变换bool create_font(const char* typeface_,
glyph_rendering ren_type);font_engine_win32_tt_*专有方法
建立字体,typeface_为字体名,ren_type稍后再说bool load_font(const char* font_name,
unsigned face_index,
glyph_rendering ren_type,
const char* font_mem = 0,
const long font_mem_size = 0);font_engine_freetype_*专有方法
建立字体,font_name是字体文件名或字体名bool prepare_glyph(unsigned glyph_code)
unsigned data_size() const
void write_glyph_to(int8u* data) const得到字体数据(字模)所需方法

字体引擎的create_font()方法和load_font()方法需要一个glyph_rendering类型的ren_type参数,它决定了字 体数据的形式。三个成员类型定义:path_adaptor_type、gray8_adaptor_type和mono_adaptor_type所包 装的字体数据是 不一样的,只有与ren_type参数对应才能生成正确的AGG显示节点。

glyph_rendering是一个枚举类型,定义是:

  1. enum agg::glyph_rendering{
  2.      glyph_ren_native_mono,   //对应mono_adaptor_type
  3.      glyph_ren_native_gray8,   //对应gray8_adaptor_type
  4.      glyph_ren_outline,    //对应path_adaptor_type
  5.      glyph_ren_agg_mono,   //对应mono_adaptor_type
  6.      glyph_ren_agg_gray8    //对应gray8_adaptor_type
  7. };

示例代码1 - 从顶点源层输出文字

  1. typedef agg::font_engine_win32_tt_int16 fe_type;
  2. typedef fe_type::path_adaptor_type vs_type;
  3. // 字体引擎
  4. fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
  5. fe.height(36.0);
  6. fe.flip_y(true);
  7. fe.hinting(true);
  8. // 注意后面的glyph_rendering ren_type参数
  9. fe.create_font("黑体",agg::glyph_ren_outline);
  10. // 字体串
  11. wchar_t *s = L"C++编程";
  12. // 存放字体数据
  13. std::vector data;
  14. // 顶点源
  15. vs_type vs;
  16. // 注意这里,使用conv_curve转换
  17. agg::conv_curve ccvs(vs);
  18. // 字符输出的位置
  19. int x=20,y=100;
  20. for(;*s;s++)
  21. {
  22.     // 让字体引擎准备好字体数据
  23.     if(!fe.prepare_glyph(*s)) continue;
  24.     // 把字体数据放到容器里
  25.      data.resize( fe.data_size() );
  26.      fe.write_glyph_to( &data[0] );
  27.     // 从字体数据中得到顶点源
  28.      vs.init(&data[0], data.size(), x, y);
  29.     // 移动输出位置
  30.      x += fe.advance_x();
  31.      y += fe.advance_y();
  32.     // 输出
  33.      ras.add_path(ccvs);
  34.      agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));
  35. }

由于字体顶点源可能会包含带Curve命令的顶点,所以要用conv_curve来 转换。你可以试试去掉这层转换,字符'C' 就不会那么平滑了。

示例代码2 - 从Scanline Rasterizer层输出文字

  1. // 字体引擎类型定义
  2. typedef agg::font_engine_win32_tt_int16 fe_type;
  3. typedef fe_type::gray8_adaptor_type ras_type;
  4. typedef ras_type::embedded_scanline sl_type;
  5. // 字体引擎
  6. fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
  7. fe.height(36.0);
  8. fe.flip_y(true);
  9. fe.hinting(true);
  10. // 注意后面的glyph_rendering ren_type参数
  11. fe.create_font("黑体",agg::glyph_ren_agg_gray8);
  12. // 字体串
  13. wchar_t *s = L"C++编程";
  14. // 存放字体数据
  15. std::vector data;
  16. // Rasterizer和Scanline
  17. ras_type ras_font;
  18. sl_type sl_font;
  19. // 字符输出的位置
  20. int x=20,y=100;
  21. for(;*s;s++)
  22. {
  23.     // 让字体引擎准备好字体数据
  24.     if(!fe.prepare_glyph(*s)) continue;
  25.     // 把字体数据放到容器里
  26.      data.resize( fe.data_size() );
  27.      fe.write_glyph_to( &data[0] );
  28.     // 从字体数据中得到Rasterizer
  29.      ras_font.init(&data[0], data.size(), x, y);
  30.     // 移动输出位置
  31.      x += fe.advance_x();
  32.      y += fe.advance_y();
  33.     // 输出
  34.      agg::render_scanlines_aa_solid(ras_font,sl_font,renb,agg::rgba(0,0,1));
  35. }

显示效果