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

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

首页休闲益智Root Board Game更新时间:2024-07-30

来源:百问网

作者:韦东山

本文字数: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; 111 112 /* 初始化 */ 113 bbox.xMin = bbox.yMin = 32000; 114 bbox.xMax = bbox.yMax = -32000; 115 116 /* 指定原点为(0, 0) */ 117 pen.x = 0; 118 pen.y = 0; 119 120 /* 计算每个字符的 bounding box */ 121 /* 先 translate, 再 load char, 就可以得到它的外框了 */ 122 for (i = 0; i < wcslen(wstr); i ) 123 { 124 /* 转换:transformation */ 125 FT_Set_Transform(face, 0, &pen); 126 127 /* 加载位图: 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 } 134 135 /* 取出 glyph */ 136 error = FT_Get_Glyph(face->glyph, &glyph); 137 if (error) 138 { 139 printf("FT_Get_Glyph error!\n"); 140 return -1; 141 } 142 143 /* 从 glyph 得到外框: bbox */ 144 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox); 145 146 /* 更新外框 */ 147 if ( glyph_bbox.xMin < bbox.xMin ) 148 bbox.xMin = glyph_bbox.xMin; 149 150 if ( glyph_bbox.yMin < bbox.yMin ) 151 bbox.yMin = glyph_bbox.yMin; 152 153 if ( glyph_bbox.xMax > bbox.xMax ) 154 bbox.xMax = glyph_bbox.xMax; 155 156 if ( glyph_bbox.yMax > bbox.yMax ) 157 bbox.yMax = glyph_bbox.yMax; 158 159 /* 计算下一个字符的原点: increment pen position */ 160 pen.x = slot->advance.x; 161 pen.y = slot->advance.y; 162 } 163 164 /* 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; 177 178 /* 把 LCD 坐标转换为笛卡尔坐标 */ 179 int x = lcd_x; 180 int y = var.yres - lcd_y; 181 182 /* 计算外框 */ 183 compute_string_bbox(face, wstr, &bbox); 184 185 /* 反推原点 */ 186 pen.x = (x - bbox.xMin) * 64; /* 单位: 1/64 像素 */ 187 pen.y = (y - bbox.yMax) * 64; /* 单位: 1/64 像素 */ 188 189 /* 处理每个字符 */ 190 for (i = 0; i < wcslen(wstr); i ) 191 { 192 /* 转换:transformation */ 193 FT_Set_Transform(face, 0, &pen); 194 195 /* 加载位图: 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 } 202 203 /* 在 LCD 上绘制: 使用 LCD 坐标 */ 204 draw_bitmap( &slot->bitmap, 205 slot->bitmap_left, 206 var.yres - slot->bitmap_top); 207 208 /* 计算下一个字符的原点: increment pen position */ 209 pen.x = slot->advance.x; 210 pen.y = slot->advance.y; 211 } 212 213 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”。

做两道题:

修改程序,支持倾斜角度显示一行文字。

修改程序,支持显示多行文字。

点击“了解更多”阅读更多相关章节
查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved