图文使用freetype渲染字体+字体颜色+字体大小

freetype的介绍各种博客都有,可以搜索看看。

freetype2.8的源码及编译出的库及头文件链接:https://download.csdn.net/download/weixin_40550094/12117925

我这边就直接写demo,本demo可以生成带颜色的bitmap;

使用freetype显示一个字符简单,网上示例也很多,但是将整屏的数据都一起传递给freetype,让其生成整屏完整的bitmap,网上几乎没有找到,再加上字体的渲染,就更少之有少,本问应用是24行40列的电视图文显示使用,也会提供本范例编译出来的freetype库文件及头文件的连接。

本范例实现整屏数据整体转换,整体渲染字色,大小和间距需要按需调整,可以NewFTString中调整;

FT_Set_Char_Size设置大小及分辨率;

#include "ftglyph.h"
#include "freetype.h"
#include <sys/stat.h>


static S32 indexLength = 0;
#define WIDTH_TTX   1280
#define HEIGHT_TTX  720
#define MAX_GLYPHS      1024

/* origin is the upper left corner */
#define dataLength (24 * 40)
static U32 dataIndexBuf[dataLength];

unsigned char* imageBuffer;

static FT_Face pFTFace;
static FT_Library library;

typedef struct FTCode_ {
    FT_ULong code;
    char utf8str[8];
}FTCode;

typedef struct FTStrImage {
    unsigned int width;
    unsigned int height;
    unsigned char* imageBuffer;
}FTStrImage;


typedef struct TGlyph_
{
    FT_UInt index;
    FT_Vector pos;
    FT_BBox drawBox;
    FT_Glyph glyph;
} TGlyph, *PGlyph;

typedef struct {
    unsigned char* image;
    unsigned int width;
    unsigned int height;
    unsigned int strLen;
}FTString;


struct color_ttx
{
    U8 blue;
    U8 green;
    U8 red;
};
color_ttx color_BITMAP[6]
{
    {0x00,0x00,0xff},/**red*/
    {0x00,0xFF,0x00},/**green**/
    {0xFF,0x00,0x00},/**blue**/
    {0x00,0x00,0x00},/**black**/
    {0xFF,0xFF,0xFF},/**white**/
    {0x00,0xFF,0xFF}/**yellow**/
};

static FTStrImage strim;

S32 initFontLib()
{
    FT_Error error = FT_Init_FreeType(&library);
    if (error)
    {
        LOGE("error = %d\n", error);
        return 0;
    }
    error = FT_New_Face(library, "/factory/atv/font/文件名.ttf", 0, &pFTFace);
    if (error == FT_Err_Unknown_File_Format )
    {
        LOGE(" ERROR: fonts not support format!\n");
        return 0;
    }
    else if (error)
    {
        LOGE("ERROR: fonts file cannot open!\n");
        return 0;
    }
    return 0;
}

 

S32 deInitFontLib()
{
    //free face?
    FT_Done_Face(pFTFace);
    pFTFace = NULL;
    free(pFTFace);

    //free FreeType Lib
    FT_Done_FreeType(library);
    library = NULL;

    return 0;
}

FTStrImage NewFTString()

