linux图像显示(五)使用freetype处理矢量字体

linux图像显示

linux图像显示(一)framebuffer操作

linux图像显示(二)bmp图片

linux图像显示(三)使用libjpg处理jpg图片

linux图像显示(四)使用libpng处理png图片

linux图像显示(五)使用freetype处理矢量字体

 

FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。

下面讲解怎么使用freetype,包括freetype的移植,freetype的使用实例

库和示例代码:https://download.csdn.net/download/weixin_42462202/10855217

1、移植库

(1)在ubuntu下解压,进入源码目录

(2)配置

①先指定编译工具链

env CC=arm-linux-gcc

②指定运行平台和库安装目录,这里我的安装目录是/opt/mlib

./configure --host=arm-linux --prefix=/opt/mlib

③编译安装

make
make install

现在在/opt/mlib目录下就生成了头文件和库

2、freetype的使用

(1)在项目中使用库

库现在已经在/opt/lib目录下,怎么使用呢?

答:通过-I -L -l 给编译器 指定头文件路径和库

-I :指定头文件路径

-L :指定库路径

-l :指定库

为了方便,写一个简单的Makefile

CFLAGS += -I/opt/mlib/include/ -I/opt/mlib/include/freetype2/ -I/opt/mlib/include/freetype2/freetype/ -I/opt/mlib/include/freetype2/freetype/config/

LDFLAGS += -L/opt/mlib/lib/
LDFLAGS += -lfreetype -lm

all:
        arm-linux-gcc examplet.c -o example $(LDFLAGS) $(CFLAGS)

(2)freetype使用步骤说明

①初始化库

 FT_EXPORT( FT_Error )
 FT_Init_FreeType( FT_Library  *alibrary );

②创建face 对象来打开字体文件

 FT_EXPORT( FT_Error ) 
 FT_New_Face( FT_Library   library,
               const char*  filepathname,
               FT_Long      face_index,
               FT_Face     *aface );

③选择字符的大小

 pixel_width:字体的像素宽度
 pixel_height:字体的像素高度

 FT_EXPORT( FT_Error )
 FT_Set_Pixel_Sizes( FT_Face  face,
                      FT_UInt  pixel_width,
                      FT_UInt  pixel_height );

④添加渲染(可选,斜体、加粗、下划线等)

  FT_EXPORT( void )
  FT_Set_Transform( FT_Face     face,
                    FT_Matrix*  matrix,
                    FT_Vector*  delta );

⑤转化bitmap位图

  FT_EXPORT( FT_Error )
  FT_Load_Char( FT_Face   face,
                FT_ULong  char_code,
                FT_Int32  load_flags );

⑥开始绘制

void
draw_bitmap( FT_Bitmap*  bitmap,
             FT_Int      x,
             FT_Int      y)

(3)freetype使用示例

①在控制台显示

#define WIDTH   640
#define HEIGHT  480

unsigned char image[HEIGHT][WIDTH];

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\n", argv[0] );
        exit( 1 );
    }        

    filename      = argv[1]; /* 获取字体格式文件 */
    text          = argv[2]; /* 获取显示内容 */
    angle         = ( 25.0 / 360 ) * 3.14159 * 2; /* 字体旋转角度 */
    
    target_height = HEIGHT; /* 得到屏幕的高度 */

    /* 1.初始化库 */
    error = FT_Init_FreeType( &library );

    /* 2.创建一个新的 face 对象来打开一个字体文件 */
    error = FT_New_Face( library, argv[1], 0, &face );

    /* 3.选择一个字符大小 */
    error = FT_Set_Pixel_Sizes(face, 24, 0);

    /* 字体旋转 */
    angle         = (25 / 360 ) * 3.14159 * 2; /* 旋转25度 */
    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 );

    /* 图像绘制起点 */
    pen.x = (g_var.xres / 2 + 8 + 16) * 64;
    pen.y = (g_var.yres / 2 +8 + 16 - 35) * 64;

    for ( n = 0; n < num_chars; n++ )
    {
        /* 4.渲染字体 */
        FT_Set_Transform( face, &matrix, &pen );

        /* 5.转化bitmap位图 */
        error = FT_Load_Char(face, text[n], FT_LOAD_RENDER); 
    
        /* 6.开始绘制 */
        draw_bitmap( &slot->bitmap,
                     slot->bitmap_left,
                     target_height - slot->bitmap_top );

        pen.x += slot->advance.x;
        pen.y += slot->advance.y;

        show_image(); 
    }
    
    FT_Done_Face    ( face );
    FT_Done_FreeType( library );
}

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( '\n' );
    }
}






    

测试方法:

第一个参数是字体格式文件
第二参数是你要显示的文字

./example simsun.ttc abc

②在lcd上显示

在lcd上显示只需要修改这个函数

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 >= g_var.xres || j >= g_var.xres )
            continue;

            /* 将这句话改为在lcd的指定位置打点 */
            //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
            lcd_put_pixel(i, j, bitmap->buffer[q * bitmap->width + p]);
        }
    }
}

③显示中文

可以通过改变FT_Load_Char( face, text[n], FT_LOAD_RENDER );的传参来显示中文

wchar_t *chinese_str = L哈哈哈g";

error = FT_Load_Char(face, chinese_str[n], FT_LOAD_RENDER);

在linux环境下wchar_t表示一个字符4个字节

可以使用wcslen(chinese_str);获取wchar_t类型字符串的字符个数

 

 

 

你可能感兴趣的:(linux图像显示(五)使用freetype处理矢量字体)