freetype_3_在arm上使用freetype显示文字
安装使用freetype库
1、配置freetype,./configure --host=arm-linux
2、编译freetype,make
3、安装freetype,make DESTDIR=/my_tmp/ install
4、将/my_tmp/usr/local/lib/ 和 /my_tmp/usr/local/include/的内容拷贝到交叉编译链相应目录下
(如果交叉编译链的库和头文件的前置路径相同,配置时可以使用–prefix= 指定安装目录,第四步省略)
5、在头文件所在的include目录中,找到freetype2,将freetype2的内容移动到include目录,将freetype2目录删除
完成以上工作后,对freetype在pc上的例程进行交叉编译 arm-linux-gcc -o build example1.c -lm -lfreetype
将安装的freetype库中后缀为.so的文件拷贝到板上lib目录下
将build和字体文件拷贝到板上运行,无错误提示
如果出现编码转换错误,或者运行后显示字符与实际不符,在编译时加上两个选项:
-finput-charset=gbk
-fexec-charset=gbk
即可
至此完成了freetype移植到arm上的工作,并测试成功
下面实现使用freetype在lcd上显示字符
完整代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/resource.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/font.h>
#include <string.h>
#include <linux/fb.h>
#include <stdio.h>
#include <wchar.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
//#include FT_GLYPH_H
int fd_fb;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
int screen_size;
unsigned char *fbmem;
unsigned int line_width;
unsigned int pixel_width;
void lcd_put_pixel(int x, int y, unsigned int color)
{
unsigned char *pen_8 = fbmem + y * line_width + x * pixel_width;
unsigned short *pen_16;
unsigned int *pen_32;
unsigned int r,g,b;
pen_16 = (unsigned short *)pen_8;
pen_32 = (unsigned int *)pen_8;
switch(var.bits_per_pixel)
{
case 8:
{
*pen_8 = color;
break;
}
case 16:
{
r = (color>>16) & 0x1f;
g = (color>>8) & 0x3f;
b = (color>>0) & 0x1f;
color = (r<<11) | (g<<5) | (b);
*pen_16 = color;
break;
}
case 32:
{
*pen_32 = color;
break;
}
default:
{
printf("can't support %dbpp\r\n",var.bits_per_pixel);
break;
}
}
}
void 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 < 0 || j < 0 || i >= var.xres || j >= var.yres)
continue;
//image[j][i] |= bitmap->buffer[q * bitmap->width + p];
lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]);
}
}
}
int main(int argv, char **argc)
{
FT_Library library;
FT_Face face;
FT_Vector pen;
wchar_t *new_str = L"小飞龙";
FT_GlyphSlot slot;
double angle;
FT_Matrix matrix;
int err;
int n;
if(argv != 2)
{
printf("Usage : %s <font_file>\r\n",argc[0]);
return -1;
}
fd_fb = open("/dev/fb0",O_RDWR);
if(fd_fb < 0)
{
printf("can't open /dev/fb0\r\n");
return -1;
}
if(ioctl(fd_fb,FBIOGET_VSCREENINFO,&var))
{
printf("can't get var\r\n");
return -1;
}
if(ioctl(fd_fb,FBIOGET_FSCREENINFO,&fix))
{
printf("can't get fix\r\n");
return -1;
}
screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
fbmem = (unsigned char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE , MAP_SHARED, fd_fb, 0);
if(fbmem == (unsigned char *)-1)
{
printf("can't mmap\r\n");
return -1;
}
pixel_width = var.bits_per_pixel / 8;
line_width = var.xres * pixel_width;
memset(fbmem,0xffffff,screen_size);
err = FT_Init_FreeType(&library);
err = FT_New_Face(library, argc[1], 0, &face );
FT_Set_Pixel_Sizes(face,32,0);
slot = face->glyph;
pen.x = var.xres / 2;
pen.x *= 64;
pen.y = var.yres / 2;
pen.y *= 64;
angle = ( 0.0 / 360 ) * 3.14159 * 2;
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
for(n = 0;n < wcslen(new_str);n++)
{
FT_Set_Transform(face,&matrix, &pen);
err = FT_Load_Char(face, new_str[n],FT_LOAD_RENDER);
if(err)
{
printf("FT load char err\r\n");
return -1;
}
draw_bitmap(&slot->bitmap,slot->bitmap_left,var.yres - slot->bitmap_top);
pen.x += 64*32;
pen.y += 64*32;
}
return 0;
}
void lcd_put_pixel(int x, int y, unsigned int color)
{
unsigned char *pen_8 = fbmem + y * line_width + x * pixel_width;
unsigned short *pen_16;
unsigned int *pen_32;
unsigned int r,g,b;
pen_16 = (unsigned short *)pen_8;
pen_32 = (unsigned int *)pen_8;
switch(var.bits_per_pixel)
{
case 8:
{
*pen_8 = color;
break;
}
case 16:
{
r = (color>>16) & 0x1f;
g = (color>>8) & 0x3f;
b = (color>>0) & 0x1f;
color = (r<<11) | (g<<5) | (b);
*pen_16 = color;
break;
}
case 32:
{
*pen_32 = color;
break;
}
default:
{
printf("can't support %dbpp\r\n",var.bits_per_pixel);
break;
}
}
}
void 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 < 0 || j < 0 || i >= var.xres || j >= var.yres)
continue;
//image[j][i] |= bitmap->buffer[q * bitmap->width + p];
lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]);
}
}
}
lcd显示