linux应用项目(一)数码相框(2)数码相框之freetype实现矢量字体的显示

xiaoxiao2021-02-28  127

上一节我们通过点阵数组实现了字母的显示:http://blog.csdn.net/fengyuwuzu0519/article/details/72877318

现在我们通过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[n], 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
转载请注明原文地址: https://www.6miu.com/read-43518.html

最新回复(0)