一、freetype簡介
FreeType庫是一個完全免費(開源)的、高品質的且可移植的字型引擎,它提供統一的接口來通路多種字型格式檔案,可以非常友善我們開發字型顯示相關的程式功能。它支援單色位圖、反走樣位圖的渲染。FreeType庫是高度子產品化的程式庫,雖然它是使用ANSI C開發,但是采用面向對象的思想,是以,FreeType的使用者可以靈活地對它進行裁剪。關于freetype的詳細資訊可以參考freetype的官方網站:https://www.freetype.org/來擷取更多相關的資訊。
CSDN下載下傳位址: https://download.csdn.net/download/tech_pro/9873843
二、下載下傳源碼編譯安裝
2.1 編譯freetype
[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]# |
---|
2.2 部署編譯環境和運作環境
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 |
---|
2.3 windows電腦上的矢量字型存放目錄
2.4 示例代碼
#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=%d\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);
/*3. 擷取固定參數*/
ioctl(lcd_fd,FBIOGET_FSCREENINFO,&finfo);
printf("smem_len=%d\n",finfo.smem_len);
printf("line_length=%d\n",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:%d\n",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;
}
複制
2.5 編譯源代碼的Makefile示例
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
複制