基于嵌入式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


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