Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15636
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2017-04-10 19:30
文章分类

全部博文(7)

文章存档

2015年(7)

我的朋友

分类: LINUX

2015-02-12 15:55:53

本文所描述的只是freetype操作的简单封装,欢迎读者吐槽、完善!

/****************freetype.h********************/

点击(此处)折叠或打开

  1. #ifndef FREETYPE_H_
  2. #define FREETYPE_H_
  3. #include <ft2build.h>
  4. #include <math.h>
  5. #include FT_FREETYPE_H
  6. #include <freetype/ftglyph.h>

  7. typedef enum{
  8.     BITMAP_PIXEL_FORMAT_RGB1555 = 0,
  9. }RGB_FORMAT_E;

  10. typedef struct des_bitmap{
  11.     unsigned int width;
  12.     unsigned int height;
  13.     unsigned char*    bitmap;
  14. }Bitmap_info;

  15. typedef struct create_bitmap{
  16.     unsigned int width;
  17.     unsigned int height;
  18.     unsigned int font_size;
  19.     //unsigned int font_color;
  20.     unsigned int font_left;
  21.     unsigned int font_top;
  22.     double font_angle;
  23. }Bitmap_creat;

  24. static Bitmap_creat creat_bitmap = {0,0,24,0,0,0.0};

  25. class CFreeType2
  26. {
  27. public:
  28.     CFreeType2();
  29.     ~CFreeType2();
  30.     static CFreeType2* GetInstance();

  31.     void Init(const char * fname, unsigned int font_size = 24);
  32.     void Done();

  33.     int SetFontSize(unsigned int font_size = 24);
  34.     int GetStringBitmap(char* str, Bitmap_info &bitmap_info,RGB_FORMAT_E format, Bitmap_creat* creat_info = &creat_bitmap);
  35.     
  36.     //void bitMap_ForceTo1555(int &width, int &height, unsigned char** buff);

  37. protected:
  38.     void draw_rgb1555( FT_Bitmap* bitmap,FT_Int x,FT_Int y);
  39.     int CreateSpace(unsigned int width, unsigned int height, RGB_FORMAT_E format);
  40.     
  41. private:
  42.     static CFreeType2* instance;

  43.     FT_Face face;
  44.     FT_Library library;
  45.     int font_size;
  46.     
  47.     unsigned char* arrLine;
  48.     int cur_width;
  49.     int cur_height;
  50. };

  51. #endif
/****************freetype.cpp********************/

