Linux电子书项目之freetype实现矢量字体的显示(2)

上一篇博文我们通过点阵数组实现了字母的显示:http://blog.csdn.net/shenhuan1104/article/details/79476053

现在我们通过freetype这个框架在PC和单板LCD上分别实现矢量字体的显示。

一、PC上矢量字体的显示

(1)矢量字体原理:存储一些关健点,然后通过贝塞尔曲线连接。

(2)显示实现过程:

  1. 给定一个文字,确定它的编码值;
  2. 根据编码值从字体文件中找到它的“glyph”;
  3. 设置字体大小;
  4. 转换为位图点阵;
  5. 在LCD上显示;
(3) 分析源码自带的例子
  1. /* example1.c                                                      */  
  2. /*                                                                 */  
  3. /* This small program shows how to print a rotated string with the */  
  4. /* FreeType 2 library.                                             */  
  5.   
  6.   
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <math.h>  
  10.   
  11. #include <ft2build.h>  
  12. #include FT_FREETYPE_H  
  13.   
  14.   
  15. #define WIDTH   80  
  16. #define HEIGHT  80  
  17.   
  18.   
  19. /* origin is the upper left corner */  
  20. unsigned char image[HEIGHT][WIDTH];  
  21.   
  22.   
  23. /* Replace this function with something useful. */  
  24.   
  25. void  
  26. draw_bitmap( FT_Bitmap*  bitmap,  
  27.              FT_Int      x,  
  28.              FT_Int      y)  
  29. {  
  30.   FT_Int  i, j, p, q;  
  31.   FT_Int  x_max = x + bitmap->width;  
  32.   FT_Int  y_max = y + bitmap->rows;  
  33.   
  34.   
  35.   for ( i = x, p = 0; i < x_max; i++, p++ )  
  36.   {  
  37.     for ( j = y, q = 0; j < y_max; j++, q++ )  
  38.     {  
  39.       if ( i < 0      || j < 0       ||  
  40.            i >= WIDTH || j >= HEIGHT )  
  41.         continue;  
  42.   
  43.       image[j][i] |= bitmap->buffer[q * bitmap->width + p];  
  44.     }  
  45.   }  
  46. }  
  47.   
  48.   
  49. void  
  50. show_image( void )  
  51. {  
  52.   int  i, j;  
  53.   
  54.   
  55.   for ( i = 0; i < HEIGHT; i++ )  
  56.   {  
  57.     for ( j = 0; j < WIDTH; j++ )  
  58.       putchar( image[i][j] == 0 ? ' '  
  59.                                 : image[i][j] < 128 ? '+'  
  60.                                                     : '*' );  
  61.     putchar( '\n' );  
  62.   }  
  63. }  
  64.   
  65.   
  66. int  
  67. main( int     argc,  
  68.       char**  argv )  
  69. {  
  70.   FT_Library    library;  
  71.   FT_Face       face;  
  72.   
  73.   FT_GlyphSlot  slot;  
  74.   FT_Matrix     matrix;                 /* transformation matrix */  
  75.   FT_Vector     pen;                    /* untransformed origin  */  
  76.   FT_Error      error;  
  77.   
  78.   char*         filename;  
  79.   char*         text;  
  80.   
  81.   double        angle;  
  82.   int           target_height;  
  83.   int           n, num_chars;  
  84.   
  85.   
  86.   if ( argc != 3 )  
  87.   {  
  88.     fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );  
  89.     exit( 1 );  
  90.   }  
  91.   
  92.   filename      = argv[1];                           /* first argument     */  
  93.   text          = argv[2];                           /* second argument    */  
  94.   num_chars     = strlen( text );  
  95.   angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 25 degrees     */  
  96.   target_height = HEIGHT;  
  97.   
  98.   error = FT_Init_FreeType( &library );              /* 初始化 initialize library */  
  99.   /* error handling omitted */  
  100.   
  101.   error = FT_New_Face( library, argv[1], 0, &face ); /* 打开字体文件argv[1]  create face object */  
  102.   /* error handling omitted */  
  103.   
  104. #if 0  
  105.   /* use 50pt at 100dpi */  
  106.   error = FT_Set_Char_Size( face, 50 * 64, 0,  
  107.                             100, 0 );                /* 设置字符大小   set character size */  
  108.   
  109.     /* pixels = 50 /72 * 100 = 69  */       
  110.     //50*64/64/72(多少英寸)   *100       100:每个英寸有多少个像素点  
  111. #else  
  112.     FT_Set_Pixel_Sizes(face, 24, 0);    //24像素大小 类似于点阵里点的个数。高度=宽度=24  
  113. #endif  
  114.   /* error handling omitted */  
  115.   
  116.   slot = face->glyph;     //取出关键点后存在face里的glyph里面  
  117.   
  118.   /* set up matrix */  
  119.   matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );  
  120.   matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );  
  121.   matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );  
  122.   matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );  
  123.   
  124.   /* the pen position in 26.6 cartesian space coordinates; */  
  125.   /* start at (0,40):lcd    relative to the upper left corner  */  
  126.   pen.x = 0 * 64;  
  127.   pen.y = ( target_height - 40 ) * 64; //此处是笛卡尔坐标。原点在左下角  
  128.                                                                          //lcd里原点在左上角 x‘=x  y’=hight-y  
  129.   
  130.   for ( n = 0; n < num_chars; n++ )  
  131.   {  
  132.     /* set transformation */  
  133.     FT_Set_Transform( face, &matrix, &pen );             //旋转 matrix:旋转矩阵  
  134.   
  135.     /* load glyph image into the slot (erase previous one) */  
  136.     error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );// FT_Load_Char:找到;取出;转换为位图;=那三个函数  
  137.     if ( error )                                          //FT_LOAD_RENDER: glyph立刻转换为位图  
  138.                                                                                                                 //text:unicode ascii编码  
  139.       continue;                 /* ignore errors */  
  140.   
  141.     /* now, draw to our target surface (convert position) */  
  142.     draw_bitmap( &slot->bitmap,                            //draw_bitmap:打印出来    bitmap里面含有点阵存到image数组中  
  143.                  slot->bitmap_left,  
  144.                  target_height - slot->bitmap_top );  
  145.   
  146.     /* increment pen position */  
  147.     pen.x += slot->advance.x;  
  148.     pen.y += slot->advance.y;  
  149.   }  
  150.   
  151.   show_image();                                              //打印image数组  
  152.   
  153.   FT_Done_Face    ( face );  
  154.   FT_Done_FreeType( library );  
  155.   
  156.   return 0;  
  157. }  
  158.   
  159. /* EOF */  

