FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,可以非常方便我们开发字体显示相关的程序功能。它支持单色位图、反走样位图的渲染。FreeType库是高度模块化的程序库,虽然它是使用ANSI C开发,但是采用面向对象的思想,因此,FreeType的用户可以灵活地对它进行裁剪。关于freetype的详细信息可以参考freetype的官方网站:https://www.freetype.org/来获取更多相关的信息。
CSDN下载地址:https://download.csdn.net/download/tech_pro/9873843
[root@wbyq pc_work]# tar xvf /mnt/hgfs/linux-share-dir/freetype-2.4.10.tar.bz2 [root@wbyq freetype-2.4.10]# ./configure --host=arm-linux --prefix=$PWD/_install [root@wbyq freetype-2.4.10]# make && make install [root@wbyq freetype-2.4.10]# tree _install/ _install/ ├── bin │ └── freetype-config ├── include │ ├── freetype2 │ │ └── freetype │ │ ├── config │ │ │ ├── ftconfig.h │ │ │ ├── ftheader.h │ │ │ ├── ftmodule.h │ │ │ ├── ftoption.h │ │ │ └── ftstdlib.h │ │ ├── freetype.h │ │ ├── ftadvanc.h │ │ ├── ftbbox.h │ │ ├── ftbdf.h │ │ ├── ftbitmap.h │ │ ├── ftbzip2.h │ │ ├── ftcache.h │ │ ├── ftchapters.h │ │ ├── ftcid.h │ │ ├── fterrdef.h │ │ ├── fterrors.h │ │ ├── ftgasp.h │ │ ├── ftglyph.h │ │ ├── ftgxval.h │ │ ├── ftgzip.h │ │ ├── ftimage.h │ │ ├── ftincrem.h │ │ ├── ftlcdfil.h │ │ ├── ftlist.h │ │ ├── ftlzw.h │ │ ├── ftmac.h │ │ ├── ftmm.h │ │ ├── ftmodapi.h │ │ ├── ftmoderr.h │ │ ├── ftotval.h │ │ ├── ftoutln.h │ │ ├── ftpfr.h │ │ ├── ftrender.h │ │ ├── ftsizes.h │ │ ├── ftsnames.h │ │ ├── ftstroke.h │ │ ├── ftsynth.h │ │ ├── ftsystem.h │ │ ├── fttrigon.h │ │ ├── fttypes.h │ │ ├── ftwinfnt.h │ │ ├── ftxf86.h │ │ ├── t1tables.h │ │ ├── ttnameid.h │ │ ├── tttables.h │ │ ├── tttags.h │ │ └── ttunpat.h │ └── ft2build.h ├── lib │ ├── libfreetype.a │ ├── libfreetype.la │ ├── libfreetype.so -> libfreetype.so.6.9.0 │ ├── libfreetype.so.6 -> libfreetype.so.6.9.0 │ ├── libfreetype.so.6.9.0 │ └── pkgconfig │ └── freetype2.pc └── share aclocal freetype2.m4 9 directories, 56 files [root@wbyq freetype-2.4.10]# |
1. 拷贝生成的库到开发板 [root@wbyq freetype-2.4.10]# cp _install/lib/*.so* /home/wbyq/rootfs/lib/ -fdv 2. 再将_install目录下的头文件和库文件拷贝到编译器的目录下,方便编译器在编译程序时能找到库和头文件。 [wbyq@wbyq freetype-2.4.10]$ sudo cp _install/include/ft2build.h /home/wbyq/work/arm-linux-gcc/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/usr/include/ [wbyq@wbyq freetype-2.4.10]$ sudo cp _install/include/freetype2/freetype/ /home/wbyq/work/arm-linux-gcc/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/usr/include/ -rf [wbyq@wbyq freetype-2.4.10]$ sudo cp _install/lib/*.so* /home/wbyq/work/arm-linux-gcc/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/usr/lib/ -dv 3. 在编译调用freetype库函数的源程序时,需要指定库文件。 比如:[wbyq@wbyq lcd_freetype]$ arm-linux-gcc freetype.c -lfreetype |
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> #include <string.h> #include <linux/fb.h> #include <sys/mman.h> #include <math.h> #include <wchar.h> #include <ft2build.h> #include FT_FREETYPE_H #include FT_STROKER_H #define LCD_DEVICE "/dev/fb0" int lcd_fd; struct fb_var_screeninfo vinfo;//可变参数 struct fb_fix_screeninfo finfo; //固定参数 unsigned char *lcd_mem=NULL; //LCD首地址 typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; /*定义一个结构体存放矢量字体的配置*/ struct FREE_TYPE_CONFIG { FT_Library library; FT_Face face; FT_GlyphSlot slot; FT_Vector pen; /* untransformed origin */ FT_Error error; FT_BBox bbox; FT_Glyph glyph; }; struct FREE_TYPE_CONFIG FreeTypeConfig; /* 函数功能: 封装画点函数 函数参数: u32 x,u32 y,u16 c */ void LCD_DrawPoint(u32 x,u32 y,u32 c) { u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8); *lcd_p=c; } /* 函数功能: 封装读点函数 函数参数: u32 x,u32 y,u16 c */ u32 LCD_ReadPoint(u32 x,u32 y) { u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8); return *lcd_p; } /*LCD显示矢量字体的位图信息 *bitmap : 要显示的字体的矢量位图 *x : 显示的x坐标 *y : 显示的y坐标 */ void LCD_DrawBitmap(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>x_max)||(j>y_max)||(i<0)||(j<0))continue; if(bitmap->buffer[q*bitmap->width+p]!=0) { LCD_DrawPoint(i, j,0xFF0033); } else { LCD_DrawPoint(i, j,0xFFFFFF); } } } } /* 函数功能: 初始化FreeType配置 */ int InitConfig_FreeType(char *font_file) { FT_Error error; /*1. 初始化freetype库*/ error=FT_Init_FreeType(&FreeTypeConfig.library); if(error) { printf("freetype字体库初始化失败.n"); return -1; } /*2. 打开加载的字体文件*/ error=FT_New_Face(FreeTypeConfig.library,font_file,0,&FreeTypeConfig.face); if(error) { printf("矢量字体文件加载失败.n"); return -2; } return 0; } /* 函数功能: 释放FreeType配置 */ void FreeType_Config(void) { FT_Done_Face(FreeTypeConfig.face); FT_Done_FreeType(FreeTypeConfig.library); } /* 函数功能: 在LCD屏显示一串文本数据 函数参数: u32 x 坐标位置 u32 y 坐标位置 u32 size 字体大小 wchar_t *text 显示的文本数据 */ int LCD_DrawText(u32 x,u32 y,u32 size,wchar_t *text) { FT_Error error; int i = 0; int bbox_height_min = 10000; int bbox_height_max = 0; /*3. 设置字符的像素的大小为size*size*/ error=FT_Set_Pixel_Sizes(FreeTypeConfig.face,size,0); if(error) { printf("字符的像素大小设置失败.n"); return -1; } /*4. 设置字体文件的轮廓的插槽*/ FreeTypeConfig.slot=FreeTypeConfig.face->glyph; /* 设置坐标为原点坐标 将LCD坐标转换成笛卡尔坐标 单位是 1/64 Point */ FreeTypeConfig.pen.x=x*64; FreeTypeConfig.pen.y=(vinfo.yres-size-y)*64; /*5. 循环的将文字显示出来*/ for(i=0;i<wcslen(text);i++) { FT_Set_Transform(FreeTypeConfig.face,0,&FreeTypeConfig.pen);//设置字体的起始坐标位置 /*装载字符编码,填充face的glyph slot成员*/ error=FT_Load_Char(FreeTypeConfig.face,text[i],FT_LOAD_RENDER); if(error) { printf("装载字符编码失败.n"); return -1; } /*通过glyph slot来获得glyph*/ FT_Get_Glyph(FreeTypeConfig.slot,&FreeTypeConfig.glyph); /*通过glyph来获得cbox*/ FT_Glyph_Get_CBox(FreeTypeConfig.glyph,FT_GLYPH_BBOX_TRUNCATE,&FreeTypeConfig.bbox); /*获得字体高度的最大值和最小值*/ if(bbox_height_min>FreeTypeConfig.bbox.yMin)bbox_height_min=FreeTypeConfig.bbox.yMin; if(bbox_height_max<FreeTypeConfig.bbox.yMax)bbox_height_max=FreeTypeConfig.bbox.yMax; /*画点,把笛卡尔坐标转换成LCD坐标*/ LCD_DrawBitmap(&FreeTypeConfig.slot->bitmap, FreeTypeConfig.slot->bitmap_left, vinfo.yres-FreeTypeConfig.slot->bitmap_top); if(FreeTypeConfig.slot->bitmap_left+size*2>vinfo.xres) { FreeTypeConfig.pen.x=0; //更新X坐标位置 FreeTypeConfig.pen.y=(vinfo.yres-size-y-size)*64; //更新Y坐标位置 } else { /* 更新原点坐标位置 */ FreeTypeConfig.pen.x+=FreeTypeConfig.slot->advance.x; FreeTypeConfig.pen.y+=FreeTypeConfig.slot->advance.y; } } return 0; } int main(int argc,char **argv) { if(argc!=2) { printf("./app <xxx.ttf 字体文件>n"); return 0; } /*1. 打开设备文件*/ lcd_fd=open(LCD_DEVICE,O_RDWR); if(lcd_fd<0) { printf("%s open error.n",LCD_DEVICE); return 0; } /*2. 获取可变参数*/ ioctl(lcd_fd,FBIOGET_VSCREENINFO,&vinfo); printf("x=%d,y=%d,pixel=%dn",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel); /*3. 获取固定参数*/ ioctl(lcd_fd,FBIOGET_FSCREENINFO,&finfo); printf("smem_len=%dn",finfo.smem_len); printf("line_length=%dn",finfo.line_length); /*4. 映射LCD地址*/ lcd_mem=mmap(NULL,finfo.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0); if(lcd_mem==NULL) { printf("映射LCD地址失败.n"); return -1; } memset(lcd_mem,0xFFFFFF,finfo.smem_len); /*5. 初始化配置FreeType*/ InitConfig_FreeType(argv[1]); /*6. 在指定位置显示文本*/ /* wcslen() 函数用于计算宽字符的个数,支持区分中文和英文字符,文本需要在UTF-8编码下。 定义宽字符串示例: wchar_t *wp=L"1234567890中国"; //12 printf("wcslen p:%dn",wcslen(wp)); 返回值是12 */ LCD_DrawText(50,56*0,56,L"北京万邦易嵌科技有限公司"); LCD_DrawText(150,56*1,56,L"www.wanbangee.com"); LCD_DrawText(200,56*3,48,L"FreeType矢量字体"); LCD_DrawText(150,56*5,80,L"Linux驱动开发"); /*7. 释放FreeType配置*/ FreeType_Config(); close(lcd_fd); return 0; } |
all: arm-linux-gcc video_app.c -I /home/wbyq/work/freetype-2.4.10/_install/include -I /home/wbyq/work/freetype-2.4.10/_install/include/freetype2 -o app -lfreetype -ljpeg cp app /home/wbyq/work/rootfs/code rm app -f |