您的位置:首页 > 其它

数码相框——矢量字体原理(7)

2014-03-06 15:21 274 查看
这一节,主要实现在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
);    

         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
.image»ñµÃ±ß½çÐÅÏ¢²¢´æ·ÅÔÚglyph_bboxÖÐ*/

          FT_Glyph_Get_CBox(glyphs
.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
.image, 0, &pen);

         /* convert glyph image to bitmap (destroy the glyph copy!) */

         /*/ ʸÁ¿Í¼×ª»»ÎªÎ»Í¼ÒÔ±ãÏÔʾ*/

         error = FT_Glyph_To_Bitmap( &glyphs
.image, FT_RENDER_MODE_NORMAL, 0, /* no additional translation */ 1 );

         if(!error)

         {

             /*Ç¿Öƽ«glyphs
.imageת»»ÎªFT_BitmapGlyph ÀàÐ͵ÄÊý¾Ý*/

            FT_BitmapGlyph bit = (FT_BitmapGlyph) glyphs
.image;    

            draw_bitmap( &bit->bitmap, bit->left, fb_var.yres- bit->top );

            FT_Done_Glyph( glyphs
.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;

}

测试结果如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  项目班