AGG 使用字体引擎(Font Engine)

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

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

头文件
  1. #include <agg_font_win32_tt.h>
  2. #include <agg_font_freetype.h>

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

类型
agg::font_engine_win32_tt_int16
agg::font_engine_win32_tt_int32
agg::font_engine_freetype_int16
agg::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;
    typedef fe_type::path_adaptor_type vs_type;
    // 字体引擎
    fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
    fe.height(36.0);
    fe.flip_y(true);
    fe.hinting(true);
    // 注意后面的glyph_rendering ren_type参数
    fe.create_font("黑体",agg::glyph_ren_outline);
    // 字体串
    wchar_t *s = L"C++编程";
    // 存放字体数据
    std::vector<agg::int8u> data;
    // 顶点源
    vs_type vs;
    // 注意这里,使用conv_curve转换
    agg::conv_curve<vs_type> ccvs(vs);
    // 字符输出的位置
    int x=20,y=100;
    for(;*s;s++)
    {
     // 让字体引擎准备好字体数据
     if(!fe.prepare_glyph(*s)) continue;
     // 把字体数据放到容器里
     data.resize( fe.data_size() );
     fe.write_glyph_to( &data[0] );
     // 从字体数据中得到顶点源
     vs.init(&data[0], data.size(), x, y);
     // 移动输出位置
     x += fe.advance_x();
     y += fe.advance_y();
     // 输出
     ras.add_path(ccvs);
     agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(0,0,1));
    }

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

示例代码2 - 从Scanline Rasterizer层输出文字
  1. // 字体引擎类型定义
    typedef agg::font_engine_win32_tt_int16 fe_type;
    typedef fe_type::gray8_adaptor_type ras_type;
    typedef ras_type::embedded_scanline sl_type;
    // 字体引擎
    fe_type fe( ::GetDC(::GetActiveWindow()) ); //注意,实际应用时要释放HDC
    fe.height(36.0);
    fe.flip_y(true);
    fe.hinting(true);
    // 注意后面的glyph_rendering ren_type参数
    fe.create_font("黑体",agg::glyph_ren_agg_gray8);
    // 字体串
    wchar_t *s = L"C++编程";
    // 存放字体数据
    std::vector<agg::int8u> data;
    // Rasterizer和Scanline
    ras_type ras_font;
    sl_type sl_font;
    // 字符输出的位置
    int x=20,y=100;
    for(;*s;s++)
    {
     // 让字体引擎准备好字体数据
     if(!fe.prepare_glyph(*s)) continue;
     // 把字体数据放到容器里
     data.resize( fe.data_size() );
     fe.write_glyph_to( &data[0] );
     // 从字体数据中得到Rasterizer
     ras_font.init(&data[0], data.size(), x, y);
     // 移动输出位置
     x += fe.advance_x();
     y += fe.advance_y();
     // 输出
     agg::render_scanlines_aa_solid(ras_font,sl_font,renb,agg::rgba(0,0,1));
    }
显示效果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这份文档提供了FreeType 2函数库设计与实现的细节。本文档的目标是让开发人员更好的理解FreeType 2是如何组织的,并让他们扩充、定制和调试它。 首先,我们先了解这个库的目的,也就是说,为什么会写这个库: * 它让客户应用程序方便的访问字体文件,无论字体文件存储在哪里,并且与字体格式无关。 * 方便的提取全局字体数据,这些数据在平常的字体格式中普遍存在。(例如:全局度量标准,字符编码/字符映射表,等等) * 方便的提取某个字符的字形数据(度量标准,图像,名字,其他任何东西) * 访问字体格式特定的功能(例如,SFNT表,多重控制,OpenType轮廓表) Freetype 2的设计也受如下要求很大的影响: * 高可移植性。这个库必须可以运行在任何环境中。这个要求引入了一些非常激烈的选择,这些是FreeType2的低级系统界面的一部分。 * 可扩展性。新特性应该可以在极少改动库基础代码的前提下添加。这个要求引入了非常简单的设计:几乎所有操作都是以模块的形式提供的。 * 可定制。它应该能够很容易建立一个只包含某个特定项目所需的特性的版本。当你需要集成它到一个嵌入式图形库的字体服务器中时,这是非常重要的。 * 简洁高效。这个库的主要目标是只有很少cpu和内存资源的嵌入式系统。 这份文档的其他部分分为几个部分。首先,一些章节介绍了库的基本设计以及Freetype 2内部对象/数据的管理。 接下来的章节专注于库的定制和与这个话题相关的系统特定的界面,如何写你自己的模块和如何按需裁减库初始化和编译。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值