linux应用项目(一)数码相框(2)数码相框之freetype实现矢量字体的显示
2017-06-07 14:46
579 查看
上一节我们通过点阵数组实现了字母的显示:http://blog.csdn.net/fengyuwuzu0519/article/details/72877318
现在我们通过freetype这个框架在PC和单板LCD上分别实现矢量字体的显示。
(2)显示实现过程
(3)如何写代码
(4)分析源码自带的例子
(5)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
(6)编译
gcc -o example1 example1.c -I/usr/local/include/freetype2/ -lfreetype -lm
(7)执行
./example1 ./simsun.ttc abc
在(0,,40)显示
(8)显示文字
(9)找编码太麻烦了
#include<wchar.h>
//intchinese_str[] = {0x97e6, 0x4e1c, 0x5c71, 0x0067};
//char *str = "韦东山";
wchar_t *chinese_str = L"韦东山g";
unsigned int *p = (wchar_t *)chinese_str;
gcc -finput-charset=GBK-fexec-charset=UTF-8 -o example1 example1.c -I /usr/local/include/freetype2 -lfreetype -lm
(10)增加打印信息
gcc -finput-charset=GBK-fexec-charset=UTF-8 -o example1 example1.c -I /usr/local/include/freetype2 -lfreetype -lm
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上显示矢量字体
arm-linux-gcc -finput-charset=GBK -fexec-charset=GBK -o show_font show_font.c -lfreetype -lm
现在我们通过freetype这个框架在PC和单板LCD上分别实现矢量字体的显示。
一、PC上矢量字体的显示
(1)矢量字体:存储一些关健点,然后通过贝塞尔曲线连接。(2)显示实现过程
(3)如何写代码
(4)分析源码自带的例子
/* 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 25 degrees */ target_height = HEIGHT; error = FT_Init_FreeType( &library ); /* 初始化 initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* 打开字体文件argv[1] create face object */ /* error handling omitted */ #if 0 /* use 50pt at 100dpi */ error = FT_Set_Char_Size( face, 50 * 64, 0, 100, 0 ); /* 设置字符大小 set character size */ /* pixels = 50 /72 * 100 = 69 */ //50*64/64/72(多少英寸) *100 100:每个英寸有多少个像素点 #else FT_Set_Pixel_Sizes(face, 24, 0); //24像素大小 类似于点阵里点的个数。高度=宽度=24 #endif /* error handling omitted */ slot = face->glyph; //取出关键点后存在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 (0,40):lcd relative to the upper left corner */ pen.x = 0 * 64; pen.y = ( target_height - 40 ) * 64; //此处是笛卡尔坐标。原点在左下角 //lcd里原点在左上角 x‘=x y’=hight-y for ( n = 0; n < num_chars; n++ ) { /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); //旋转 matrix:旋转矩阵 /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, text , FT_LOAD_RENDER );// FT_Load_Char:找到;取出;转换为位图;=那三个函数 if ( error ) //FT_LOAD_RENDER: glyph立刻转换为位图 //text:unicode ascii编码 continue; /* ignore errors */ /* now, draw to our target surface (convert position) */ draw_bitmap( &slot->bitmap, //draw_bitmap:打印出来 bitmap里面含有点阵存到image数组中 slot->bitmap_left, target_height - slot->bitmap_top ); /* increment pen position */ pen.x += slot->advance.x; pen.y += slot->advance.y; } show_image(); //打印image数组 FT_Done_Face ( face ); FT_Done_FreeType( library ); return 0; } /* EOF */
(5)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
(6)编译
gcc -o example1 example1.c -I/usr/local/include/freetype2/ -lfreetype -lm
(7)执行
./example1 ./simsun.ttc abc
在(0,,40)显示
(8)显示文字
(9)找编码太麻烦了
#include<wchar.h>
//intchinese_str[] = {0x97e6, 0x4e1c, 0x5c71, 0x0067};
//char *str = "韦东山";
wchar_t *chinese_str = L"韦东山g";
unsigned int *p = (wchar_t *)chinese_str;
gcc -finput-charset=GBK-fexec-charset=UTF-8 -o example1 example1.c -I /usr/local/include/freetype2 -lfreetype -lm
(10)增加打印信息
gcc -finput-charset=GBK-fexec-charset=UTF-8 -o example1 example1.c -I /usr/local/include/freetype2 -lfreetype -lm
二、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上显示矢量字体
#include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <linux/fb.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <math.h> #include <wchar.h> #include <stdlib.h> #include <ft2build.h> #include FT_FREETYPE_H #include FT_GLYPH_H #define FONTDATAMAX 4096 static const unsigned char fontdata_8x16[FONTDATAMAX] = { }; int fd_fb; struct fb_var_screeninfo var; /* Current var */ struct fb_fix_screeninfo fix; /* Current fix */ int screen_size; unsigned char *fbmem; unsigned int line_width; unsigned int pixel_width; int fd_hzk16; struct stat hzk_stat; unsigned char *hzkmem; /* color : 0x00RRGGBB */ 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 int *pen_32; unsigned int red, green, blue; pen_16 = (unsigned short *)pen_8; pen_32 = (unsigned int *)pen_8; switch (var.bits_per_pixel) { 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 surport %dbpp\n", var.bits_per_pixel); 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)) { /* show */ lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */ } else { /* hide */ lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */ } } } } void lcd_put_chinese(int x, int y, unsigned char *str) { unsigned int area = str[0] - 0xA1; unsigned int where = str[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)) { /* show */ lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */ } else { /* hide */ lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */ } } } } /* 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; //printf("x = %d, y = %d\n", x, y); 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) { unsigned char str[] = "中"; wchar_t *chinese_str = L"繁"; FT_Library library; FT_Face face; int error; FT_Vector pen; FT_GlyphSlot slot; FT_Matrix matrix; /* transformation matrix */ double angle; if (argc != 3) { printf("Usage : %s <font_file> <angle>\n", argv[0]); return -1; } fd_fb = open("/dev/fb0", O_RDWR); if (fd_fb < 0) { printf("can't open /dev/fb0\n"); 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("can't mmap\n"); return -1; } fd_hzk16 = open("HZK16", O_RDONLY); if (fd_hzk16 < 0) { printf("can't open HZK16\n"); return -1; } if(fstat(fd_hzk16, &hzk_stat)) { printf("can't get fstat\n"); return -1; } hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0); if (hzkmem == (unsigned char *)-1) { printf("can't mmap for hzk16\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); /* 显示矢量字体 */ error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */ /* error handling omitted */ slot = face->glyph; FT_Set_Pixel_Sizes(face, 24, 0); /* 确定座标: * lcd_x = var.xres/2 + 8 + 16 * lcd_y = var.yres/2 + 16 * 笛卡尔座标系: * x = lcd_x = var.xres/2 + 8 + 16 * y = var.yres - lcd_y = var.yres/2 - 16 */ pen.x = (var.xres/2 + 8 + 16) * 64; pen.y = (var.yres/2 - 16) * 64; angle = ( 1.0 * strtoul(argv[2], NULL, 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 ); /* set transformation */ FT_Set_Transform( face, &matrix, &pen); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER ); if (error) { printf("FT_Load_Char error\n"); return -1; } draw_bitmap( &slot->bitmap, slot->bitmap_left, var.yres - slot->bitmap_top); return 0; }
arm-linux-gcc -finput-charset=GBK -fexec-charset=GBK -o show_font show_font.c -lfreetype -lm
相关文章推荐
- Linux电子书项目之freetype实现矢量字体的显示(2)
- linux应用项目(一)数码相框(2)数码相框之字符编码与字符的点阵显示
- 基于嵌入式linux的freetype矢量字体简单显示的实现
- linux应用项目(一)数码相框(3)数码相框之电子书
- WindML、FreeType和TrueType三者相结合实现矢量字体的显示
- 3.数码相框-通过freetype库实现矢量显示
- linux应用项目(一)数码相框(1)数码相框之系统框架
- linux应用项目(一)数码相框数码相框之电子书
- 使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果
- 数码相框——矢量字体原理(7)
- 使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果
- 实现 linux 终端上不同字体颜色显示
- 数码相框——矢量字体原理(1)
- 使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果(转载)
- 数码相框——矢量字体原理(4)
- 学习数码相框1.2.0.0字符的编码方式_显示点阵文字_freetype_在PC上测试freetype
- freetype显示矢量字体 -- 在LCD上测试
- (转)使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果
- 数码相框——矢量字体原理(6)
- 数码相框——矢量字体原理(5)