(4)freetype文件的编译需要库,所以需要提前编译freetype产生编译freetype函数的环境。生成响应的库。

安装配置freetype_PC::

tar xjf freetype-2.4.10.tar.bz2

mv freetype-2.4.10   freetype-2.4.10_pc

cd freetype-2.4.10_pc/

./configure

make

sudo make install

(5)编译

gcc -o example1 example1.c -I/usr/local/include/freetype2/ -lfreetype -lm

(6)执行

./example1  ./simsun.ttc  abc

二、ARM上显示矢量字体

(1)交叉编译freetype库文件

tar xjf freetype-2.4.10.tar.bz2

./configure --host=arm-linux

make

make DESTDIR=$PWD/tmp install


把tmp/usr/local/lib/*  复制到/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

sudo cp */usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib -d -rf

把tmp/usr/local/include/*  复制到/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include

cp */usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include -rf

(2)编译

arm-linux-gcc -finput-charset=GBK -oexample1 example1.c  -lfreetype -lm

(3)修改代码在LCD上显示矢量字体

[cpp]  view plain  copy
  1. #include <sys/mman.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <unistd.h>  
  5. #include <linux/fb.h>  
  6. #include <fcntl.h>  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <math.h>  
  10. #include <wchar.h>  
  11. #include <stdlib.h>  
  12.   
  13. #include <ft2build.h>  
  14. #include FT_FREETYPE_H  
  15. #include FT_GLYPH_H  
  16.   
  17. #define FONTDATAMAX 4096  
  18.   
  19. static const unsigned char fontdata_8x16[FONTDATAMAX] = {  
  20. };  
  21.   
  22. int fd_fb;  
  23. struct fb_var_screeninfo var;   /* Current var */  
  24. struct fb_fix_screeninfo fix;   /* Current fix */  
  25. int screen_size;  
  26. unsigned char *fbmem;  
  27. unsigned int line_width;  
  28. unsigned int pixel_width;  
  29.   
  30. int fd_hzk16;  
  31. struct stat hzk_stat;  
  32. unsigned char *hzkmem;  
  33.   
  34.   
  35.   
  36. /* color : 0x00RRGGBB */  
  37. void lcd_put_pixel(int x, int y, unsigned int color)  
  38. {  
  39.     unsigned char *pen_8 = fbmem+y*line_width+x*pixel_width;  
  40.     unsigned short *pen_16;   
  41.     unsigned int *pen_32;     
  42.   
  43.     unsigned int red, green, blue;    
  44.   
  45.     pen_16 = (unsigned short *)pen_8;  
  46.     pen_32 = (unsigned int *)pen_8;  
  47.   
  48.     switch (var.bits_per_pixel)  
  49.     {  
  50.         case 8:  
  51.         {  
  52.             *pen_8 = color;  
  53.             break;  
  54.         }  
  55.         case 16:  
  56.         {  
  57.             /* 565 */  
  58.             red   = (color >> 16) & 0xff;  
  59.             green = (color >> 8) & 0xff;  
  60.             blue  = (color >> 0) & 0xff;  
  61.             color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);  
  62.             *pen_16 = color;  
  63.             break;  
  64.         }  
  65.         case 32:  
  66.         {  
  67.             *pen_32 = color;  
  68.             break;  
  69.         }  
  70.         default:  
  71.         {  
  72.             printf("can't surport %dbpp\n", var.bits_per_pixel);  
  73.             break;  
  74.         }  
  75.     }  
  76. }  
  77.   
  78. void lcd_put_ascii(int x, int y, unsigned char c)  
  79. {  
  80.     unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];  
  81.     int i, b;  
  82.     unsigned char byte;  
  83.   
  84.     for (i = 0; i < 16; i++)  
  85.     {  
  86.         byte = dots[i];  
  87.         for (b = 7; b >= 0; b--)  
  88.         {  
  89.             if (byte & (1<<b))  
  90.             {  
  91.                 /* show */  
  92.                 lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */  
  93.             }  
  94.             else  
  95.             {  
  96.                 /* hide */  
  97.                 lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */  
  98.             }  
  99.         }  
  100.     }  
  101. }  
  102.   
  103. void lcd_put_chinese(int x, int y, unsigned char *str)  
  104. {  
  105.     unsigned int area  = str[0] - 0xA1;  
  106.     unsigned int where = str[1] - 0xA1;  
  107.     unsigned char *dots = hzkmem + (area * 94 + where)*32;  
  108.     unsigned char byte;  
  109.   
  110.     int i, j, b;  
  111.     for (i = 0; i < 16; i++)  
  112.         for (j = 0; j < 2; j++)  
  113.         {  
  114.             byte = dots[i*2 + j];  
  115.             for (b = 7; b >=0; b--)  
  116.             {  
  117.                 if (byte & (1<<b))  
  118.                 {  
  119.                     /* show */  
  120.                     lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */  
  121.                 }  
  122.                 else  
  123.                 {  
  124.                     /* hide */  
  125.                     lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */  
  126.                 }  
  127.                   
  128.             }  
  129.         }  
  130.       
  131. }  
  132. /* Replace this function with something useful. */  
  133.   
  134. void  
  135. draw_bitmap( FT_Bitmap*  bitmap,  
  136.              FT_Int      x,  
  137.              FT_Int      y)  
  138. {  
  139.   FT_Int  i, j, p, q;  
  140.   FT_Int  x_max = x + bitmap->width;  
  141.   FT_Int  y_max = y + bitmap->rows;  
  142.   
  143.     //printf("x = %d, y = %d\n", x, y);  
  144.   
  145.   for ( i = x, p = 0; i < x_max; i++, p++ )  
  146.   {  
  147.     for ( j = y, q = 0; j < y_max; j++, q++ )  
  148.     {  
  149.       if ( i < 0      || j < 0       ||  
  150.            i >= var.xres || j >= var.yres )  
  151.         continue;  
  152.   
  153.       //image[j][i] |= bitmap->buffer[q * bitmap->width + p];  
  154.       lcd_put_pixel(i, j, bitmap->buffer[q * bitmap->width + p]);  
  155.     }  
  156.   }  
  157. }  
  158.   
  159.   
  160. int main(int argc, char **argv)  
  161. {  
  162.     unsigned char str[] = "中";  
  163.     wchar_t *chinese_str = L"繁";  
  164.   
  165.     FT_Library    library;  
  166.     FT_Face       face;  
  167.     int error;  
  168.     FT_Vector     pen;  
  169.     FT_GlyphSlot  slot;  
  170.     FT_Matrix     matrix;                 /* transformation matrix */  
  171.     double        angle;  
  172.   
  173.     if (argc != 3)  
  174.     {  
  175.         printf("Usage : %s <font_file> <angle>\n", argv[0]);  
  176.         return -1;  
  177.     }  
  178.           
  179.   
  180.     fd_fb = open("/dev/fb0", O_RDWR);  
  181.     if (fd_fb < 0)  
  182.     {  
  183.         printf("can't open /dev/fb0\n");  
  184.         return -1;  
  185.     }  
  186.   
  187.     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))  
  188.     {  
  189.         printf("can't get var\n");  
  190.         return -1;  
  191.     }  
  192.   
  193.     if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))  
  194.     {  
  195.         printf("can't get fix\n");  
  196.         return -1;  
  197.     }  
  198.   
  199.     line_width  = var.xres * var.bits_per_pixel / 8;  
  200.     pixel_width = var.bits_per_pixel / 8;  
  201.     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;  
  202.     fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);  
  203.     if (fbmem == (unsigned char *)-1)  
  204.     {  
  205.         printf("can't mmap\n");  
  206.         return -1;  
  207.     }  
  208.   
  209.     fd_hzk16 = open("HZK16", O_RDONLY);  
  210.     if (fd_hzk16 < 0)  
  211.     {  
  212.         printf("can't open HZK16\n");  
  213.         return -1;  
  214.     }  
  215.     if(fstat(fd_hzk16, &hzk_stat))  
  216.     {  
  217.         printf("can't get fstat\n");  
  218.         return -1;  
  219.     }  
  220.     hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);  
  221.     if (hzkmem == (unsigned char *)-1)  
  222.     {  
  223.         printf("can't mmap for hzk16\n");  
  224.         return -1;  
  225.     }  
  226.   
  227.     /* 清屏: 全部设为黑色 */  
  228.     memset(fbmem, 0, screen_size);  
  229.   
  230.     lcd_put_ascii(var.xres/2, var.yres/2, 'A');  
  231.   
  232.     printf("chinese code: %02x %02x\n", str[0], str[1]);  
  233.     lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);  
  234.   
  235.   
  236.     /* 显示矢量字体 */  
  237.     error = FT_Init_FreeType( &library );              /* initialize library */  
  238.     /* error handling omitted */  
  239.       
  240.     error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */  
  241.     /* error handling omitted */      
  242.     slot = face->glyph;  
  243.   
  244.     FT_Set_Pixel_Sizes(face, 24, 0);  
  245.   
  246.     /* 确定座标: 
  247.      * lcd_x = var.xres/2 + 8 + 16 
  248.      * lcd_y = var.yres/2 + 16 
  249.      * 笛卡尔座标系: 
  250.      * x = lcd_x = var.xres/2 + 8 + 16 
  251.      * y = var.yres - lcd_y = var.yres/2 - 16 
  252.      */  
  253.     pen.x = (var.xres/2 + 8 + 16) * 64;  
  254.     pen.y = (var.yres/2 - 16) * 64;  
  255.   
  256.     angle = ( 1.0 * strtoul(argv[2], NULL, 0) / 360 ) * 3.14159 * 2;      /* use 25 degrees     */  
  257.     /* set up matrix */  
  258.     matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );  
  259.     matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );  
  260.     matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );  
  261.     matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );  
  262.   
  263.     /* set transformation */  
  264.     FT_Set_Transform( face, &matrix, &pen);  
  265.   
  266.     /* load glyph image into the slot (erase previous one) */  
  267.     error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );  
  268.     if (error)  
  269.     {  
  270.         printf("FT_Load_Char error\n");  
  271.         return -1;  
  272.     }  
  273.       
  274.     draw_bitmap( &slot->bitmap,  
  275.                  slot->bitmap_left,  
  276.                  var.yres - slot->bitmap_top);  
  277.   
  278.     return 0;     
  279. }  
