freetype 输出一个一个字符

这篇博客介绍了如何利用Freetype库在控制台上输出一个旋转的字符串。首先,文章提到了在mac上安装Freetype库的方法,然后通过示例代码展示了配置头文件和库的过程。在遇到face正常但无法输出字体的问题时,建议使用特定的ttf字体文件如keyboard.ttf或serial.ttf来解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Freetype : 基本知识

配置:添加头文件

#include <ft2build.h>

#include FT_FREETYPE_H

以及配置库: 这里我用mac 版的,直接用 brew install  freetype, 然后将库添加到工程上去

以下在控制台上输出一个字符为例子: 

问题: 

1.face是正常的,但是无法输出字体: 原因ttf 可能不一样,可以用keyboard.ttf 或者serial.ttf

版本一的过程:比较直观,直接看代码


```

#include <iostream>

#include <string>

#include <ft2build.h>

#include FT_FREETYPE_H

#include FT_ERRORS_H



#pragma comment(lib, "freetype.lib")

using namespace std;



void Draw_Bitmap(unsigned char* bitmap, int width, int height);



int main(int argc, char** argv)

{

    

    string font("/System/Library/Fonts/keyboard.ttf");

    char charcter = 'a';

    

    cout << "font: " << font << "\tcharcter: " << charcter<<endl;

    

    // 初始化Freetype库

    FT_Library library;

    FT_Error error = FT_Init_FreeType(&library);

    if (error)

    {

        cout << "error in init freetype" << endl;

    }

    

    // 创建字体外观

    FT_Face face;

    error = FT_New_Face(library, font.c_str(), 0, &face);

    if (error == FT_Err_Unknown_File_Format)

    {

        cout << "error in file format" << endl;

    }

    else if (error)

    {

        cout << "error in create face" << endl;

    }

    

    // 设置字体大小

    error = FT_Set_Pixel_Sizes(face, 30, 0);

    if (error)

    {

        cout << "error in set pixel size" << endl;

    }

    

    // 获取字符索引

    unsigned int index = FT_Get_Char_Index(face, charcter);

    

    // 载入字形

    error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT);

    if (error)

    {

        cout << "error in load glyph" << endl;

    }

    

    // 渲染轮廓

    error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);

    if (error)

    {

        cout << "error in render glyph" << endl;

    }

    

    // bitmap.width 字形图象一行有多少个像素

    // bitmap.pitch 表示字形图象一行有多少个字节

    Draw_Bitmap(face->glyph->bitmap.buffer, face->glyph->bitmap.pitch,

                face->glyph->bitmap.rows);

    

    FT_Done_Face(face);

    FT_Done_FreeType(library);

    

    return 0;

}



void Draw_Bitmap(unsigned char* bitmap, int width, int height)

{

    cout << endl;

    if (bitmap == NULL)

        return;

    for (int i = 0; i < height; i++)

    {

        for (int j = 0; j < width; j++)

        {

            int color = bitmap[i * width + j];

            if (color == 0)

            {

                cout << " ";

            }

            else

            {

                cout << "*";

            }

        }

        cout << endl;

    }

}

```


 版本二:添加了变换矩阵,这里不注释掉没有用

/* 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 <iostream>



#include <ft2build.h>

#include FT_FREETYPE_H



using namespace std;



#define WIDTH   64

#define HEIGHT  48





/* 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 simplicity, we assume that `bitmap->pixel_mode' */

    /* is `FT_PIXEL_MODE_GRAY' (i.e., not a bitmap font)   */

    

    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' );

    }

}





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      = "/System/Library/Fonts/keyboard.ttf";                           /* first argument     */

    text          = "a";                           /* second argument    */

    num_chars     = strlen( text );

    angle         = ( -30.0 / 360 ) * 3.14159 * 2;      /* use 25 degrees     */

    target_height = HEIGHT;

    

    error = FT_Init_FreeType( &library );              /* initialize library */

    /* error handling omitted */

    if(error)

    {

        cout << "error init freetype" << endl;

    }

    

    error = FT_New_Face( library, filename, 0, &face );/* create face object  index为0总是成功的  face->num_faces可以表明有多少faces*/

    /* error handling omitted */

    if(error == FT_Err_Unknown_File_Format) //字体格式不对

    {

        cout << "error in file format" << endl;

    }

    else if(error)

    {

        cout << "error in create face" << endl;

    }

    

    /* use 50pt at 100dpi */

    //通过设置长宽范围设置,后面两个是分辨率

    error = FT_Set_Char_Size( face, 10*54, 0,

                             100, 0);                /* set character size */

    /* error handling omitted */

    

    /* cmap selection omitted;                                        */

    /* for simplicity we assume that the font contains a Unicode cmap */

    

    slot = face->glyph; //slot 对象

    

    /* set up matrix */

    //不知道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 (300,200) relative to the upper left corner  */

    //不知道pen的作用是什么

    pen.x =  18 * 64;//300 * 64;

    pen.y = ( target_height - 55 ) * 64;

    

    for ( n = 0; n < num_chars; n++ )

    {

        /* set transformation */

        //set_Transform 是做什么的, 设置转换矩阵

       // FT_Set_Transform( face, &matrix, &pen );

        

        /* load glyph image into the slot (erase previous one) */

        //加载每一个字,加载出来后会有一个bitmap结构体,里面的buffer存储八位像素点数据,按照字宽以行进行排列,要求转化为位图,这里是一个字节表示一个像素

        //FT_LOAD_MONOCHROME 1位表示一个像素

        //freetype是按照Unicode码来索引,utf8是Unicode辩题,可以经过变换得到Unicode码

        //单色位图可以节省空间,生成的单色位图是整个字框,描绘时,将包含字的最小字框给描画出来,以节省空间

        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 */

```






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值