字库转换成位图

从字库中读取汉字利用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 }

 

posted @ 2013-02-22 11:22  bit by bit  阅读(1483)  评论(0)    收藏  举报