arm-linux-gcc -finput-charset=GBK -fexec-charset=GBK -o show_font show_font.c -lfreetype -lm 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如何使用汉字库的代码,delphi 6 switch (PixelSize) { case 12: HZKSize = 24; //汉字库字模大小24字节(12*16/8) ASCSize = 12; //ASC字库字模大小12字节 AreaOffset = 0;//16区以前不独立成字库 File1Name = GetAppPath()+"font\\HZK12"; iFileHandle1 = fopen(File1Name.c_str(), "rb"); File2Name = GetAppPath()+"font\\ASC12"; iFileHandle2 = fopen(File2Name.c_str(), "rb"); break; case 16: HZKSize = 32; //汉字库字模大小32字节(12*16/8) ASCSize = 16; //ASC字库字模大小16字节 AreaOffset = 0;//16区以前不独立成字库 File1Name = GetAppPath()+"font\\HZK16"; iFileHandle1 = fopen(File1Name.c_str(), "rb"); File2Name = GetAppPath()+"font\\ASC16"; iFileHandle2 = fopen(File2Name.c_str(), "rb"); break; case 24: HZKSize = 72; //汉字库字模大小32字节(24*24/8) ASCSize = 72; //ASC字库字模大小16字节(24*24/8) AreaOffset = 15;//16区以前独立成字库 File1Name = GetAppPath()+"font\\HZK24F"; iFileHandle1 = fopen(File1Name.c_str(), "rb"); File2Name = GetAppPath()+"font\\ASC24"; iFileHandle2 = fopen(File2Name.c_str(), "rb"); File3Name = GetAppPath()+"font\\HZK24T"; iFileHandle3 = fopen(File3Name.c_str(), "rb"); break; case 40: HZKSize = 200; //汉字库字模大小32字节(40*40/8) ASCSize = 120; //ASC字库字模大小16字节(40*24/8) AreaOffset = 15;//16区以前独立成字库 File1Name = GetAppPath()+"font\\HZK40S"; iFileHandle1 = fopen(File1Name.c_str(), "rb"); File2Name = GetAppPath()+"font\\ASC40"; iFileHandle2 = fopen(File2Name.c_str(), "rb"); File3Name = GetAppPath()+"font\\HZK40T"; iFileHandle3 = fopen(File3Name.c_str(), "rb"); break; case 48: HZKSize = 288; //汉字库字模大小32字节(48*48/8) ASCSize = 144; //ASC字库字模大小16字节(48*24/8) AreaOffset = 15;//16区以前独立成字库 File1Name = GetAppPath()+"font\\HZK48S"; iFileHandle1 = fopen(File1Name.c_str(), "rb"); File2Name = GetAppPath()+"font\\ASC48"; iFileHandle2 = fopen(File2Name.c_str(), "rb"); File3Name = GetAppPath()+"font\\HZK48T"; iFileHandle3 = fopen(File3Name.c_str(), "rb"); break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值