嵌入式 Linux下利用FreeType2的API实现字符的显示

网上的FreeType2例子太少,能显示汉字的比较难找,C语言代码写的更难找,能找到的,基本上是被转载了N遍的同一个示例代码,基本上解决不了我的问题。

于是乎,花费了不少时间才完成了这些代码;

主要功能是:

将传入的GB2312编码的char型字符串转换成图片数组并输出。

主要原理是:

将GB2312编码的char型字符串,转换成unicode编码的wchar_t型字符串;

之后,利用FreeType2的API获取汉字的字体位图。

代码看似不怎么复杂,之前找char转wchar_t的代码,没找到一个合适的,最后呢,东拼西凑,就得到了想要的代码;

还有,输出的是记录每个像素点的256级灰度的数组,也就是和png图片中alpha通道一样,0- 255表示透明度, 0为完全透明,255为不透明;

想要将这些文字贴到图片上,有个公式:

r2 = (r1 * alpha + r2 * (255 - alpha)) /255;
g2 = (g1 * alpha + g2 * (255 - alpha)) /255;
b2 = (b1 * alpha + b2 * (255 - alpha))/255;

r、g、b表示图片的red、greenblue三种颜色,这三种颜色通过组合可以变成不同的颜色;

alpha是文字位图的alpha通道; 

r2、b2g2是图片重叠后该像素点显示的颜色;
r1、b1g1是文字位图的每个像素点显示的颜色。

相关信息请参考这篇文章:http://www.linuxidc.com/Linux/2012-01/52144.htm

有需要这些代码的人的话,请把代码改一下,因为这是从我的LCUI图形库的代码中复制过来的,不能直接使用。


