framebuffer其实主要针对LCD屏幕,
对于驱动,一般开发板厂商会做好,如果没有做好,那么就需要编写对应的framebuffer驱动,参考:
- Linux内核自带的framebuffer驱动
- Linux中的绑定文档
- 百度
对于应用编程,主要有几步:
- 找到LCD屏幕对应的设备结点,一般是/dev/fb0;
- 获取LCD的参数,主要是LCD的可变参数
- 用mmap映射LCD的显存,后面就可以直接操作这块区域了
- 操作LCD也是一样的,最基础的就是画一个像素,后面的操作都是基于这个API的。
//获得LCD文件句柄
fd_fb = open("/dev/fb0", O_RDWR);
//获得LCD可变参数(包含分辨率等信息,这些是驱动中设定的)
ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);
line_width = var.xres * var.bits_per_pixel / 8;
pixel_width = var.bits_per_pixel / 8;
screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
//mmap映射
fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
//将LCD屏幕设为白色(每个点都是0xff,即0xffffff)
memset(fb_base, 0xff, screen_size);
//设置某点为红色
lcd_put_pixel(var.xres/2+i, var.yres/2, 0xFF0000);
//取消映射
munmap(fb_base , screen_size);
//关闭LCD文件
close(fd_fb);
嵌入式Linux应用变成之操作屏幕就是这么简单,下面来说一下其它方面的知识。
字符编码和字体类型之间的关系。
- 首先明白,最终都是一个一个像素的设置
- 所以在屏幕上显示一个字符时,先获得其点阵,然后再一个一个像素的设置。
字符编码:比如有ASCII、GB2312、UTF-8等。字符编码就是用不同的数字表示一个字符,比如对于ASCII来说,字符0就是48,即0x30;而对于其它编码来说就不一定了。
字体类型:比如有新宋体、黑体、隶书等。它们其实就是具体的点阵不同(外观不同)。
所以应用编程时是这样的,比如要在LCD屏幕上显示一个“我”字,那么先确定编码方式,得到其编码值,再从字体类型文件中找到其点阵,最后显示到LCD屏幕上去即可。
还有一个问题就是对于LCD屏幕来说,一个像素点颜色的格式,比如RGB888、RGB565,所以在画一个像素时需要转换。我就不关心这些了,网上应该有api。
例子
lcd_put_ascii(var.xres/2, var.yres/2, 'A');
unsigned char str[] = "中";
lcd_put_chinese(var.xres/2 + 8, var.yres/2, str);
//从上面可以看出,显示字符和汉字时对于接口来说没有什么不同
//技巧
//对于中文字符库,我们可以把文件直接映射到内存,这样读取时都很块
freetype的使用
它是一个开源的字体引擎,用于渲染文字。分为以下几大步:
-
初始化FreeType Library;
声明一个Library对象,我感觉它里面应该包含了一些api,后面加载具体字体时会使用到其中的api来进行配置。
-
初始化和载入Font Face;
读入字体文件,通过Library对象来对FontFace进行一些基本配置。
-
设置字符大小;
-
渲染字符,得到相应的bitmap;
-
拷贝并排版文字。
wchar_t *chinese_str = L"繁";
FT_Library library;
FT_Face face;
FT_Vector pen;
FT_GlyphSlot slot;
int font_size = 24;
error = FT_Init_FreeType( &library );
//argv[1]是具体的字体文件,比如新宋体
error = FT_New_Face( library, argv[1], 0, &face );
slot = face->glyph;
FT_Set_Pixel_Sizes(face, font_size, 0);
//获得位图,保存在face->glyph.bitmap中
error = FT_Load_Char(
face,
chinese_str[0],
FT_LOAD_RENDER );
//向LCD输出
draw_bitmap( &slot->bitmap,
var.xres/2,
var.yres/2);
freetype传入一串字符串后,固定其第一个字符原点后,后面的字符的位置也就固定了,可以通过结构体中各成员获得,具体就不说了。直接使用api。
此文件下的show_line.c就是使用freetype在某个位置显示一行文字的例程。
- 打开LCD设备结点,即/dev/fb0
- 通过ioctl获得LCD的可变参数(如分辨率)
- 映射LCD显存
- 定义一个Library、Face、pen、slot
- 初始化Library、加载字体
- 配置,渲染并获得位图
- 更新LCD显存