这一节,主要实现在LCD的居中显示两行字符
来源:http://liu1227787871.blog.163.com/blog/static/2053631972012628101423971/
代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
//#include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/fb.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
int fd_fb = 0;
struct fb_var_screeninfo fb_var;
struct fb_fix_screeninfo fb_fix;
int screen_size = 0;
unsigned char* fb_mem;
int line_width;
int pix_width;
typedef struct TGlyph_ {
FT_UInt index; /* glyph index */
FT_Vector pos; /* glyph origin on the baseline */
FT_Glyph image; /* glyph image */
} TGlyph, *PGlyph;
#define MAX_GLYPHS 100
void lcd_put_pixel(int x, int y, unsigned int color)
{
unsigned char *pen_8 = (unsigned char*)(fb_mem+y*line_width+x*pix_width);
unsigned short *pen_16;
unsigned int *pen_32;
pen_16 = (unsigned short*)pen_8;
pen_32 = (unsigned int*)pen_8;
unsigned char red,green,blue;
switch(fb_var.bits_per_pixel)
{
case 8:
*pen_8 = color;
break;
case 16:
red = (color >>16)&0xff;
green = (color>>8)&0xff;
blue = (color>>0)&0xff;
color = ((red>>3)<<11)|((green>>2)<<5)|((blue>>3)<<0);
*pen_16 = color;
break;
case 32:
*pen_32 = color;
break;
default:
printf("Can' support error\n");
break;
}
}
/* Replace this function with something useful. */
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 >= fb_var.xres|| j >= fb_var.yres)
continue;
lcd_put_pixel(i,j, bitmap->buffer[q * bitmap->width + p]);
}
}
}
int Get_Glyphs_Frm_Wstr(FT_Face face, wchar_t* wstr, TGlyph glyphs[] )
{
int n;
PGlyph glyph = glyphs;
int pen_x = 0;
int pen_y = 0;
int error;
FT_GlyphSlot slot =face->glyph;
for(n=0;n<wcslen(wstr);n++)
{
/*¸ù¾Ýunicode±àÂë»ñµÃglyphË÷Òý*/
glyph->index = FT_Get_Char_Index( face, wstr[n] );
glyph->pos.x = pen_x;
glyph->pos.y = pen_y;
/*¸ù¾ÝË÷Òý»ñµÃglyph£¬²¢½«glyph´æ·ÅÔÚface->glyph*/
error = FT_Load_Glyph( face, glyph->index, FT_LOAD_DEFAULT );
if ( error )
continue;
/* ½«face->glyphÌáÈ¡³öÀ´´æ·ÅÔÚglyph->imageÀïÃæ*/
error = FT_Get_Glyph( face->glyph, &glyph->image);
if ( error )
continue;
/* translate the glyph image now */
/*½«glyphµÄλÖ÷ÅÔÚglyph->imageÖÐ*/
FT_Glyph_Transform( glyph->image, 0, &glyph->pos);
pen_x += slot->advance.x; /* 1/64 point */
/* increment number of glyphs */
glyph++;
}
/* count number of glyphs loaded */
return (glyph - glyphs);
}
void compute_string_bbox( TGlyph glyphs[],FT_UInt num_glyphs, FT_BBox *abbox )
{
FT_BBox bbox;
int n;
bbox.xMin = bbox.yMin = 32000;
bbox.xMax = bbox.yMax = -32000;
for ( n = 0; n < num_glyphs; n++ )
{
FT_BBox glyph_bbox;
/*¸ù¾Ýglyphs[n].image»ñµÃ±ß½çÐÅÏ¢²¢´æ·ÅÔÚglyph_bboxÖÐ*/
FT_Glyph_Get_CBox(glyphs[n].image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox );
if(glyph_bbox.xMin < bbox.xMin)
bbox.xMin = glyph_bbox.xMin;
if(glyph_bbox.xMax > bbox.xMax)
bbox.xMax = glyph_bbox.xMax;
if(glyph_bbox.yMin < bbox.yMin)
bbox.yMin = glyph_bbox.yMin;
if(glyph_bbox.yMax > bbox.yMax)
bbox.yMax = glyph_bbox.yMax;
}
/*·µ»Øbbox*/
*abbox = bbox;
}
void Draw_Glyphs(TGlyph glyphs[], FT_UInt num_glyphs, FT_Vector pen)
{
int n;
int error;
for(n=0;n<num_glyphs;n++)
{
/*¼Ç¼ԵãÐÅÏ¢*/
FT_Glyph_Transform( glyphs[n].image, 0, &pen);
/* convert glyph image to bitmap (destroy the glyph copy!) */
/*/ ʸÁ¿Í¼×ª»»ÎªÎ»Í¼ÒÔ±ãÏÔʾ*/
error = FT_Glyph_To_Bitmap( &glyphs[n].image, FT_RENDER_MODE_NORMAL, 0, /* no additional translation */ 1 );
if(!error)
{
/*Ç¿Öƽ«glyphs[n].imageת»»ÎªFT_BitmapGlyph ÀàÐ͵ÄÊý¾Ý*/
FT_BitmapGlyph bit = (FT_BitmapGlyph) glyphs[n].image;
draw_bitmap( &bit->bitmap, bit->left, fb_var.yres- bit->top );
FT_Done_Glyph( glyphs[n].image);
}
}
}
int main(int argc,char ** argv)
{
FT_Library library;
FT_Face face;
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
FT_Error error;
double angle;
FT_BBox bbox;
// FT_Glyph glyph;
int target_height;
int n;
int line_ymax = 0;
int line_ymin =320;
wchar_t *wstr1 = L"hello嵌入式g";
wchar_t *wstr2 = L"www.100ask.com";
TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */
FT_UInt num_glyphs;
int line_box_width;
int line_box_height;
fd_fb = open("/dev/fb0",O_RDWR);
if(fd_fb < 0)
{
printf("open /dev/fb0 failed\n");
return -1;
}
if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &fb_var))
{
printf("get var information failed\n");
return -1;
}
if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fb_fix))
{
printf("get fix information failed\n");
return -1;
}
screen_size = fb_var.xres * fb_var.yres * fb_var.bits_per_pixel /8;
line_width = fb_var.xres * fb_var.bits_per_pixel /8;
pix_width = fb_var.bits_per_pixel /8;
fb_mem =(unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if(fb_mem == (unsigned char *)-1)
{
printf("fb_mem mmap failed\n ");
return -1;
}
memset(fb_mem, 0, screen_size);
/*Ôö¼ÓFreetype*/
if(argc != 2)
{
printf("Useage: %s <font file>\n",argv[0]);
return -1;
}
error = FT_Init_FreeType( &library ); /* initialize library */
if(error)
{
printf("FT_Init_FreeType failed\n");
return -1;
}
error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
if(error)
{
printf("FT_New_Face failed\n");
return -1;
}
FT_Set_Pixel_Sizes(face, 24, 0);
/*wstr1*/
num_glyphs = Get_Glyphs_Frm_Wstr(face, wstr1, glyphs);
compute_string_bbox(glyphs, num_glyphs, &bbox);
/*¼ÆËã³öÒ»ÐÐ×ÖÌåµÄ¿í¶ÈºÍ¸ß¶È*/
line_box_width = bbox.xMax - bbox.xMin;
line_box_height = bbox.yMax - bbox.yMin;
/*ÖØж¨Î»µÚ¶þÐеÄ×ø±ê*/
/*定位使宽字符居中显示*/
pen.x = (fb_var.xres - line_box_width)/2 * 64;
pen.y = (fb_var.yres - line_box_height)/2 * 64;
/*ÏÔʾ*/
Draw_Glyphs(glyphs, num_glyphs, pen);
/*wstr2*/
num_glyphs = Get_Glyphs_Frm_Wstr(face, wstr2, glyphs);
compute_string_bbox(glyphs, num_glyphs, &bbox);
line_box_width = bbox.xMax - bbox.xMin;
line_box_height = bbox.yMax - bbox.yMin;
/*重新的定位第二宽字符的位置*/
pen.x = (fb_var.xres - line_box_width)/2 * 64;
pen.y = pen.y - 24 *64;
Draw_Glyphs(glyphs, num_glyphs, pen);
FT_Done_Face ( face );
FT_Done_FreeType( library );
return 0;
}
测试结果如下: