字库转换成位图
从字库中读取汉字利用freetype转换成bitmap
1 #include <stdint.h> 2 #include <wchar.h> 3 #include <iconv.h> 4 #include <ft2build.h> 5 #include FT_FREETYPE_H 6 #include FT_GLYPH_H 7 #include FT_ERRORS_H 8 9 #define PRINTF_INFO(pInfo, args...)\ 10 {\ 11 printf("|%s:%d|"pInfo"\n", __FILE__, __LINE__, ##args);\ 12 }\ 13 14 typedef struct 15 { 16 int usWidth; 17 int usHeight; 18 unsigned char* buff; 19 }FontBmp; 20 21 static int 22 GetBitmap( char* szFontFile, wchar_t* swText, 23 uint32_t ulLen, int nFontSize, 24 int nSpace, FontBmp* pFontBmp) 25 { 26 PRINTF_INFO("===enter GetBitmap()==="); 27 FT_Library ftLib = NULL; 28 FT_Face ftFace = NULL; 29 FT_Error ftError = 0; 30 FT_Bitmap ftBitmap; 31 FT_BitmapGlyph ftBmpGlyph; 32 FT_Glyph ftGlyph; 33 FT_GlyphSlot ftGlyphslot; 34 int i, j, k, temp, nBgHeight; 35 int start_x = 0, start_y = 0; 36 int nChHeight = 0, nChWidth = 0, nTextWidth = 0; 37 size_t size = 0; 38 unsigned char** pszTextAlpha = NULL; 39 nBgHeight = nFontSize + 5; /* 背景图形的高度,这个高度要大于字体的高度,所以是+5 */ 40 ftError = FT_Init_FreeType(&ftLib); 41 if (ftError) 42 { 43 PRINTF_INFO("FT_Init_FreeType() Failed!"); 44 ftLib = 0; 45 return -1; 46 } 47 PRINTF_INFO("FT_Init_FreeType() Success!"); 48 ftError = FT_New_Face(ftLib, szFontFile, 0, &ftFace); 49 if (ftError == FT_Err_Unknown_File_Format) 50 { 51 PRINTF_INFO("FT_New_Face() Failed! FT_Err_Unknown_File_Format"); 52 return -2; 53 } 54 else if (ftError) 55 { 56 PRINTF_INFO("FT_New_Face() Failed %d! Other Error!", ftError); 57 return -3; 58 } 59 PRINTF_INFO("FT_New_Face() Success!"); 60 pszTextAlpha = (uint8_t**)malloc(sizeof(uint8_t*)*nBgHeight); //分配内存,用于存储字体背景的数据 61 if (NULL == pszTextAlpha) 62 { 63 PRINTF_INFO("malloc() Failed!"); 64 return -1; 65 } 66 for (i=0; i < nBgHeight; i++) 67 { 68 pszTextAlpha[i] = (uint8_t*)malloc(sizeof(uint8_t)*1); //为背景图的每一行分配内存 69 if (NULL == pszTextAlpha[i]) 70 { 71 PRINTF_INFO("malloc() Failed! %d", i); 72 return -1; 73 } 74 } 75 ftError = FT_Select_Charmap(ftFace, FT_ENCODING_UNICODE); //设置字体的编码方式 76 if (ftError) 77 { 78 PRINTF_INFO("FT_Select_Charmap() Failed!"); 79 return ftError; 80 } 81 ftError = FT_Set_Pixel_Sizes(ftFace, 0, nFontSize); //设置字体大小 82 if (ftError) 83 { 84 PRINTF_INFO("FT_Set_Pixel_Sizes() Failed!"); 85 return ftError; 86 } 87 PRINTF_INFO("FT_Set_Pixel_Sizes() Success!"); 88 ftGlyphslot = ftFace->glyph; 89 for (temp = 0; temp < ulLen; temp++) 90 { 91 ftError = FT_Load_Char(ftFace, swText[temp], FT_LOAD_RENDER | FT_LOAD_NO_AUTOHINT);//提取一个字形图像 92 PRINTF_INFO("swText[%d] = 0x%x", temp, swText[temp]); 93 if (ftError) 94 { 95 PRINTF_INFO("FT_Load_Char() Failed!"); 96 continue; 97 } 98 PRINTF_INFO("FT_Load_Char() Success %d!", temp); 99 ftError = FT_Get_Glyph(ftFace->glyph, &ftGlyph); 100 if (ftError) 101 { 102 PRINTF_INFO("FT_Get_Glyph() Failed!"); 103 return ftError; 104 } 105 if (swText[temp] == L' ') //如果取得的为空格 106 { 107 k = 0; 108 nChWidth = (nFontSize - 2) / 2; 109 nChHeight = nFontSize; 110 nTextWidth = start_x + nChWidth; 111 start_y = 0; 112 for (i = 0; i < nBgHeight; i++) 113 { 114 pszTextAlpha[i] = (uint8_t*)realloc(pszTextAlpha[i], sizeof(uint8_t)*nTextWidth); 115 for (j = start_x - nSpace; j < nTextWidth; j++) 116 { 117 pszTextAlpha[i][j] = 0; 118 } 119 } 120 for (i = 0; i < nChHeight; i++) 121 { 122 for (j=0; j< nChWidth; j++) 123 { 124 pszTextAlpha[start_y+i][start_x+j] = 0; 125 k++; 126 } 127 } 128 start_x += (nChWidth + nSpace);; /* 画笔向右边移动 */ 129 } 130 else 131 { 132 /* 256级灰度字形转换成位图 */ 133 ftError = FT_Glyph_To_Bitmap(&ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1); 134 if (ftError) 135 { 136 PRINTF_INFO("FT_Glyph_To_Bitmap() Failed!"); 137 } 138 PRINTF_INFO("FT_Glyph_To_Bitmap() Success!"); 139 ftBmpGlyph = (FT_BitmapGlyph)ftGlyph; 140 ftBitmap = ftBmpGlyph->bitmap; 141 k = 0; 142 //start_y = nFontSize - ftGlyphslot->bitmap_top + 2; /* 获取起点的y轴坐标 */ 143 start_y = nFontSize - ftBitmap.rows + 2; 144 if (start_y < 0) 145 { 146 start_y = 0; 147 } 148 if (ftBitmap.rows > nBgHeight) 149 { 150 nChHeight = nFontSize; 151 } 152 else 153 { 154 nChHeight = ftBitmap.rows; 155 } 156 157 if (nChHeight + start_y > nBgHeight) 158 { 159 nChHeight = nBgHeight - start_y; 160 } 161 nChWidth = ftBitmap.width; 162 nTextWidth = start_x + ftBitmap.width; 163 for (i=0; i<nBgHeight; i++) 164 { 165 pszTextAlpha[i] = (uint8_t*)realloc(pszTextAlpha[i], sizeof(uint8_t)*nTextWidth); 166 for (j = start_x - nSpace; j < nTextWidth; j++) 167 { 168 pszTextAlpha[i][j] = 0; 169 } 170 } 171 for (i = 0; i < nBgHeight; i++) 172 { 173 for (j = 0; j < nChWidth; j++) 174 { 175 if (i >= start_y && i < start_y + nChHeight) 176 { 177 pszTextAlpha[i][start_x + j] = ftBitmap.buffer[k]; 178 k++; 179 } 180 else 181 { 182 pszTextAlpha[i][start_x + j] = 0; 183 } 184 } 185 } 186 start_x += (nChWidth + nSpace); 187 FT_Done_Glyph(ftGlyph); 188 PRINTF_INFO("FT_Done_Glyph() Success!"); 189 ftGlyph = NULL; 190 } 191 } 192 193 FT_Done_Face(ftFace); 194 ftFace = NULL; 195 FT_Done_FreeType(ftLib); 196 ftLib = NULL; 197 pFontBmp->usWidth = nTextWidth; 198 pFontBmp->usHeight = nBgHeight; 199 size = sizeof(uint8_t) * nTextWidth * nBgHeight; 200 pFontBmp->buff = (uint8_t*)malloc(size); 201 PRINTF_INFO("nTextWidth = %d", nTextWidth); 202 PRINTF_INFO("nBgHeight = %d", nBgHeight); 203 k = 0; 204 //for (int i = 0 ; i < nBgHeight; ++i) 205 //{ 206 // for (int j = 0 ; j < nTextWidth; ++j) 207 // { 208 // pFontBmp->buff[k] = pszTextAlpha[i][j]; 209 // ++k; 210 // } 211 // free(pszTextAlpha[i]); 212 //} 213 for (i = 0; i < nBgHeight; i++) 214 { 215 memcpy(pFontBmp->buff + k, pszTextAlpha[i], sizeof(uint8_t) * nTextWidth); 216 k += nTextWidth; 217 free(pszTextAlpha[i]); 218 } 219 220 free(pszTextAlpha); 221 return 0; 222 } 223 224 static int 225 code_convert( char *src_charset, char *des_charset, 226 const char *inbuf, unsigned int inlen, 227 unsigned char *outbuf, unsigned int outlen ) 228 { 229 iconv_t cd; 230 const char **pin = &inbuf; 231 unsigned char **pout = &outbuf; 232 233 cd = iconv_open(des_charset, src_charset); 234 if (cd == 0) { 235 return -1; 236 } 237 238 memset(outbuf, 0, outlen); 239 240 if (iconv(cd,(char**)pin, &inlen, (char**)pout, &outlen)==-1) { 241 return -1; 242 } 243 244 iconv_close(cd); 245 return 0; 246 } 247 248 #define MAX_SAVE_NUM 20 249 static wchar_t 250 covernt_code(unsigned char in[MAX_SAVE_NUM]) 251 { 252 wchar_t unicode; 253 unicode = in[0]; 254 if (unicode >= 0xF0) { 255 unicode = (wchar_t) (in[0] & 0x07) << 18; 256 unicode |= (wchar_t) (in[1] & 0x3F) << 12; 257 unicode |= (wchar_t) (in[2] & 0x3F) << 6; 258 unicode |= (wchar_t) (in[3] & 0x3F); 259 } else if (unicode >= 0xE0) { 260 unicode = (wchar_t) (in[0] & 0x0F) << 12; 261 unicode |= (wchar_t) (in[1] & 0x3F) << 6; 262 unicode |= (wchar_t) (in[2] & 0x3F); 263 } else if (unicode >= 0xC0) { 264 unicode = (wchar_t) (in[0] & 0x1F) << 6; 265 unicode |= (wchar_t) (in[1] & 0x3F); 266 } 267 268 269 static int 270 utf8_to_unicode(char *in_utf8_str, wchar_t **out_unicode) 271 /* 功能:将UTF-8编码的字符串转换成Unicode编码字符串 */ 272 { 273 wchar_t *buff; 274 unsigned char *p, t, save[MAX_SAVE_NUM]; 275 unsigned int len, i, j, n, count; 276 277 len = strlen(in_utf8_str)+1; 278 buff = (wchar_t *)calloc(sizeof(wchar_t), len); 279 280 for(count=0,i=0,j=0; i<len; ++i) { 281 t = in_utf8_str[i]; 282 /* 结束符的判断 */ 283 if(t == 0) { 284 break; 285 } 286 287 if((t>>7) == 0) {// 0xxxxxxx 288 buff[j] = t; 289 ++j; 290 } 291 else if((t>>5) == 6) {// 110xxxxx 292 count = 2; 293 } 294 else if((t>>4) == 14) {// 1110xxxx 295 count = 3; 296 } 297 else if((t>>3) == 30) {// 11110xxx 298 count = 4; 299 } 300 else if((t>>2) == 62) {// 111110xx 301 count = 5; 302 } 303 else if((t>>1) == 126) {// 1111110x 304 count = 6; 305 } 306 if(count > 0) { 307 p = (unsigned char*)&in_utf8_str[i]; 308 for(n=0; n<count; ++n) { 309 save[n] = *p++; 310 } 311 312 count = 0; 313 buff[j] = covernt_code(save); 314 memset(save, 0, sizeof(save)); 315 ++j; 316 } 317 } 318 /**** 319 printf("result code:"); 320 for(i=0; i<j; ++i) 321 printf("%02x ", buff[i]); 322 printf("\n"); 323 ******/ 324 *out_unicode = buff; 325 return j; 326 } 327 328 static int 329 gb2312_to_unicode(char *in_gb2312_str, wchar_t **out_unicode) 330 /* 功能:将GB2312编码的字符串转换成Unicode编码字符串 */ 331 { 332 char *buff; 333 unsigned char *p; 334 unsigned int len, new_len; 335 336 len = strlen(in_gb2312_str); 337 new_len = len*3; 338 buff = (char *) calloc ( sizeof(char), new_len ); 339 p = (unsigned char*) buff; 340 if(code_convert("gb2312", "utf8", in_gb2312_str, len, p, new_len)) { 341 printf("gb2312_to_unicode(): error\n"); 342 return -1; 343 } 344 len = utf8_to_unicode(buff, out_unicode); 345 free(buff); 346 return len; 347 } 348 349 int Char_To_Wchar_T(char *in_text, wchar_t **unicode_text) 350 /* 351 * 功能:将char型字符串转换成wchar_t字符串 352 * 参数说明: 353 * in_text :传入的char型字符串 354 * unicode_text :输出的wchar_t型字符串 355 * 返回值:正常则wchar_t型字符串的长度,否则返回-1 356 * */ 357 { 358 return gb2312_to_unicode(in_text, unicode_text); 359 //如果你的字符串常量所在的源文件的编码方式是UTF-8,请用下面这行 360 //return utf8_to_unicode(in_text, unicode_text); 361 } 362 363 /* 功能:在屏幕上以0和1表示字体位图 */ 364 int Show_Font_Bitmap(FontBmp *in_fonts) 365 { 366 int x, y; 367 for(y = 0;y < in_fonts->usHeight; ++y) 368 { 369 for(x = 0;x < in_fonts->usWidth; ++x) 370 { 371 if(in_fonts->buff[y * (in_fonts->usWidth) + x] > 0) 372 { 373 printf("1"); 374 } 375 else 376 { 377 printf("0"); 378 } 379 } 380 printf("\n"); 381 } 382 printf("\n"); 383 return 0; 384 } 385 386 387 int Str2Pic(char *pcText) 388 { 389 wchar_t* swText = NULL; 390 uint32 ulLen; 391 FontBmp bmpFont; 392 int nlen = 0; 393 394 //swText = (wchar_t*)calloc(1, sizeof(wchar_t) * strlen(pcText)*2); 395 //ulLen = strlen(pcText) * 2; 396 397 wchar_t* pWchart = Str2Unicode(pcText, &nlen); 398 399 PRINTF_INFO("wchar_t = %d", sizeof(wchar_t)); 400 /* if (0 != GetUnicode_str(swText, &ulLen, pcText)) 401 { 402 free(swText); 403 return -2; 404 }*/ 405 406 // 2、GetFontBmp 407 PRINTF_INFO("pWchart[0] = 0x%x len = %d", pWchart[0], nlen); 408 409 if (0 != GetBitmap("/usr/share/fonts/truetype/Loma.ttf", pWchart, nlen, 20, 2, &bmpFont)) 410 { 411 free(swText); 412 return -3; 413 } 414 415 Show_Font_Bitmap(&bmpFont); 416 417 return 0; 418 } 419 420 int main() 421 { 422 char *pcText = "5汉"; 423 Str2Pic(pcText); 424 return 0; 425 }

浙公网安备 33010602011771号