使用freetype来显示中文汉字和英文字符
Posted 叶念西风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用freetype来显示中文汉字和英文字符相关的知识,希望对你有一定的参考价值。
这里我们用到了freetype。进入官网http://savannah.nongnu.org/download/freetype/ 中下载最新的版本2.7的源代码和文件。freetype-2.7.tar.gz freetype-doc-2.7.tar.gz
首先我们在使用官方提供的程序在pc上运行一下。
在freetype-doc-2.7.tar.gz文件中的docus目录下的tutorial有一个example.c的源文件。
example.c:
/* example1.c */ /* */ /* This small program shows how to print a rotated string with the */ /* FreeType 2 library. */ #include <stdio.h> #include <string.h> #include <math.h> #include <ft2build.h> #include FT_FREETYPE_H #define WIDTH 80 #define HEIGHT 80 /* origin is the upper left corner */ unsigned char image[HEIGHT][WIDTH]; /* Replace this function with something useful. */ void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y) { FT_Int i, j, p, q; FT_Int x_max = x + bitmap->width; FT_Int y_max = y + bitmap->rows; for ( i = x, p = 0; i < x_max; i++, p++ ) { for ( j = y, q = 0; j < y_max; j++, q++ ) { if ( i < 0 || j < 0 || i >= WIDTH || j >= HEIGHT ) continue; image[j][i] |= bitmap->buffer[q * bitmap->width + p]; } } } void show_image( void ) { int i, j; for ( i = 0; i < HEIGHT; i++ ) { for ( j = 0; j < WIDTH; j++ ) putchar( image[i][j] == 0 ? ‘ ‘ : image[i][j] < 128 ? ‘+‘ : ‘*‘ ); putchar( ‘\n‘ ); } } int main( int argc, char** argv ) { FT_Library library; FT_Face face; FT_GlyphSlot slot; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ FT_Error error; char* filename; char* text; double angle; int target_height; int n, num_chars; if ( argc != 3 ) { fprintf ( stderr, "usage: %s font sample-text\n", argv[0] ); exit( 1 ); } filename = argv[1]; /* first argument */ text = argv[2]; /* second argument */ num_chars = strlen( text ); angle = ( 0.0 / 360 ) * 3.14159 * 2; /* use 0 degrees 旋转 */ target_height = HEIGHT; error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, filename, 0, &face );/* create face object */ /* error handling omitted */ /* use 50pt at 100dpi */ error = FT_Set_Char_Size( face, 50 * 64, 0, 30, 0 ); /* set character size */ /* error handling omitted */ slot = face->glyph; /* set up matrix */ matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); /* the pen position in 26.6 cartesian space coordinates; */ /* start at (40,0) relative to the upper left corner */ pen.x = 0 * 64; pen.y = ( target_height - 40 ) * 64; for ( n = 0; n < num_chars; n++ ) { /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); if ( error ) continue; /* ignore errors */ /* now, draw to our target surface (convert position) */ draw_bitmap( &slot->bitmap, slot->bitmap_left, target_height - slot->bitmap_top ); /* increment pen position */ pen.x += slot->advance.x; pen.y += slot->advance.y; } show_image(); FT_Done_Face ( face ); FT_Done_FreeType( library ); return 0; } /* EOF */
程序中把输出的字符打印在屏幕上,分辨率是640*480,从300,200 处开始显示.这里我为了便于查看就改为了80*80.从40,0处开始显示
编译:
gcc -o example1 example1.c -I /usr/local/include/freetype2/ -lfreetype -lm
运行程序即可。
arm:
首先配置:
./configure --host=arm-linux
make
make install
将生成的文件拷贝到交叉编译器和开发板文件系统相应的位置。
编译文件:
arm-linux-gcc -o test main.c -lfreetype -lm
将test和字体文件拷贝到开发板中即可运行程序.
源代码:
#include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <linux/fb.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <math.h> #include "show_font.h" #include <ft2build.h> #include FT_FREETYPE_H unsigned char *hzkmem; unsigned char *fbmem; unsigned int line_width; unsigned int pixel_width; struct fb_var_screeninfo var; void lcd_put_pixel( int x, int y, unsigned int color ) { unsigned char *pen_8 = fbmem +y*line_width + x*pixel_width; unsigned short *pen_16; unsigned short *pen_32; unsigned char red,green,blue; pen_16 = (unsigned short *)pen_8; pen_32 = (unsigned short *)pen_8; switch( pixel_width*8 ) { case 8: *pen_8 = color; break; case 16: /* 565 */ red = (color>>16) & 0xff; green = (color>>8) & 0xff; blue = (color>>0) & 0xff; color = ((red>>3)<<11) | ((green>>2)<<5) |((blue>>3)); *pen_16 = color; break; case 32: *pen_32 = color; break; default: printf("can‘t support %ddpp\n",pixel_width*8 ); break; } } void lcd_put_ascii( int x, int y, unsigned char c ) { unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16]; int i,b; unsigned char byte; for( i=0; i< 16; i++ ) { byte = dots[i]; for( b=7;b>=0;b--) { if( byte & (1<<b)) { lcd_put_pixel(x+7-b,y+i, 0xffffff ); } else { lcd_put_pixel(x+7-b,y+i, 0x000000 ); } } } } void lcd_put_chinese( int x, int y, unsigned char *c ) { unsigned int area = c[0] - 0xa1; unsigned int where = c[1] - 0xa1; unsigned char *dots = hzkmem + (area*94+where)*32; unsigned char byte; int i,j,b; for( i=0; i<16; i++ ) { for( j=0; j<2; j++ ) { byte = dots[i*2+j]; for( b=7; b>=0; b-- ) { if( byte & (1<<b) ) lcd_put_pixel(x+j*8+7-b,y+i, 0xffffff ); else lcd_put_pixel(x+j*8+7-b,y+i, 0x000000 ); } } } } void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y) { FT_Int i, j, p, q; FT_Int x_max = x + bitmap->width; FT_Int y_max = y + bitmap->rows; for ( i = x, p = 0; i < x_max; i++, p++ ) { for ( j = y, q = 0; j < y_max; j++, q++ ) { if ( i < 0 || j < 0 || i >= var.xres || j >= var.yres ) continue; //image[j][i] |= bitmap->buffer[q * bitmap->width + p]; lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]); } } } int main( int argc, char **argv ) { int hzk_fd; int fd_fb; struct fb_fix_screeninfo fix; int screen_size; FT_Library library; FT_Error error; FT_Face face; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ double angle; wchar_t *chinese_char = L"周zhou"; unsigned char str[]={0xd6,0xd0}; struct stat hzk_stat; fd_fb = open("/dev/fb0", O_RDWR ); if( fd_fb<0 ) { perror("oepn failed"); return -1; } if( ioctl( fd_fb, FBIOGET_VSCREENINFO, &var ) ) { printf("can‘t get var\n"); return -1; } if( ioctl( fd_fb, FBIOGET_FSCREENINFO, &fix ) ) { printf("can‘t get fix\n"); return -1; } line_width = var.xres * var.bits_per_pixel / 8; pixel_width = var.bits_per_pixel / 8; screen_size = var.xres * var.yres * var.bits_per_pixel / 8; fbmem = (unsigned char *)mmap( NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb,0 ); if( fbmem == (unsigned char *)-1 ) { printf("mmap is failed\n"); return -1; } hzk_fd = open("HZK16", O_RDONLY ); if( hzk_fd<0 ) { printf("can‘t open hzk\n"); return -1; } if( fstat(hzk_fd, &hzk_stat)) { printf("can‘t get fstat\n"); return -1; } hzkmem = (unsigned char *)mmap( NULL, hzk_stat.st_size, PROT_READ, MAP_SHARED,hzk_fd,0 ); if( hzkmem == (unsigned char *)-1 ) { printf("mmap hzk is failed\n"); return -1; } memset( fbmem, 0, screen_size ); lcd_put_ascii(var.xres/2,var.yres/2,‘A‘ ); printf("chinese code : %02x %02x\n", str[0],str[1]); lcd_put_chinese( var.xres/2 +8 ,var.yres/2, str ); if( argc != 2 ) { printf("Usage: %s <font_file>\n", argv[0]); return -1; } error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */ /* use 50pt at 100dpi */ error = FT_Set_Pixel_Sizes( face, 30, 0 ); /* set character size */ angle = ( 0.0 / 360 ) * 3.14159 * 2; /* use 25 degrees */ /* set up matrix */ matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); /* the pen position in 26.6 cartesian space coordinates; */ /* start at (40,0) relative to the upper left corner */ pen.x = (var.xres/2+8+16) * 64; pen.y = ( var.yres/2 - 16 ) * 64; /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, chinese_char[0], FT_LOAD_RENDER ); if(error) { printf("FT_load_char error\n"); return -1; } draw_bitmap( &face->glyph->bitmap, face->glyph->bitmap_left, var.yres - face->glyph->bitmap_top ); return 0; }
sds
以上是关于使用freetype来显示中文汉字和英文字符的主要内容,如果未能解决你的问题,请参考以下文章
Opencv310图片Mat中叠加汉字(freetype+VS2015)