电子产品量产工具-学习笔记(3)字体显示部分

项目代码链接:https://github.com/studyalldaya/100ask_project1

freetype库

freetype2库相关博客可以参考:

  1. FreeTpye库学习笔记:将矢量字体解析为位图
  2. FreeType2
  3. FreeType2使用总结

一般使用就是

  1. 使用 FT_Init_FreeType() 函数初始化一个 FT_Library 句柄。
int ret;
    FT_Library library;
    /* 显示矢量字体 */
    ret = FT_Init_FreeType(&library);               /* initialize library */
    if (ret) {
        printf("FT_Init_FreeType err\n");
        return -1;
    }
  1. 通过字体文件名加载FT_Face
ret = FT_New_Face(library, file_path, 0, &face); /* create face object */
    if (ret) {
        printf("FT_New_Face err\n");
        return -1;
    }
  1. 此处设置字体编码方式为Unicode,如果不设置,FreeType默认为 utf-16编码类型
FT_Select_Charmap(face, FT_ENCODING_UNICODE);
  1. 设置字体大小
//设置成12*12像素,  0表示和另一个值相等!
    FT_Set_Pixel_Sizes(face, defaultFontSize, 0);
  1. 设置旋转角度及原点位置,加载字形位图
    直接使用 FT_Load_Char() 来代替 FT_Get_Char_Index()、FT_Get_Load_Glyph() 和 FT_Render_Glyph(),一步到位,例如:
FT_Set_Transform(face, 0, &pen);//0表示不旋转
/* 加载位图,默认RGB888 */
    error = FT_Load_Char(face, code, FT_LOAD_RENDER);//加载face.glyph
    if (error) {
        printf("FT_Load_Char error\n");
        return -1;
    }

其中 FT_LOAD_RENDER 表示直接将图像转为位图,所以不需要使用 FT_Render_Glyph() 函数。
该函数默认生成的位图是 FT_RENDER_MODE_NORMAL 类型,即 RGB888。

使用这个库时要注意头文件的包含目录应该到${INC_DIR}/freetype2,
单位为1/64像素

底层通过freetype获得bitmap

fbt->currOriginX和fbt->currOriginY有函数参数fbt提供,即要

static int freetype_get_bitmap(unsigned int code, Font_bitmap *fbt)
{
    int error;
    FT_Vector pen;
    FT_Glyph glyph;
    FT_GlyphSlot slot;
    /*得到开始位置*/
    pen.x = fbt->currOriginX * 64; /* 单位: 1/64像素 */
    pen.y = fbt->currOriginY * 64; /* 单位: 1/64像素 */
    /* 设置旋转以及位置 */
    FT_Set_Transform(face, 0, &pen);//0表示不旋转

    /* 加载位图,默认RGB888 */
    error = FT_Load_Char(face, code, FT_LOAD_RENDER);//加载face.glyph
    if (error) {
        printf("FT_Load_Char error\n");
        return -1;
    }
    slot = face->glyph;

    fbt->buffer = slot->bitmap.buffer;

    fbt->region.x = slot->bitmap_left;
    fbt->region.y = fbt->currOriginY * 2 - slot->bitmap_top;
    fbt->region.width = slot->bitmap.width;
    fbt->region.height = slot->bitmap.rows;
    fbt->nextOriginX = fbt->currOriginX + slot->advance.x / 64;
    fbt->nextOriginY = fbt->currOriginY;

    return 0;
}

同样提供注册函数给上层manager。

void freetype_font_register(void)
{
    register_font_style(&freetype_style);
}

上层manager

用Font_bitmap 表示一个字符的相关信息,有它的region、freetype的origin原件,表示字符的位图的buffer。
用Font_style 表示字体显示的方式,可以是普通点阵也可以是用freetype的矢量字体,这里使用freetype。

typedef struct Font_bitmap {
    Region region;

    int currOriginX;//freetype 当前基点的x
    int currOriginY;
    int nextOriginX;
    int nextOriginY;

    unsigned char *buffer;
} Font_bitmap;

typedef struct Font_style {
    char *name;//用普通点阵还是使用freetype

    int (*font_init)(char *fname);
    int (*font_set_size)(int size);
    int (*font_get_bitmap)(unsigned int code, Font_bitmap *fbt);//code:编码值
    int (*font_get_text_bbox)(char *str, Cartesian_region *textBBox);
    struct Font_style *next;
} Font_style;

manager这层主要是对外提供一些api函数,首先和其它模块一样用链表把不同style链接起来,方便后续进行扩展。

extern void freetype_font_register(void);

void register_font_style(Font_style *fs)
{
    fs->next = fontStyleHead;
    fontStyleHead = fs;
}

void font_init(void)
{
    freetype_font_register();
}

注册完底层的style之后,可以根据name来选择作为默认的style,就是遍历链表,找到对应的那个节点,并调用那个节点的init函数。

//传入style以及  ttc文件 or ttf文件 ttf为字形文件,ttc里面含有多个ttf也就是含有多个字形,通过不同编码找到对应字形
int select_and_init_font(char *style, char *file_path)
{
    Font_style *ptTmp = fontStyleHead;
    while (ptTmp) {
        if (strcmp(ptTmp->name, style) == 0)
            break;
        ptTmp = ptTmp->next;
    }

    if (!ptTmp)
        return -1;

    defaultFontStyle = ptTmp;
    return ptTmp->font_init(file_path);
}

api一般只是返回对应的默认设备的相应函数即可,把底层函数细节隐藏起来。

int font_get_bitmap(unsigned int code, Font_bitmap *fbm)
{
    return defaultFontStyle->font_get_bitmap(code, fbm);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值