点击(此处)折叠或打开

  1. #include "freetype.h"

  2. CFreeType2* CFreeType2::instance = NULL;

  3. CFreeType2::CFreeType2()
  4. {
  5.     font_size = 24;

  6.     cur_height = 0;
  7.     cur_width = 0;
  8.     arrLine = NULL;
  9. }

  10. CFreeType2::~CFreeType2()
  11. {
  12.     if(instance != NULL)
  13.     {
  14.         delete instance;
  15.         instance = NULL;
  16.     }

  17.     if(arrLine != NULL)
  18.     {
  19.         delete[] arrLine;
  20.         arrLine = NULL;
  21.     }
  22. }

  23. CFreeType2* CFreeType2::GetInstance()
  24. {
  25.     if(instance == NULL)
  26.     {
  27.         instance = new CFreeType2();
  28.     }
  29.     return instance;
  30. }

  31. void CFreeType2::Done()
  32. {
  33.     FT_Done_Face(face);
  34.     FT_Done_FreeType(library);
  35. }

  36. void CFreeType2::Init(const char * fname, unsigned int font_size)
  37. {
  38.     this->font_size = font_size;

  39.     if (FT_Init_FreeType( &library ))
  40.         fprintf(stderr,"FT_Init_FreeType failed");

  41.     if (FT_New_Face( library, fname, 0, &face ))
  42.         fprintf(stderr,"FT_New_Face failed (there is probably a problem with your font file)");

  43.     if(FT_Set_Char_Size( face,font_size<<6, 0, 96, 0))
  44.         fprintf(stderr,"FT_Set_Char_Size failed (there is probably a problem with your font file)");
  45. }

  46. int CFreeType2::SetFontSize(unsigned int font_size)
  47. {
  48.     FT_Set_Char_Size( face,font_size<< 6, 0, 96, 0);

  49.     return 0;
  50. }



  51. void show_image( void )
  52. {
  53. //     int i, j;
  54. //    
  55. //    
  56. //     for ( i = 0; i < cur_height; i++ )
  57. //     {
  58. //     for ( j = 0; j < cur_width; j++ )
  59. //     putchar( image[i][j] == 0 ? ' '
  60. //     : image[i][j] < 128 ? '+'
  61. //     : '*' );
  62. //     putchar( '\n' );
  63. //     }
  64. }

  65. /*
  66. void CFreeType2::bitMap_ForceTo1555(int &width, int &height, unsigned char** buff)
  67. {
  68.     width = cur_width;
  69.     height = cur_height;
  70.     int i, j;
  71.     FT_Short rgb1555;
  72.     
  73.     //show_image();
  74.     *buff = (unsigned char*)malloc(cur_height * cur_width * 2);
  75.     
  76.     memset(*buff, 0x0, cur_height * cur_width * 2);
  77.     for ( i = 0; i < cur_height; i++ )
  78.     {
  79.         for ( j = 0; j < cur_width; j++ ) {
  80.             //*(array+i*y+j)表示array[i][j]
  81.             //if(image[i][j] != 0) {
  82.             if(*(image+i*cur_width+j) != 0) {
  83.                 //描边 占用原有字的边界
  84. //                    if(        image[i+1][j] == 0 || image[i][j+1] == 0
  85. //                        ||     image[i-1][j] == 0 || image[i][j-1] == 0)
  86. //                    {
  87. //                        rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
  88. //                    }
  89. //                    else
  90. //                    {
  91. //                        rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);
  92. //                    }
  93.                 //复合
  94. //                    rgb1555 = (1<<15) | ((0X1F & image[i][j])<<10) | ((0X1F & image[i][j])<<5) | ((0X1F & image[i][j])<<0);

  95.                 //直接使用
  96.                 //rgb1555 = (1<<15) | (image[i][j]<<10) | (image[i][j]<<5) | (image[i][j]<<0);
  97.                 rgb1555 = (1<<15) | (*(image+i*cur_width+j)<<10) | (*(image+i*cur_width+j)<<5) | (*(image+i*cur_width+j)<<0);
  98.                 
  99.                 memcpy(*buff + i*cur_width*2 + j*2, &rgb1555, sizeof(FT_Short));

  100.             }
  101.             else
  102.             {
  103.                 //描外边
  104.                 if(i == 0 || i>= cur_height-1)
  105.                 {
  106.                     rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
  107.                 }
  108. //                    else if(image[i+1][j] != 0 || image[i][j+1] != 0
  109. //                        ||     image[i-1][j] != 0 || image[i][j-1] != 0)
  110.                 else if(*(image+i*cur_width+j) != 0 || *(image+i*cur_width+j) != 0
  111.                         ||    *(image+i*cur_width+j) != 0 || *(image+i*cur_width+j) != 0)

  112.                 {
  113.                     rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
  114.                 }
  115.                 else
  116.                 {
  117.                     rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
  118.                 }
  119.                 
  120.                 memcpy(*buff + i*cur_width*2 + j*2, &rgb1555, sizeof(FT_Short));
  121.             }
  122.         }
  123.     }
  124.     #if 0
  125.     for(i=0; i<cur_height; i++)
  126.     {
  127.         for(j=0; j<cur_width*2; j+=2)
  128.         {
  129.             FT_Short rgb1555;
  130.             memcpy(&rgb1555, *buff + i*cur_width*2 + j, sizeof(FT_Short));
  131.             putchar( rgb1555 == 0 ? ' '
  132.                                 : rgb1555 < 128 ? '+'
  133.                                                     : '*' );
  134.         }
  135.         printf("\n");
  136.     }
  137.     #endif
  138. }
  139. */

  140. /*****************************************************************************
  141.  Prototype : CFreeType2.CreateSpace
  142.  Description : 分配bitmap的存储空间
  143.  Input : unsigned int width
  144.                 unsigned int height
  145.                 RGB_FORMAT_E format
  146.  Output : None
  147.  Return Value : int
  148.  Calls :
  149.  Called By :
  150.  
  151.   History :
  152.   1.Date : 2015/2/12
  153.     Author : donyj
  154.     Modification : Created function

  155. *****************************************************************************/
  156. int CFreeType2::CreateSpace(unsigned int width, unsigned int height, RGB_FORMAT_E format)
  157. {
  158.     unsigned int bytes;
  159.     
  160.     switch(format)
  161.     {
  162.     case BITMAP_PIXEL_FORMAT_RGB1555:
  163.         {
  164.             bytes = 2;
  165.             break;
  166.         }
  167. //        case BITMAP_PIXEL_FORMAT_GRAY_BIT8:
  168. //            {
  169. //                bytes = 1;
  170. //                break;
  171. //            }
  172.     default:
  173.         {
  174.             bytes = 2;
  175.             break;
  176.         }
  177.     }
  178.     
  179.     //如果字符占用的内存变了,则重新分配,否则复用 malloc
  180.     if(cur_height != height || cur_width != width)
  181.     {
  182.         if(arrLine != NULL)
  183.         {
  184.             delete[] arrLine;
  185.             arrLine = NULL;
  186.         }
  187.         cur_width = width;
  188.         cur_height = height;
  189.         arrLine = new unsigned char[height*width*bytes];
  190.     }
  191.     memset(arrLine, 0x0, width*height*bytes);

  192.     return 0;
  193. }

  194. /*****************************************************************************
  195.  Prototype : CFreeType2.GetStringBitmap
  196.  Description : 根据字符串生成bitmap
  197.  Input : char* str
  198.                 Bitmap_info &bitmap_info
  199.                 RGB_FORMAT_E format
  200.                 Bitmap_creat* creat_info
  201.  Output : None
  202.  Return Value : int
  203.  Calls :
  204.  Called By :
  205.  
  206.   History :
  207.   1.Date : 2015/2/12
  208.     Author : donyj
  209.     Modification : Created function

  210. *****************************************************************************/
  211. int CFreeType2::GetStringBitmap(char* str, Bitmap_info &bitmap_info, RGB_FORMAT_E format, Bitmap_creat* creat_info)
  212. {
  213.     FT_GlyphSlot slot;
  214.     FT_Matrix matrix; /* transformation matrix */
  215.     FT_Vector pen; /* untransformed origin */
  216.     FT_Error error;

  217.     double angle;
  218.     int map_height;
  219.     int n, str_len;
  220.     int          ret;

  221.     str_len = strlen(str);

  222.     if(creat_info == NULL)
  223.     {
  224.         //开辟存储空间
  225.         ret = CreateSpace(str_len*font_size,font_size,format);
  226.         if(ret != 0)
  227.         {
  228.             printf("CreateSpace error!");
  229.             return -1;
  230.         }
  231.         
  232.         angle = ( 0.0 / 360 ) * 3.14159 * 2;     //字体旋转
  233.         map_height = cur_height;

  234.         /* use font_size at 96dpi */
  235.         error = FT_Set_Char_Size( face, font_size * 64, 0, 96, 0 );
  236.         if(error)
  237.         {
  238.             printf("FT_Set_Char_Size error!");
  239.             return -1;
  240.         }

  241.         /* the pen position in 26.6 cartesian space coordinates; */
  242.         /* start at (0,0) relative to the upper left corner */
  243.         pen.x = 0 * 64;//300 * 64;
  244.         pen.y = 0 * 64;//( target_height - 200 ) * 64;
  245.     }
  246.     else
  247.     {
  248.         if(creat_info->width < str_len*creat_info->font_size)
  249.         {
  250.             creat_info->width = str_len*creat_info->font_size;
  251.         }
  252.         if(creat_info->height < creat_info->font_size)
  253.         {
  254.             creat_info->height = creat_info->font_size;
  255.         }
  256.         //开辟存储空间
  257.         ret = CreateSpace(creat_info->width,creat_info->height,format);
  258.         if(ret != 0)
  259.         {
  260.             printf("CreateSpace error!");
  261.             return -1;
  262.         }
  263.         
  264.         angle = ( creat_info->font_angle / 360 ) * 3.14159 * 2;     //字体旋转
  265.         map_height = cur_height;

  266.         /* use font_size at 96dpi */
  267.         error = FT_Set_Char_Size( face, creat_info->font_size * 64, 0, 96, 0 );
  268.         if(error)
  269.         {
  270.             printf("FT_Set_Char_Size error!");
  271.             return -1;
  272.         }
  273.         
  274.         /* the pen position in 26.6 cartesian space coordinates; */
  275.         /* start at (0,0) relative to the upper left corner */
  276.         pen.x = creat_info->font_left * 64;
  277.         pen.y = (map_height - creat_info->font_size - creat_info->font_top) * 64;
  278.     }
  279.     
  280.     
  281.     slot = face->glyph;

  282.     /* set up matrix */
  283.     matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
  284.     matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
  285.     matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
  286.     matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );

  287.     
  288.     for ( n = 0; n < str_len; n++ )
  289.     {
  290.         /* set transformation */
  291.         FT_Set_Transform( face, &matrix, &pen );

  292.         /* load glyph image into the slot (erase previous one) */
  293.         error = FT_Load_Char( face, str[n], FT_LOAD_RENDER );
  294.         if ( error )
  295.              continue; /* ignore errors */
  296.         /* now, draw to our target surface (convert position) */
  297.         switch(format)
  298.         {
  299.         case BITMAP_PIXEL_FORMAT_RGB1555:
  300.             {
  301.                 draw_rgb1555( &slot->bitmap,
  302.          slot->bitmap_left,
  303.          map_height - slot->bitmap_top );
  304.                 break;
  305.             }

  306.         default:
  307.             {
  308.                 break;
  309.             }
  310.         }

  311.         /* increment pen position */
  312.         pen.x += slot->advance.x;
  313.         pen.y += slot->advance.y;
  314.     }

  315.     //赋值返回
  316.     bitmap_info.width = cur_width;
  317.     bitmap_info.height = cur_height;
  318.     bitmap_info.bitmap = arrLine;

  319.     return 0;
  320. }

  321. /*****************************************************************************
  322.  Prototype : CFreeType2.draw_rgb1555
  323.  Description : 填充bitmap rgb1555格式
  324.  Input : FT_Bitmap* bitmap
  325.                 FT_Int x
  326.                 FT_Int y
  327.  Output : None
  328.  Return Value : void
  329.  Calls :
  330.  Called By :
  331.  
  332.   History :
  333.   1.Date : 2015/2/12
  334.     Author : donyj
  335.     Modification : Created function

  336. *****************************************************************************/
  337. void CFreeType2::draw_rgb1555( FT_Bitmap* bitmap,FT_Int x,FT_Int y){
  338.     FT_Int i, j, p, q;
  339.     FT_Int x_max = x + bitmap->width;
  340.     FT_Int y_max = y + bitmap->rows;


  341.     for ( i = x, p = 0; i < x_max; i++, p++ ){
  342.         for ( j = y, q = 0; j < y_max; j++, q++ ){
  343.             if ( i < 0 || j < 0 || i >= cur_width || j >= cur_height )
  344.                 continue;
  345.             unsigned short int rgb1555;

  346.             if(bitmap->buffer[q * bitmap->width + p] != 0) {
  347.             //描边 占用原有字的边界
  348. //                    if(        bitmap->buffer[(q+1) * bitmap->width + p] == 0 || bitmap->buffer[q * bitmap->width + (p+1)] == 0
  349. //                        ||     bitmap->buffer[(q-1) * bitmap->width + p] == 0 || bitmap->buffer[q * bitmap->width + (p-1)] == 0)
  350. //                    {
  351. //                        rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
  352. //                    }
  353. //                    else
  354. //                    {
  355. //                        rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);
  356. //                    }
  357.             //复合
  358. //                    rgb1555 = (1<<15) | ((0X1F & bitmap->buffer[q * bitmap->width + p])<<10)
  359. //                            | ((0X1F & bitmap->buffer[q * bitmap->width + p])<<5) | (bitmap->buffer[q * bitmap->width + p])<<0);

  360.             //直接使用
  361.             rgb1555 = (1<<15) | (bitmap->buffer[q * bitmap->width + p]<<10) | (bitmap->buffer[q * bitmap->width + p]<<5) | (bitmap->buffer[q * bitmap->width + p]<<0);
  362.             //rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);

  363.             }
  364.             else
  365.             {
  366.                 //描外边
  367.                 if(j == 0 || j>= cur_height-1)
  368.                 {
  369.                     rgb1555 = (1<<15) | (0<<10) | (0<<5) | (0<<0);
  370.                 }
  371.                 else if(bitmap->buffer[(q+1) * bitmap->width + p] != 0 || bitmap->buffer[q * bitmap->width + (p+1)] != 0
  372.                     //||    bitmap->buffer[(q-1) * bitmap->width + p] != 0 || bitmap->buffer[q * bitmap->width + (p-1)] != 0
  373.                     )
  374.     
  375.                 {
  376.                     rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
  377.                 }
  378.                 else
  379.                 {
  380.                     rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
  381.                 }

  382.                 //rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
  383.             }
  384.     

  385.             
  386. //                if(tmp == '\0'){
  387. //                    rgb1555 = (0<<15) | (0x0<<10) | (0x0<<5) | (0x0<<0);
  388. //                }else{
  389. //                    rgb1555 = (1<<15) | (0x1F<<10) | (0x1F<<5) | (0x1F<<0);
  390. //                }
  391.                 memcpy(arrLine+j*cur_width*2+2*i,&rgb1555,sizeof(rgb1555));
  392.         }
  393.     }
  394. }
通过GetInstance()获取句柄来调用方法!暂时只实现了转换成rgb1555格式的bitmap。生成出来的字体不怎么好看,希望有人能指出,并且帮忙决解这个问题!

本文所有:Devile May Cry J        QQ:384668960
阅读(2184) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~