{
    FT_Error error;
    FT_Set_Char_Size(pFTFace,16 << 6,16 << 6 ,120,120);
    FT_GlyphSlot slot = pFTFace->glyph;
    FT_UInt glyph_index = 0;
    FT_Bool use_kerning = FT_HAS_KERNING(pFTFace);
    FT_UInt previous = 0;
    FTCode* codes = 0;
    U32 spacing = 10;
    int pen_x = 0;
    int pen_y = 0;
    TGlyph glyphs[MAX_GLYPHS];
    FT_UInt num_glyphs = 0;
    FT_BBox bbox;
    U32 charSpace = 20;
    bbox.xMin = bbox.yMin = 100000;
    bbox.xMax = bbox.yMax = -100000;
    PGlyph glyph = glyphs;

    U32 line = 23;
    LOGE("use_kerning = %d",use_kerning);
    for( unsigned int n = 0; n < indexLength; n++)
    {
        FT_BBox glyph_bbox;
        memset(&glyph_bbox,0x00,sizeof(glyph_bbox));
        if((n%40 == 0) && (n != 0))
        {
            pen_y = spacing + pen_y + 10;
            pen_x = 0;
            line--;
        }

        glyph->index = FT_Get_Char_Index(pFTFace, dataIndexBuf[dataLength    - (24 - line)*40 + n %40]);
        if ( use_kerning && previous && glyph->index)
        {
            FT_Vector delta;
            FT_Get_Kerning(pFTFace, previous, glyph->index,
            FT_KERNING_DEFAULT, &delta );
            pen_x += delta.x >> 6;
            LOGE("pen_x = %d delta.x = %d\n",pen_x,delta.x);
        }
        glyph->pos.x = pen_x;
        glyph->pos.y = pen_y;
        error = FT_Load_Glyph(pFTFace, glyph->index, FT_LOAD_DEFAULT);
        if ( error )
        {
            LOGE("ERROR: FT_Load_Glyph\n");
        }

        error = FT_Get_Glyph(pFTFace->glyph, &glyph->glyph);//装载一个新的字形图像到字形槽,前面装载的将会从字形槽中抹去
        if ( error )
        {
            LOGE("ERROR: FT_Get_Glyph!\n");
        }


        pen_x += slot->advance.x >> 6;
        previous = glyph->index;

        FT_Glyph_Get_CBox(glyph->glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
        //LOGE("pos.x = %d,pos.y = %d,,previous = %d",glyph->pos.x,glyph->pos.y,previous);
        glyph_bbox.xMin += glyph->pos.x;
        glyph_bbox.xMax += glyph->pos.x;
        glyph_bbox.yMin += glyph->pos.y;
        glyph_bbox.yMax += glyph->pos.y;
        if(n == 0)
        {
            spacing = glyph_bbox.yMax;//用于保存字符的行高
        }
        if (glyph_bbox.xMin < bbox.xMin)
        {
            bbox.xMin = glyph_bbox.xMin;
        }
        if (glyph_bbox.yMin < bbox.yMin)
        {
            bbox.yMin = glyph_bbox.yMin;
        }
        if (glyph_bbox.xMax > bbox.xMax)
        {
            bbox.xMax = glyph_bbox.xMax;
        }
        if (glyph_bbox.yMax > bbox.yMax)
        {
            bbox.yMax = glyph_bbox.yMax;
        }

        //LOGE("[%d %d %d %d]\n", glyph_bbox.xMin, glyph_bbox.yMin, glyph_bbox.xMax, glyph_bbox.yMax);
        glyph->drawBox = glyph_bbox;
        glyph++;
    }

    num_glyphs = glyph - glyphs;
    if ( bbox.xMin > bbox.xMax )
    {
        bbox.xMin = 0;
        bbox.yMin = 0;
        bbox.xMax = 0;
        bbox.yMax = 0;
    }
    unsigned int width = bbox.xMax+1;
    unsigned int height = bbox.yMax-bbox.yMin+1;
    unsigned int start_x = 0;
    unsigned int start_y = 0;
    LOGE("width = %d height = %d \n", width, height);
    for ( unsigned int n = 0; n < indexLength; n++)
    {
        PGlyph pplyph = glyphs+n;
        FT_Vector pen = glyph->pos;
        error = FT_Glyph_To_Bitmap(&pplyph->glyph, FT_RENDER_MODE_NORMAL, &pen, 0);
        if ( !error )
        {
            FT_BitmapGlyph bit = (FT_BitmapGlyph)pplyph->glyph;
            start_x = pplyph->drawBox.xMin;
            start_y = height - (pplyph->drawBox.yMin-bbox.yMin+bit->bitmap.rows);
            for (unsigned int y = 0; y < bit->bitmap.rows; y++)
            {
                for (unsigned int x = 0; x < bit->bitmap.width; x++)
                {
                    unsigned int iy = start_y + y;
                    unsigned int ix = start_x + x;
                    unsigned int index = (iy*width + ix)*4;
                    imageBuffer[index] = color_BITMAP[4].blue;
                    imageBuffer[index+1] = color_BITMAP[4].green;
                    imageBuffer[index+2] = color_BITMAP[4].red;
                    imageBuffer[index+3] = bit->bitmap.buffer[y * bit->bitmap.width + x];
                }
            }
            FT_Done_Glyph(pplyph->glyph);
        }
    }
    //free codes
    free(codes);
    strim.width = width;
    strim.height = height;
    strim.imageBuffer = imageBuffer;//release after
    return strim;
}

 

void test()

{

        initFontLib();
        memset(&strim,0x00,sizeof(strim));
        imageBuffer = (unsigned char*)malloc(WIDTH_TTX*HEIGHT_TTX*4);
        memset(imageBuffer,0x00,WIDTH_TTX*HEIGHT_TTX*4);

        for(U32 loop = 0,value = 0;loop < dataLength;loop ++)
        {
              dataIndexBuf[indexLength] = value + 57360;
              indexLength++;
              if(loop%9 == 0 && loop != 0)
              {
                  value = 0;
              }
              else
              {
                  value++;
              }
        }

       memset(imageBuffer,0x00,WIDTH_TTX*HEIGHT_TTX*4);

       strim = NewFTString();

        Draw_Bitmap_Argb8888(0, 0, strim.width, strim.height, strim.imageBuffer);
        GFX_Flip_Window();

        deInitFontLib();
        free(strim.imageBuffer);
        free(imageBuffer);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值