zoukankan      html  css  js  c++  java
  • 使用freetype来显示中文汉字和英文字符

    这里我们用到了freetype。进入官网http://savannah.nongnu.org/download/freetype/ 中下载最新的版本2.7的源代码和文件。freetype-2.7.tar.gz freetype-doc-2.7.tar.gz

    首先我们在使用官方提供的程序在pc上运行一下。需要安装zlib库。

    freetype-doc-2.7.tar.gz文件中的docus目录下的tutorial有一个example.c的源文件。

    example.c:

    /* example1.c                                                      */
    /*                                                                 */
    /* This small program shows how to print a rotated string with the */
    /* FreeType 2 library.                                             */
    
    
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    
    #include <ft2build.h>
    #include FT_FREETYPE_H
    
    
    #define WIDTH   80
    #define HEIGHT  80
    
    
    /* origin is the upper left corner */
    unsigned char image[HEIGHT][WIDTH];
    
    
    /* 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 >= WIDTH || j >= HEIGHT )
            continue;
    
          image[j][i] |= bitmap->buffer[q * bitmap->width + p];
        }
      }
    }
    
    
    void
    show_image( void )
    {
      int  i, j;
    
    
      for ( i = 0; i < HEIGHT; i++ )
      {
        for ( j = 0; j < WIDTH; j++ )
          putchar( image[i][j] == 0 ? ' '
                                    : image[i][j] < 128 ? '+'
                                                        : '*' );
        putchar( '
    ' );
      }
    }
    
    
    int
    main( int     argc,
          char**  argv )
    {
      FT_Library    library;
      FT_Face       face;
    
      FT_GlyphSlot  slot;
      FT_Matrix     matrix;                 /* transformation matrix */
      FT_Vector     pen;                    /* untransformed origin  */
      FT_Error      error;
    
      char*         filename;
      char*         text;
    
      double        angle;
      int           target_height;
      int           n, num_chars;
    
    
      if ( argc != 3 )
      {
        fprintf ( stderr, "usage: %s font sample-text
    ", argv[0] );
        exit( 1 );
      }
    
      filename      = argv[1];                           /* first argument     */
      text          = argv[2];                           /* second argument    */
      num_chars     = strlen( text );
      angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 0 degrees  旋转     */
      target_height = HEIGHT;
    
      error = FT_Init_FreeType( &library );              /* initialize library */
      /* error handling omitted */
    
      error = FT_New_Face( library, filename, 0, &face );/* create face object */
      /* error handling omitted */
    
      /* use 50pt at 100dpi */
      error = FT_Set_Char_Size( face, 50 * 64, 0,
                                30, 0 );                /* set character size */
      /* error handling omitted */
    
      slot = face->glyph;
    
      /* set up matrix */
      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 );
    
      /* the pen position in 26.6 cartesian space coordinates; */
      /* start at (40,0) relative to the upper left corner  */
      pen.x = 0 * 64;
      pen.y = ( target_height - 40 ) * 64;
    
      for ( n = 0; n < num_chars; n++ )
      {
        /* set transformation */
        FT_Set_Transform( face, &matrix, &pen );
    
        /* load glyph image into the slot (erase previous one) */
        error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
        if ( error )
          continue;                 /* ignore errors */
    
        /* now, draw to our target surface (convert position) */
        draw_bitmap( &slot->bitmap,
                     slot->bitmap_left,
                     target_height - slot->bitmap_top );
    
        /* increment pen position */
        pen.x += slot->advance.x;
        pen.y += slot->advance.y;
      }
    
      show_image();
    
      FT_Done_Face    ( face );
      FT_Done_FreeType( library );
    
      return 0;
    }
    
    /* EOF */

     程序中把输出的字符打印在屏幕上,分辨率是640*480,从300,200 处开始显示.这里我为了便于查看就改为了80*80.从40,0处开始显示

     编译:

    gcc -o example1 example1.c -I /usr/local/include/freetype2/ -lfreetype -lm

     运行程序即可。

    arm:

    首先配置:

    ./configure --host=arm-linux
    make
    make DESTDIR=$PWD/tmp install

    将生成的文件拷贝到交叉编译器和开发板文件系统相应的位置。

    编译文件:

    arm-linux-gcc -o test main.c  -lfreetype -lm

    将test和字体文件拷贝到开发板中即可运行程序.

    源代码:

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    #include <linux/fb.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <math.h>
    
    #include "show_font.h"
    #include <ft2build.h>
    #include FT_FREETYPE_H
    
    
    unsigned char *hzkmem;
    unsigned char *fbmem;
    unsigned int line_width;
    unsigned int pixel_width;
    
    struct fb_var_screeninfo var;
    
    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 short *pen_32;
        unsigned char red,green,blue;
    
        pen_16 = (unsigned short *)pen_8;
        pen_32 = (unsigned short *)pen_8;
    
        switch( pixel_width*8 )
        {
        case 8:
            *pen_8 = color;
            break;
    
        case 16:
            /* 565 */
            red = (color>>16) & 0xff;
            green = (color>>8) & 0xff;
            blue = (color>>0) & 0xff;
            color = ((red>>3)<<11) | ((green>>2)<<5) |((blue>>3));
            *pen_16 = color;
            break;
    
        case 32:
            *pen_32 = color;
            break;
        default:
            printf("can't support %ddpp
    ",pixel_width*8 );
            break;
        }
    }
    
    void lcd_put_ascii( int x, int y, unsigned char c )
    {
        unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
        int i,b;
        unsigned char byte;
    
        for( i=0; i< 16; i++ )
        {
            byte = dots[i];
            for( b=7;b>=0;b--)
            {
                if( byte & (1<<b))
                {
                    lcd_put_pixel(x+7-b,y+i, 0xffffff );
                }
                else
                {
                    lcd_put_pixel(x+7-b,y+i, 0x000000 );
                }
            }
        }
    
    }
    
    void lcd_put_chinese( int x, int y, unsigned char *c )
    {
        unsigned int area = c[0] - 0xa1;
        unsigned int where = c[1] - 0xa1;
        unsigned char *dots = hzkmem + (area*94+where)*32;
        unsigned char byte;
        int i,j,b;
        for( i=0; i<16; i++ )
        {
            for( j=0; j<2; j++ )
            {
                byte = dots[i*2+j];
                for( b=7; b>=0; b-- )
                {
                    if( byte & (1<<b) )
                        lcd_put_pixel(x+j*8+7-b,y+i, 0xffffff );
                    else
                        lcd_put_pixel(x+j*8+7-b,y+i, 0x000000 );
                }
            }
        }
    }
    
    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 argc, char **argv )
    {
        int hzk_fd;
        int fd_fb;
        struct fb_fix_screeninfo fix;
    
        int screen_size;
    
        FT_Library    library;
        FT_Error      error;
        FT_Face       face;
        FT_Matrix     matrix;                 /* transformation matrix */
        FT_Vector     pen;                    /* untransformed origin  */
    
        double        angle;
    
        wchar_t *chinese_char = L"周zhou";
    
    
    
    
        unsigned char str[]={0xd6,0xd0};
        struct stat hzk_stat;
    
    
        fd_fb = open("/dev/fb0",  O_RDWR );
        if( fd_fb<0 )
        {
            perror("oepn failed");
            return -1;
        }
    
        if( ioctl( fd_fb,  FBIOGET_VSCREENINFO, &var ) )
        {
            printf("can't get var
    ");
            return -1;
        }
    
        if( ioctl( fd_fb,  FBIOGET_FSCREENINFO, &fix ) )
        {
            printf("can't get fix
    ");
            return -1;
        }
        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;
        fbmem = (unsigned char *)mmap( NULL, screen_size,  PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb,0 );
        if( fbmem == (unsigned char *)-1 )
        {
            printf("mmap is failed
    ");
            return -1;
        }
    
        hzk_fd = open("HZK16",  O_RDONLY );
        if( hzk_fd<0 )
        {
            printf("can't open hzk
    ");
            return -1;
        }
    
        if( fstat(hzk_fd, &hzk_stat))
        {
            printf("can't get fstat
    ");
            return -1;
        }
    
        hzkmem = (unsigned char *)mmap( NULL, hzk_stat.st_size,  PROT_READ, MAP_SHARED,hzk_fd,0 );
        if( hzkmem == (unsigned char *)-1 )
        {
            printf("mmap hzk is failed
    ");
            return -1;
        }
    
    
        memset( fbmem, 0, screen_size );
    
        lcd_put_ascii(var.xres/2,var.yres/2,'A' );
    
        printf("chinese code : %02x  %02x
    ", str[0],str[1]);
        lcd_put_chinese( var.xres/2 +8 ,var.yres/2, str );
    
        if( argc != 2 )
        {
            printf("Usage: %s  <font_file>
    ", argv[0]);
            return -1;
        }
    
        error = FT_Init_FreeType( &library );              /* initialize library */
        /* error handling omitted */
    
    
        error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
    
        /* use 50pt at 100dpi */
        error = FT_Set_Pixel_Sizes( face, 30, 0 );                /* set character size */
    
        angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 25 degrees     */
         /* set up matrix */
        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 );
    
        /* the pen position in 26.6 cartesian space coordinates; */
        /* start at (40,0) relative to the upper left corner  */
        pen.x = (var.xres/2+8+16) * 64;
        pen.y = ( var.yres/2 - 16 ) * 64;
    
        /* set transformation */
        FT_Set_Transform( face, &matrix, &pen );
    
        /* load glyph image into the slot (erase previous one) */
        error = FT_Load_Char( face, chinese_char[0], FT_LOAD_RENDER );
        if(error)
        {
            printf("FT_load_char error
    ");
            return -1;
        }
    
        draw_bitmap( &face->glyph->bitmap,
                     face->glyph->bitmap_left,
                     var.yres - face->glyph->bitmap_top );
    
    
        return 0;
    
    
    }

    sds

  • 相关阅读:
    Visual Studio 2010使用Visual Assist X的方法
    SQL Server 2000 评估版 升级到 SQL Server 2000 零售版
    双网卡多网络单主机同时访问
    开发即过程!立此纪念一个IT新名词的诞生
    delphi dxBarManager1 目录遍历 转为RzCheckTree2树
    5320 软件集合
    delphi tree 从一个表复制到另一个表
    DELPHI 排课系统课表
    长沙金思维 出现在GOOGLE的 金思维 相关搜索里啦!!
    如何在DBGrid的每一行前加一个单选框?
  • 原文地址:https://www.cnblogs.com/ynxf/p/6274067.html
Copyright © 2011-2022 走看看