基於嵌入式linux的freetype矢量字體簡單顯示的實現

一、freetype簡介

FreeType庫是一個完全免費(開源)的、高質量的且可移植的字體引擎,它提供統一的接口來訪問多種字體格式文件,可以非常方便我們開發字體顯示相關的程序功能。它支持單色位圖、反走樣位圖的渲染。FreeType庫是高度模塊化的程序庫,雖然它是使用ANSI C開發,但是採用面向對象的思想,因此,FreeType的用戶可以靈活地對它進行裁剪。關於freetype的詳細信息可以參考freetype的官方網站:https://www.freetype.org/來獲取更多相關的信息。

二、基本開發環境

PC機:Ubuntu9.10

交叉工具版本 :gcc version 4.3.2

開發板:JZ2440

linux內核版本:Linux-3.4.10

freetype版本:Freetype-2.4.10

要想使用freetype矢量字體庫來開發,必須先要下載這個矢量字體庫,可以從官網:https://www.freetype.org/下載,也可以從我上傳的資料點擊這裏下載。下載完成後將這個矢量字體庫編譯安裝到交叉編譯工具鏈和開發板的根文件系統當中(具體過程可以自己去搜索)。

三、基本開發步驟

1、打開LCD液晶設備

爲了使用freetype矢量字體庫來顯示文字,首先要把和硬件LCD液晶相關的顯示字體操作的API接口實現。

1.1 打開LCD設備,獲取相關參數,映射顯存到用戶空間

這部分具體代碼實現如下:

/* 以可讀可寫方式打開LCD設備驅動文件 */
	fd_fb = open("/dev/fb0", O_RDWR);
	if(fd_fb == -1)
	{
		printf("can't open /dev/fb0!\n");
		return -1;
	}

	/* 獲取液晶屏設備的可變參數 */
	ret = ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);
	if(ret == -1)
	{
		printf("can't ioctl for /dev/fb0!\n");
		return -1;
	}

	/* 獲取液晶屏設備的固定參數 */
	ret = ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix);
	if(ret == -1)
	{
		printf("can't ioctl for /dev/fb0!\n");
		return -1;
	}

	/* 獲取相關的顯存信息 */
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
	line_width  = var.xres * var.bits_per_pixel / 8;
	pixel_width = var.bits_per_pixel / 8;

	/* 將液晶顯存映射到用戶空間 */
	fbmem = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
	if(fbmem == (char *)-1)
	{
		printf("mmap for /dev/fb0 error!\n");
		return -1;
	}

	/* 將液晶屏清爲黑色 */
	lcd_clear_screen(BLACK);

1.2 實現像素顯示和清屏接口

像素顯示是所有液晶屏顯示的最基本的調用接口,通過它可以實現各種各樣的顯示技巧,那麼這個函數的具體實現如下:
/*	在液晶屏上面顯示一個像素
 *		x : 表示x座標
 *		y : 表示y座標
 *		color : 表示像素顯示的顏色
 */
void lcd_put_pixel(int x, int y, int color)
{
	/* 獲取像素點在顯存中的位置 */
	unsigned char *pen8 = fbmem + y * line_width + x * pixel_width;
	unsigned short *pen16 = (unsigned short *)pen8;
	unsigned int *pen32 = (unsigned int *)pen32;

	int red, green, blue;

	/* 判斷一個像素點所佔的位數 */
	switch(var.bits_per_pixel)
	{
		case 16:		// RGB = 565
		{
			red   = (color >> 16) & 0xff;
			green = (color >> 8) & 0xff;
			blue  = color & 0xff;

			*pen16 = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
			break;	
		}
		case 32:	
		{
			*pen32 = color;
			break;
		}
		default :
		{
			printf("don't support this size of pixel : %d\n", var.bits_per_pixel);
			break;
		}
	}
}
清屏函數的實現也是經常用到的,它的主要作用就是把屏幕清成同一種顏色,方便文字、圖像等的顯示,它的具體實現如下所示:
/*	液晶屏清屏
 *		color : 表示清屏顏色
 */
void lcd_clear_screen(int color)
{
	memset(fbmem, color, screen_size);
}

2、初始化庫

初始化庫,會創建一個freetype庫的實例,具體實現如下:

/* 初始化freetype庫 */
	error = FT_Init_FreeType( &library );
	if(error)
	{
		printf("FT_Init_FreeType error!\n");
		return -1;
	}

3、加載字體文件

加載字體,創建一個face對象,用它來描述加載的字體的類型,具體的實現如下:

/* 打開加載的字體文件 */
 	error = FT_New_Face( library, argv[1], 0, &face );
  	if(error)
  	{
		printf("FT_New_Face error!\n");
		return -1;
	}
argv[1] : 傳入加載的字體文件的名稱。

4、設置字體大小

我們這裏通過像素的形式來設置字體的大小,設置字體的大小爲24*24,具體實現如下:

/* 設置字符的像素的大小爲24*24 */
	error = FT_Set_Pixel_Sizes(face, 24, 0);
	if(error)
	{
		printf("FT_Set_Pixel_Sizes error!\n");
		return -1;
	}

5、根據字符的編碼值,加載glyph

FT_Set_Transform(face, 0, &pen);	// 設置字體的起始座標位置

		/* 裝載字符編碼,填充face的glyph slot成員 */
		error = FT_Load_Char( face, wcstr1[i], FT_LOAD_RENDER);
		if(error)
		{
			printf("FT_Load_Char error!\n");
			return -1;
		}

6、獲取字體的位圖信息,通過液晶屏顯示出來

這個函數的具體實現如下:

/*	LCD顯示矢量字體的位圖信息
 *		bitmap : 要顯示的字體的矢量位圖
 *		x : 顯示的x座標
 *		y : 顯示的y座標
 */
void lcd_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 > x_max) || (j > y_max) || (i < 0) || (j < 0))
				continue;
			if(bitmap->buffer[q * bitmap->width + p] != 0)
			{
				lcd_put_pixel(i, j, WHITE);
			}
			else
			{
				lcd_put_pixel(i, j, BLACK);
			}
		}
	}
	
}

以上就簡單的介紹了整個freetype的開發基本過程,完整的內容可以參考freetype的官方網站:https://www.freetype.org/,也可以參考這篇文章:https://wenku.baidu.com/view/2d24be10cc7931b765ce155b.html


附錄:完整代碼實現請從以下鏈接下載

http://download.csdn.net/download/tech_pro/9873843


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章