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

原创 2013年12月02日 14:52:24

网上的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;  
   

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

相关文章推荐

嵌入式开发中配置freetype

1:修改添加嵌入式开发板的架构类型:vim ./builds/unix/config.sub 如搜索:x86添加你支持的型号类型:我这边是:csky-6622 case $basic_machine ...

嵌入式 初探freetype字体库

文字的显示依赖于字体字库,大致的字体字库分为点阵字库、笔画字库和轮廓字库。 点阵字库:缺点比较明显,缩放存在锯齿,渲染旋转等操作相对复杂,且效果不理想,先大多用在嵌入式行业(基本抛弃),常见格式有b...
  • skdkjxy
  • skdkjxy
  • 2013年12月02日 14:52
  • 1224

Linux下,利用FreeType2的API实现字符的显示

网上的FreeType2例子太少,能显示汉字的比较难找,C语言代码写的更难找,能找到的,基本上是被转载了N遍的同一个示例代码,基本上解决不了我的问题。 于是乎,花费了不少时间才完成了这些代码。 ...

嵌入式 Linux下curl库API简单介绍

1:CURLcode curl_global_init(long flags);函数,这个函数全局需要调用一次(多次调用也可以,不过没有必要), 所以这也是把Curlplus设计成单体类的原因,cur...
  • skdkjxy
  • skdkjxy
  • 2014年10月21日 17:01
  • 1008

基于嵌入式linux的freetype矢量字体简单显示的实现

一、freetype简介 FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,可以非常方便我们开发字体显示相关的程序功能。它支持单色位图、反...

使用FreeType制作嵌入式(WINCE)使用字体文件

在产品设计初期,本人只想实现一下字体的使用,不想过多依赖于平台提供的API,为日后移植到Linux等其他系统也可通用,于是乎开始Google,接触到了FreeType,通过对FreeType的剪裁,让...
  • Mr_dodo
  • Mr_dodo
  • 2012年09月29日 11:19
  • 1244

嵌入式samba功能的实现,linux下samba的移植

1、samba 下载地址: 新版本下载: https://download.samba.org/pub/samba/ 老版本下载: https://download.samba.org/pub...

Linux下的微型嵌入式GUI

  • 2007年09月22日 03:39
  • 279KB
  • 下载

利用freetype显示unicode字符

使用freetype加载矢量字库,ttf字体文件,通过字符的unicode,load一个字符的点阵!汉字的unicode使用32bit既可表达,比如‘’我‘’的unicode是0x6211 定义全...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式 Linux下利用FreeType2的API实现字符的显示
举报原因:
原因补充:

(最多只允许输入30个字)