[cpp]

      #include"LCUI_Build.h"   
      #includeLCUI_MAIN_H   
      #includeLCUI_FONTS_H     
      #include"all.h"   
         
       
      intcode_convert(char *from_charset,char *to_charset,const char*inbuf,unsigned int inlen,  
      unsignedchar *outbuf,unsigned int outlen)  
      { 
              iconv_t cd;  
              const char **pin = &inbuf;  
              unsigned char **pout = &outbuf; 
              cd = iconv_open(to_charset,from_charset);  
              if (cd==0) return -1;  
              memset(outbuf,0,outlen);  
              if(iconv(cd,(char**)pin,&inlen,(char**)pout,&outlen)==-1)return -1;  
              iconv_close(cd);  
              return 0;  
      } 
         
       
      intGB2312_To_UTF8(const char *inbuf,unsigned int inlen,unsigned char*outbuf,unsigned int outlen)  
      { 
              return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen); 
      } 
         
      unsignedshort Get_Unicode(char *in_gb2312)  
      { 
              unsigned char out[256];  
              int rc;  
              unsigned int length_gb2312;  
         
               
              length_gb2312 = strlen(in_gb2312);  
              rc = GB2312_To_UTF8(in_gb2312,length_gb2312,out,256); 
         
               
              unsigned short unicode;  
              unicode = out[0];  
              if (unicode >= 0xF0) {  
                      unicode = (unsigned short) (out[0] & 0x07)<< 18;  
                      unicode |= (unsigned short) (out[1] & 0x3F)<< 12;  
                      unicode |= (unsigned short) (out[2] & 0x3F)<< 6;  
                      unicode |= (unsigned short) (out[3] & 0x3F); 
              } else if (unicode >= 0xE0) { 
                      unicode = (unsigned short) (out[0] & 0x0F)<< 12;  
                      unicode |= (unsigned short) (out[1] & 0x3F)<< 6;  
                      unicode |= (unsigned short) (out[2] & 0x3F); 
              } else if (unicode >= 0xC0) { 
                      unicode = (unsigned short) (out[0] & 0x1F)<< 6;  
                      unicode |= (unsigned short) (out[1] & 0x3F); 
              }  
              return unicode;  
      } 
         
         
         
         
      intShow_Font_Bitmap(Font_Bitmap_Data *in_fonts) 
       
      { 
              int x,y;  
              for(y=0;y<in_fonts->height;++y){ 
                      for(x=0;x<in_fonts->width;++x){ 
                              if(in_fonts->text_alpha[y*in_fonts->width+x]>0) 
                              printf("1");  
                              else printf("0");  
                      }  
                      printf("\n");  
              }  
              printf("\n");  
              return 0;  
      } 
         
         
         
         
      intGet_Fonts_Bitmap(  
      char*font_file,                         
      char*in_text,                             
      intfonts_pixel_size,               
      intspace,                                     
      Font_Bitmap_Data *out_fonts   
      ) 
       
       
       
       
       
      { 
              FT_Library                p_FT_Lib =NULL;       
              FT_Face                      p_FT_Face =NULL;           
              FT_Error                    error = 0;  
              FT_Bitmap                  bitmap;  
              FT_BitmapGlyph        bitmap_glyph;  
              FT_Glyph                    glyph;  
              FT_GlyphSlot            slot;  
              int i , j ,temp,num,bg_height;  
              char error_str[200];  
              error = FT_Init_FreeType( &p_FT_Lib);   
              if (error)     
              {  
                      p_FT_Lib = 0 ;  
                      printf(FT_INIT_ERROR);  
                      return - 1 ;  
              }  
               
              error = FT_New_Face(p_FT_Lib, font_file , 0 , &p_FT_Face);  
              if ( error == FT_Err_Unknown_File_Format )   
              {   
                      printf(FT_UNKNOWN_FILE_FORMAT);  
                      return - 1 ;  
              }   
              else if (error)  
              {  
                      printf(FT_OPEN_FILE_ERROR);  
                      perror("FreeeType2");  
                      return - 1 ;  
              }  
              j = 0;  
              wchar_t *unicode_text;  
              char ch[256];  
              unicode_text =(wchar_t*)calloc(1,sizeof(wchar_t)*(strlen(in_text)*2)); 
              for(i=0;i<strlen(in_text);++i){ 
                      memset(ch,0,sizeof(ch));   
                      ch[0] = in_text[i];   
                      if(ch[0] < 0) {   
                               
                              if(i < strlen(in_text)-1){  
                                      ch[1] = in_text[i+1];  
                                      ++i;  
                              }  
                              else break;  
                      }  
                      unicode_text[j] = Get_Unicode(ch);   
                      ++j;  
              }  
              num = j;  
                 
              int start_x = 0,start_y = 0;  
              int ch_height = 0,ch_width = 0;  
              int k,text_width = 0;  
              size_t size = 0;  
              unsigned char **text_alpha;   
              bg_height = fonts_pixel_size+5;  
               
              text_alpha = (unsigned char**)malloc(sizeof(unsignedchar*)*bg_height);   
              for(i=0;i<bg_height;++i){  
               
                      text_alpha[i] = (unsigned char*)malloc(sizeof(unsignedchar)*1);   
              }  
              FT_Select_Charmap(p_FT_Face,FT_ENCODING_UNICODE);     
              FT_Set_Pixel_Sizes(p_FT_Face,0,fonts_pixel_size);     
         
              slot = p_FT_Face->glyph;  
              for(temp=0;temp<num;++temp){ 
                       
                       
                      error = FT_Load_Char( p_FT_Face,unicode_text[temp],  FT_LOAD_RENDER |FT_LOAD_NO_AUTOHINT);   
                      if(!error){  
                               
                               
                              error = FT_Get_Glyph(p_FT_Face -> glyph,&glyph);  
                              if (!error)  
                              {  
                                      if(unicode_text[temp] == ' ') {  
                                               
                                              k = 0;  
                                              ch_width    = (fonts_pixel_size-2)/2;  
                                              ch_height  = fonts_pixel_size; 
                                              text_width = start_x + ch_width;  
                                              start_y = 0;  
                                              for(i=0;i<bg_height;++i){  
                                                      text_alpha[i] = (unsignedchar*)realloc(text_alpha[i],sizeof(unsigned char)*text_width); 
                                                      for(j=start_x-space;j<text_width;++j)text_alpha[i][j] = 0;  
                                              }  
                                              for ( i = 0 ; i < ch_height; ++i) 
                                              {  
                                                      for ( j = 0 ; j < ch_width; ++j) 
                                                      {  
                                                              text_alpha[start_y + i][start_x + j] = 0;  
                                                              ++k;  
                                                      }  
                                              }  
                                              start_x += (ch_width+space);  
                                      }  
                                      else{  
                                               
                                              FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0,1);  
                                               
                                              bitmap_glyph = (FT_BitmapGlyph)glyph;  
                                              bitmap            = bitmap_glyph -> bitmap;  
                                              k = 0;  
                                                 
                                              start_y = fonts_pixel_size - slot->bitmap_top + 2; 
                                              if(start_y < 0) start_y = 0; 
                                              if(bitmap.rows > bg_height) ch_height =fonts_pixel_size;  
                                              else ch_height = bitmap.rows;  
                                              if(ch_height+start_y > bg_height) ch_height =bg_height - start_y;  
                                              ch_width = bitmap.width;  
                                                 
                                              text_width = start_x + bitmap.width;  
                                              for(i=0;i<bg_height;++i){  
                                               
                                                      text_alpha[i] = (unsignedchar*)realloc(text_alpha[i],sizeof(unsigned char)*text_width); 
                                                      for(j=start_x-space;j<text_width;++j)text_alpha[i][j] = 0;  
                                              }  
                                               
                                              for(i = 0; i < bg_height; ++i){   
                                                      for(j = 0;j < ch_width; ++j){ 
                                                              if(i >= start_y && i< start_y + ch_height){  
                                                               
                                                                      text_alpha[i][start_x + j] = bitmap.buffer[k]; 
                                                                      ++k;  
                                                              }  
                                                              else text_alpha[i][start_x + j] = 0;  
                                                      }  
                                              }  
                                              start_x += (ch_width+space);  
                                               
                                              FT_Done_Glyph(glyph);  
                                              glyph = NULL;  
                                      }  
                              }  
                              else{  
                                      sprintf(error_str,"FreeType2 错误[%d]",error); 
                                      perror(error_str);  
                              }  
                      }  
                      else{  
                              sprintf(error_str,"FreeType2 错误[%d]",error); 
                              perror(error_str);  
                      }  
              }  
               
              FT_Done_Face(p_FT_Face);  
              p_FT_Face = NULL;  
               
              FT_Done_FreeType(p_FT_Lib);  
              p_FT_Lib = NULL;     
              temp = 0;  
              out_fonts->width      =text_width;                   
              out_fonts->height    =bg_height;                     
              if(out_fonts->malloc == IS_TRUE)free(out_fonts->text_alpha); 
              size = sizeof(unsigned char) * text_width * bg_height; 
              out_fonts->text_alpha = (unsignedchar*)calloc(1,size);     
              k = 0;  
              for ( i = 0 ; i < bg_height; ++i) 
              {  
                      for ( j = 0 ; j < text_width; ++j) 
                      {  
                              out_fonts->text_alpha[k] = text_alpha[i][j]; 
                              ++k;  
                      }  
              }  
              out_fonts->malloc = IS_TRUE; 
               
              for(i=0;i<bg_height;++i){  
                      free(text_alpha[i]);  
              }  
              free(text_alpha);  
              free(unicode_text);  
              return 0;  
      } 

这些代码在我的工程里的运行效果:

你可能感兴趣的:(嵌入式 Linux下利用FreeType2的API实现字符的显示)