使用 freetype 计算一行文字的外框


使用 freetype 计算一行文字的外框文章插图
来源:百问网
作者:韦东山
本文字数:2620 , 阅读时长:4分钟
前面提到过 , 一行文字中:后一个字符的原点=前一个字符的原点+advance 。
所以要计算一行文字的外框 , 需要按照排列顺序处理其中的每一个字符 。
代码如下 , 注释写得很清楚了:
102 int compute_string_bbox(FT_Face face, wchar_t *wstr, FT_BBox *abbox)103 {104 int i;105 int error;106 FT_BBox bbox;107 FT_BBox glyph_bbox;108 FT_Vector pen;109 FT_Glyph glyph;110 FT_GlyphSlot slot = face->glyph;111112 /* 初始化 */113 bbox.xMin = bbox.yMin = 32000;114 bbox.xMax = bbox.yMax = -32000;115116 /* 指定原点为(0, 0) */117 pen.x = 0;118 pen.y = 0;119120 /* 计算每个字符的 bounding box */121 /* 先 translate, 再 load char, 就可以得到它的外框了 */122 for (i = 0; i < wcslen(wstr); i++)123 {124 /* 转换:transformation */125 FT_Set_Transform(face, 0, 126127 /* 加载位图: load glyph image into the slot (erase previous one) */128 error = FT_Load_Char(face, wstr[i], FT_LOAD_RENDER);129 if (error)130 {131 printf("FT_Load_Char error\n");132 return -1;133 }134135 /* 取出 glyph */136 error = FT_Get_Glyph(face->glyph, 137 if (error)138 {139 printf("FT_Get_Glyph error!\n");140 return -1;141 }142143 /* 从 glyph 得到外框: bbox */144 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, 145146 /* 更新外框 */147 if ( glyph_bbox.xMin < bbox.xMin )148 bbox.xMin = glyph_bbox.xMin;149150 if ( glyph_bbox.yMin < bbox.yMin )151 bbox.yMin = glyph_bbox.yMin;152153 if ( glyph_bbox.xMax > bbox.xMax )154 bbox.xMax = glyph_bbox.xMax;155156 if ( glyph_bbox.yMax > bbox.yMax )157 bbox.yMax = glyph_bbox.yMax;158159 /* 计算下一个字符的原点: increment pen position */160 pen.x += slot->advance.x;161 pen.y += slot->advance.y;162 }163164 /* return string bbox */165 *abbox = bbox;166 }调整原点并绘制代码如下 , 也不复杂:
169 int display_string(FT_Face face, wchar_t *wstr, int LCD_x, int lcd_y)170 {171 int i;172 int error;173 FT_BBox bbox;174 FT_Vector pen;175 FT_Glyph glyph;176 FT_GlyphSlot slot = face->glyph;177178 /* 把 LCD 坐标转换为笛卡尔坐标 */179 int x = lcd_x;180 int y = var.yres - lcd_y;181182 /* 计算外框 */183 compute_string_bbox(face, wstr, 184185 /* 反推原点 */186 pen.x = (x - bbox.xMin) * 64; /* 单位: 1/64 像素 */187 pen.y = (y - bbox.yMax) * 64; /* 单位: 1/64 像素 */188189 /* 处理每个字符 */190 for (i = 0; i < wcslen(wstr); i++)191 {192 /* 转换:transformation */193 FT_Set_Transform(face, 0, 194195 /* 加载位图: load glyph image into the slot (erase previous one) */196 error = FT_Load_Char(face, wstr[i], FT_LOAD_RENDER);197 if (error)198 {199 printf("FT_Load_Char error\n");200 return -1;201 }202203 /* 在 LCD 上绘制: 使用 LCD 坐标 */204 draw_bitmap( 207208 /* 计算下一个字符的原点: increment pen position */209 pen.x += slot->advance.x;210 pen.y += slot->advance.y;211 }212213 return 0;214 }上机实验编译命令(如果你使用的交叉编译链前缀不是 arm-buildroot-linux-gnueabihf , 请自行修改命令):
$ arm-buildroot-linux-gnueabihf-gcc -o show_line show_line.c -lfreetype将编译好的 show_line 文件与 simsun.ttc 字体文件拷贝至开发板 , 这 2 个文件放在同一个目录下 , 然后执行以下命令(其中的 3 个数字分别表示 LCD 的 X 坐标、Y 坐标、字体大小):
[root@board:~]# ./show_line ./simsun.ttc 10 200 80如果实验成功 , 可以在 LCD 上看到一行文字“百问网 www.100ask.net” 。
做两道题:修改程序 , 支持倾斜角度显示一行文字 。
修改程序 , 支持显示多行文字 。
【使用 freetype 计算一行文字的外框】「新品首发」STM32MP157开发板火爆预售!首批仅300套
点击“了解更多”阅读更多相关章节