FreeType使用实例细节分析

简介: FreeType使用实例细节分析

结构体&链表操作(尾插)

结构体

typedef struct FontBitMap {
    int iXLeft;  /* 位图左上角X座标 */
    int iYTop;   /* 位图左上角Y座标 */
    int iXMax;   /* 位图的最大X座标值 */
    int iYMax;   /* 位图的最大Y座标值 */
    int iBpp;    /* 位图中一个象素用多少位来表示 */
    int iPitch;  /* 对于单色位图, 两行象素之间的跨度, 即第N行、第N+1行象素数据之间的偏移值 */
    int iCurOriginX;  /* 位图的原点X座标(一般是左下角), 使用原点来确定相邻字符的位置 */
    int iCurOriginY;  /* 位图的原点Y座标 */
    int iNextOriginX; /* 下一个字符即右边字符的原点X座标 */
    int iNextOriginY; /* 下一个字符即右边字符的原点Y座标 */
    unsigned char *pucBuffer;  /* 存有字符的位图数据 */
}T_FontBitMap, *PT_FontBitMap;
typedef struct FontOpr {
    char *name;             /* 字体模块的名字 */
    int (*FontInit)(char *pcFontFile, unsigned int dwFontSize);  /* 字体模块的初始化函数 */
    int (*GetFontBitmap)(unsigned int dwCode, PT_FontBitMap ptFontBitMap);  /* 根据编码值获得字符的位图 */
    void (*SetFontSize)(unsigned int dwFontSize);   /* 设置字体尺寸(单位:象素) */
    struct FontOpr *ptNext;  /* 链表 */
}T_FontOpr, *PT_FontOpr;

结构体定义了字体位图和字体模块的相关信息,可以用于存储和操作字体相关的数据和函数。

链表操作

#include <config.h>
#include <fonts_manager.h>
#include <string.h>
static PT_FontOpr g_ptFontOprHead = NULL;
static int g_dwFontSize;
/**********************************************************************
 * 函数名称: RegisterFontOpr
 * 功能描述: 注册"字体模块", 所谓字体模块就是取出字符位图的方法
 * 输入参数: ptFontOpr - 一个结构体,内含"取出字符位图"的操作函数
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int RegisterFontOpr(PT_FontOpr ptFontOpr)
{
    PT_FontOpr ptTmp;
    if (!g_ptFontOprHead)
    {
        g_ptFontOprHead   = ptFontOpr;
        ptFontOpr->ptNext = NULL;
    }
    else
    {
        ptTmp = g_ptFontOprHead;
        while (ptTmp->ptNext)
        {
            ptTmp = ptTmp->ptNext;
        }
        ptTmp->ptNext     = ptFontOpr;
        ptFontOpr->ptNext = NULL;
    }
    return 0;
}
/**********************************************************************
 * 函数名称: ShowFontOpr
 * 功能描述: 显示本程序能支持的"字体模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/
void ShowFontOpr(void)
{
    int i = 0;
    PT_FontOpr ptTmp = g_ptFontOprHead;
    while (ptTmp)
    {
        printf("%02d %s\n", i++, ptTmp->name);
        ptTmp = ptTmp->ptNext;
    }
}
/**********************************************************************
 * 函数名称: GetFontOpr
 * 功能描述: 根据名字取出指定的"字体模块"
 * 输入参数: pcName - 名字
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - 字体模块的PT_FontOpr结构体指针
 ***********************************************************************/
PT_FontOpr GetFontOpr(char *pcName)
{
    PT_FontOpr ptTmp = g_ptFontOprHead;
    while (ptTmp)
    {
        if (strcmp(ptTmp->name, pcName) == 0)
        {
            return ptTmp;
        }
        ptTmp = ptTmp->ptNext;
    }
    return NULL;
}
/**********************************************************************
 * 函数名称: SetFontSize
 * 功能描述: 设置字符的尺寸(单位:色素)
 * 输入参数: dwFontSize - 字符的尺寸(单位:色素)
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/
void SetFontSize(unsigned int dwFontSize)
{
    PT_FontOpr ptTmp = g_ptFontOprHead;
    g_dwFontSize = dwFontSize;
    while (ptTmp)
    {
        if (ptTmp->SetFontSize)
        {
            ptTmp->SetFontSize(dwFontSize);
        }
        ptTmp = ptTmp->ptNext;
    }
}
/**********************************************************************
 * 函数名称: GetFontSize
 * 功能描述: 获得字符的尺寸(单位:色素)
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 字符的尺寸(单位:色素)
 ***********************************************************************/
unsigned int GetFontSize(void)
{
    return g_dwFontSize;
}
/**********************************************************************
 * 函数名称: GetFontBitmap
 * 功能描述: 获得字符的位图
 * 输入参数: dwCode       - 字符的编码值(可能是ASCII/GBK/UNICODE)
 * 输出参数: ptFontBitMap - 内含位图信息
 * 返 回 值: 0  - 成功
 *            -1 - 失败 
 ***********************************************************************/
int GetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iError = 0;
    PT_FontOpr ptTmp = g_ptFontOprHead;
    while (ptTmp)
    {
        iError = ptTmp->GetFontBitmap(dwCode, ptFontBitMap);
        if (0 == iError)
        {
            return 0;
        }
        ptTmp = ptTmp->ptNext;
    }
    return -1;
}
/**********************************************************************
 * 函数名称: SetFontsDetail
 * 功能描述: 设置字体模块的信息,比如指定字库文件,指定字符尺寸
 * 输入参数: pcFontsName - 要设置的字体模块的名字
 *            pcFontsFile - 字库文件
 *            dwFontSize  - 字符的尺寸(单位:色素), 程序运行时可用SetFontSize修改
 * 输出参数: 无
 * 返 回 值: 0      - 成功
 *            其他值 - 失败 
 ***********************************************************************/
int SetFontsDetail(char *pcFontsName, char *pcFontsFile, unsigned int dwFontSize)
{
    int iError = 0;
    PT_FontOpr ptFontOpr;
    ptFontOpr = GetFontOpr(pcFontsName);
    if (NULL == ptFontOpr)
    {
        return -1;
    }
    g_dwFontSize = dwFontSize;
    iError = ptFontOpr->FontInit(pcFontsFile, dwFontSize);
    return iError;
}
/**********************************************************************
 * 函数名称: FontsInit
 * 功能描述: 调用各个字体模块的初始化函数
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int FontsInit(void)
{
    int iError;
#if 0    
    iError = ASCIIInit();
    if (iError)
    {
        DBG_PRINTF("ASCIIInit error!\n");
        return -1;
    }
    iError = GBKInit();
    if (iError)
    {
        DBG_PRINTF("GBKInit error!\n");
        return -1;
    }
#endif    
    iError = FreeTypeInit();
    if (iError)
    {
        DBG_PRINTF("FreeTypeInit error!\n");
        return -1;
    }
    return 0;
}

这段代码实现了字体管理器的功能,包括注册字体模块、显示支持的字体模块、获取指定字体模块、设置字符尺寸、获取字符尺寸、获取字符位图、设置字体模块信息和初始化字体模块等操作。

主要函数和数据结构说明如下:

数据结构:

PT_FontOpr:指向FontOpr结构体的指针,用于表示字体模块。

g_ptFontOprHead:指向字体模块链表头部的指针,用于存储注册的字体模块。

g_dwFontSize:字符的尺寸(单位:像素)。

函数:

RegisterFontOpr:注册字体模块的函数,将字体模块添加到链表中。

ShowFontOpr:显示支持的字体模块的函数,遍历链表打印字体模块的名称。

GetFontOpr:根据名称获取指定的字体模块的函数,遍历链表查找匹配的字体模块并返回其指针。

SetFontSize:设置字符尺寸的函数,遍历链表调用字体模块的设置字符尺寸函数。

GetFontSize:获取字符尺寸的函数,返回全局变量g_dwFontSize的值。

GetFontBitmap:获取字符位图的函数,遍历链表调用字体模块的获取字符位图函数。

SetFontsDetail:设置字体模块信息的函数,根据名称获取指定字体模块,并调用其初始化函数进行字体模块的设置。

FontsInit:字体模块的初始化函数,调用各个字体模块的初始化函数进行初始化。

这些函数共同实现了字体模块的注册、管理和操作,通过链表结构和函数指针的方式实现了对不同字体模块的扩展和灵活切换。

freetype

#include <config.h>
#include <fonts_manager.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize);
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static void FreeTypeSetFontSize(unsigned int dwFontSize);
static T_FontOpr g_tFreeTypeFontOpr = {
    .name          = "freetype",
    .FontInit      = FreeTypeFontInit,
    .GetFontBitmap = FreeTypeGetFontBitmap,
    .SetFontSize   = FreeTypeSetFontSize,
};
static FT_Library g_tLibrary;
static FT_Face g_tFace;
static FT_GlyphSlot g_tSlot;
/**********************************************************************
 * 函数名称: FreeTypeFontInit
 * 功能描述: FreeType字体模块的初始化函数
 * 输入参数: pcFontFile - FreeType字库文件
 *            dwFontSize - 字符尺寸(单位:象素)
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize)
{
    int iError;
    /* 显示矢量字体 */
    iError = FT_Init_FreeType(&g_tLibrary );               /* initialize library */
    /* error handling omitted */
    if (iError)
    {
        DBG_PRINTF("FT_Init_FreeType failed\n");
        return -1;
    }
    iError = FT_New_Face(g_tLibrary, pcFontFile, 0, &g_tFace); /* create face object */
    /* error handling omitted */
    if (iError)
    {
        DBG_PRINTF("FT_Init_FreeType failed\n");        
        return -1;
    }
    g_tSlot = g_tFace->glyph;
    iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
    if (iError)
    {
        DBG_PRINTF("FT_Set_Pixel_Sizes failed : %d\n", dwFontSize);
        return -1;
    }
    return 0;
}
/**********************************************************************
 * 函数名称: ASCIIGetFontBitmap
 * 功能描述: 获得UNICODE字符的FreeType位图
 * 输入参数: dwCode       - 字符的UNICODE编码值
 * 输出参数: ptFontBitMap - 内含位图信息
 * 返 回 值: 0  - 成功
 *            -1 - 失败 
 ***********************************************************************/
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iError;
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;
#if 0
    FT_Vector tPen;
    tPen.x = 0;
    tPen.y = 0;
    /* set transformation */
    FT_Set_Transform(g_tFace, 0, &tPen);
#endif
    /* load glyph image into the slot (erase previous one) */
    //iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER );
    iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
    if (iError)
    {
        DBG_PRINTF("FT_Load_Char error for code : 0x%x\n", dwCode);
        return -1;
    }
    //DBG_PRINTF("iPenX = %d, iPenY = %d, bitmap_left = %d, bitmap_top = %d, width = %d, rows = %d\n", iPenX, iPenY, g_tSlot->bitmap_left, g_tSlot->bitmap_top, g_tSlot->bitmap.width, g_tSlot->bitmap.rows);
    ptFontBitMap->iXLeft    = iPenX + g_tSlot->bitmap_left;
    ptFontBitMap->iYTop     = iPenY - g_tSlot->bitmap_top;
    ptFontBitMap->iXMax     = ptFontBitMap->iXLeft + g_tSlot->bitmap.width;
    ptFontBitMap->iYMax     = ptFontBitMap->iYTop  + g_tSlot->bitmap.rows;
    ptFontBitMap->iBpp      = 1;
    ptFontBitMap->iPitch    = g_tSlot->bitmap.pitch;
    ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer;
    ptFontBitMap->iNextOriginX = iPenX + g_tSlot->advance.x / 64;
    ptFontBitMap->iNextOriginY = iPenY;
    //DBG_PRINTF("iXLeft = %d, iYTop = %d, iXMax = %d, iYMax = %d, iNextOriginX = %d, iNextOriginY = %d\n", ptFontBitMap->iXLeft, ptFontBitMap->iYTop, ptFontBitMap->iXMax, ptFontBitMap->iYMax, ptFontBitMap->iNextOriginX, ptFontBitMap->iNextOriginY);
    return 0;
}
/**********************************************************************
 * 函数名称: FreeTypeSetFontSize
 * 功能描述: 设置字符的尺寸(单位:色素)
 * 输入参数: dwFontSize - 字符的尺寸(单位:色素)
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/
static void FreeTypeSetFontSize(unsigned int dwFontSize)
{
    FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
}
/**********************************************************************
 * 函数名称: FreeTypeInit
 * 功能描述: 注册"FreeType字体模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int FreeTypeInit(void)
{
    return RegisterFontOpr(&g_tFreeTypeFontOpr);
}

这段代码是一个字体管理器的实现,主要用于注册和管理字体模块,并提供获取字体位图的功能。

以下是主要函数和数据结构的说明:

结构体 T_FontOpr:

name:字体模块的名称。

FontInit:字体模块的初始化函数。

GetFontBitmap:获取字体位图的函数。

SetFontSize:设置字符尺寸的函数。

函数 RegisterFontOpr:

功能:注册字体模块。

输入参数:ptFontOpr,指向一个结构体,包含获取字符位图的操作函数。

返回值:0 表示成功,其他值表示失败。

函数 ShowFontOpr:

功能:显示支持的字体模块。

输出:打印支持的字体模块的名称。

函数 GetFontOpr:

功能:根据模块名获取字体模块的结构体指针。

输入参数:pcName,字体模块的名称。

返回值:若找到对应的模块,则返回模块的指针;否则返回 NULL。

函数 SetFontSize:

功能:设置字符的尺寸。

输入参数:dwFontSize,字符的尺寸(单位:像素)。

函数 GetFontSize:

功能:获取字符的尺寸。

返回值:字符的尺寸(单位:像素)。

函数 GetFontBitmap:

功能:获取字符的位图。

输入参数:dwCode,字符的编码值;ptFontBitMap,指向存储位图信息的结构体指针。

返回值:0 表示成功,-1 表示失败。

函数 SetFontsDetail:

功能:设置字体模块的信息,如指定字库文件和字符尺寸。

输入参数:pcFontsName,要设置的字体模块的名称;pcFontsFile,字库文件;dwFontSize,字符的尺寸(单位:像素)。

返回值:0 表示成功,其他值表示失败。

函数 FontsInit:

功能:调用各个字体模块的初始化函数。

返回值:0 表示成功,其他值表示失败。

字体模块 “FreeType” 的实现:

函数 FreeTypeFontInit:FreeType 字体模块的初始化函数。

函数 FreeTypeGetFontBitmap:获取字符的 FreeType 位图。

函数 FreeTypeSetFontSize:设置字符的尺寸。

函数 FreeTypeInit:注册 FreeType 字体模块。

该代码实现了一个简单的字体管理器,并注册了一个名为 “freetype” 的字体模块,使用 FreeType 库来获取字符位图。

FreeType 相关结构体

static FT_Library g_tLibrary;
static FT_Face g_tFace;
static FT_GlyphSlot g_tSlot;

这段代码声明了三个静态变量 g_tLibrary、g_tFace 和 g_tSlot,它们的类型都是 FreeType 库中定义的结构体类型。

FT_Library 是 FreeType 库中的核心库对象,表示一个 FreeType 库的实例。它是一个包含 FreeType 库内部数据和函数指针的结构体,用于管理字体的加载、渲染和操作等操作。

FT_Face 表示一个字体对象,用于表示一个字体文件。它包含了字体文件的各种属性和数据,如字体的轮廓、字形、字体名称等。通过 FT_New_Face 函数可以创建一个 FT_Face 对象。

FT_GlyphSlot是一个结构体,用于存储字体的字形轮廓和相关信息。它包含了字形的位图数据、轮廓数据以及字形的位置和尺寸等信息。

这些静态变量用于在字体管理器的代码中存储 FreeType 相关的对象和数据,并在初始化字体模块时进行初始化和设置。在其他函数中,可以使用这些静态变量来进行字体的加载、渲染和位图获取等操作。

FreeType字体模块的初始化函数

/**********************************************************************
 * 函数名称: FreeTypeFontInit
 * 功能描述: FreeType字体模块的初始化函数
 * 输入参数: pcFontFile - FreeType字库文件
 *            dwFontSize - 字符尺寸(单位:象素)
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize)
{
    int iError;
    /* 显示矢量字体 */
    iError = FT_Init_FreeType(&g_tLibrary );               /* initialize library */
    /* error handling omitted */
    if (iError)
    {
        DBG_PRINTF("FT_Init_FreeType failed\n");
        return -1;
    }
    iError = FT_New_Face(g_tLibrary, pcFontFile, 0, &g_tFace); /* create face object */
    /* error handling omitted */
    if (iError)
    {
        DBG_PRINTF("FT_Init_FreeType failed\n");        
        return -1;
    }
    g_tSlot = g_tFace->glyph;
    iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
    if (iError)
    {
        DBG_PRINTF("FT_Set_Pixel_Sizes failed : %d\n", dwFontSize);
        return -1;
    }
    return 0;
}

这段代码是 FreeTypeFontInit 函数的实现。该函数用于初始化 FreeType 字体模块,并设置字体文件和字体大小。

函数参数说明:

char *pcFontFile:指向字体文件路径的字符串指针。

unsigned int dwFontSize:字体大小,单位为像素。

函数内部逻辑:

调用 FT_Init_FreeType 函数初始化 FreeType 库,该函数会创建一个 FreeType 库实例并将其存储在 g_tLibrary 变量中。

如果初始化失败(返回值非零),则打印调试信息并返回 -1 表示失败。

调用 FT_New_Face 函数创建一个字体对象,并将其存储在 g_tFace 变量中。这个函数会读取指定路径的字体文件,并加载其字体数据。

如果创建字体对象失败(返回值非零),则打印调试信息并返回 -1 表示失败。

将 g_tFace 中的字形对象(glyph)赋值给 g_tSlot 变量,以便后续使用。

调用 FT_Set_Pixel_Sizes 函数设置字体的像素大小。这会调整字体对象的尺寸以适应指定的字体大小。

如果设置字体大小失败(返回值非零),则打印调试信息并返回 -1 表示失败。

如果一切顺利,函数返回 0 表示成功初始化字体模块。

该函数的作用是在 FreeType 字体模块中初始化相关的数据结构和对象,为后续的字体渲染和位图获取操作做准备。

获得UNICODE字符的FreeType位图

/**********************************************************************
 * 函数名称: ASCIIGetFontBitmap
 * 功能描述: 获得UNICODE字符的FreeType位图
 * 输入参数: dwCode       - 字符的UNICODE编码值
 * 输出参数: ptFontBitMap - 内含位图信息
 * 返 回 值: 0  - 成功
 *            -1 - 失败 
 ***********************************************************************/
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iError;
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;
#if 0
    FT_Vector tPen;
    tPen.x = 0;
    tPen.y = 0;
    /* set transformation */
    FT_Set_Transform(g_tFace, 0, &tPen);
#endif
    /* load glyph image into the slot (erase previous one) */
    //iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER );
    iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
    if (iError)
    {
        DBG_PRINTF("FT_Load_Char error for code : 0x%x\n", dwCode);
        return -1;
    }
    //DBG_PRINTF("iPenX = %d, iPenY = %d, bitmap_left = %d, bitmap_top = %d, width = %d, rows = %d\n", iPenX, iPenY, g_tSlot->bitmap_left, g_tSlot->bitmap_top, g_tSlot->bitmap.width, g_tSlot->bitmap.rows);
    ptFontBitMap->iXLeft    = iPenX + g_tSlot->bitmap_left;
    ptFontBitMap->iYTop     = iPenY - g_tSlot->bitmap_top;
    ptFontBitMap->iXMax     = ptFontBitMap->iXLeft + g_tSlot->bitmap.width;
    ptFontBitMap->iYMax     = ptFontBitMap->iYTop  + g_tSlot->bitmap.rows;
    ptFontBitMap->iBpp      = 1;
    ptFontBitMap->iPitch    = g_tSlot->bitmap.pitch;
    ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer;
    ptFontBitMap->iNextOriginX = iPenX + g_tSlot->advance.x / 64;
    ptFontBitMap->iNextOriginY = iPenY;
    //DBG_PRINTF("iXLeft = %d, iYTop = %d, iXMax = %d, iYMax = %d, iNextOriginX = %d, iNextOriginY = %d\n", ptFontBitMap->iXLeft, ptFontBitMap->iYTop, ptFontBitMap->iXMax, ptFontBitMap->iYMax, ptFontBitMap->iNextOriginX, ptFontBitMap->iNextOriginY);
    return 0;
}

这段代码是 FreeTypeGetFontBitmap 函数的实现。该函数用于获取指定 UNICODE 字符的 FreeType 位图。

函数参数说明:

unsigned int dwCode:字符的 UNICODE 编码值。

PT_FontBitMap ptFontBitMap:指向存储位图信息的结构体指针。

函数内部逻辑:

声明并初始化变量 iError,iPenX 和 iPenY,用于后续操作。

调用 FT_Load_Char 函数加载指定字符的字形图像到字形槽(glyph slot)中,并指定加载标志为 FT_LOAD_RENDER | FT_LOAD_MONOCHROME。这将加载字符的位图图像,并将其存储在字形槽的 bitmap 成员中。

如果加载字形图像失败(返回值非零),则打印调试信息并返回 -1 表示失败。

计算位图在画布上的位置和尺寸,并将其存储在 ptFontBitMap 结构体的相应成员中。

iXLeft 和 iYTop 是位图左上角的坐标,根据当前的绘制原点和字形槽的 bitmap_left 和 bitmap_top 计算得到。

iXMax 和 iYMax 是位图右下角的坐标,根据 iXLeft、iYTop 和位图的宽度(bitmap.width)和高度(bitmap.rows)计算得到。

iBpp 表示位图的每像素位数,这里是单色位图,因此为 1。

iPitch 是位图的行间距,即每行像素占用的字节数。

pucBuffer 是指向位图数据的缓冲区指针,存储在字形槽的 bitmap.buffer 中。

iNextOriginX 和 iNextOriginY 是下一个字符绘制原点的坐标,根据当前绘制原点和字形槽的 advance.x 值计算得到。

如果一切顺利,函数返回 0 表示成功获取位图。

该函数的作用是利用 FreeType 库加载指定字符的字形图像,并提取其中的位图信息,包括位置、尺寸、像素位数、行间距和数据缓冲区。这些信息可以用于后续的字体渲染和显示操作。

设置字符的尺寸(单位:色素

/**********************************************************************
 * 函数名称: FreeTypeSetFontSize
 * 功能描述: 设置字符的尺寸(单位:色素)
 * 输入参数: dwFontSize - 字符的尺寸(单位:色素)
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/
static void FreeTypeSetFontSize(unsigned int dwFontSize)
{
    FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
}

这段代码是 FreeTypeSetFontSize 函数的实现。该函数用于设置字符的尺寸(单位:像素)。

函数参数说明:

unsigned int dwFontSize:字符的尺寸(单位:像素)。函数内部逻辑:

调用 FreeType 库的 FT_Set_Pixel_Sizes 函数,将指定字符的字体尺寸设置为 dwFontSize 像素高度。第二个参数为高度,设置为 dwFontSize,第三个参数为宽度,设置为 0,表示按比例自动计算宽度。

如果设置失败(返回值非零),可以打印调试信息或采取适当的错误处理措施。

该函数的作用是通过调用 FreeType 库函数,设置指定字符的字体尺寸,以便在后续的字体渲染和显示操作中使用。

注册"FreeType字体模块"

/**********************************************************************
 * 函数名称: FreeTypeInit
 * 功能描述: 注册"FreeType字体模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int FreeTypeInit(void)
{
    return RegisterFontOpr(&g_tFreeTypeFontOpr);
}

gbk

#include <config.h>
#include <fonts_manager.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize);
static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static T_FontOpr g_tGBKFontOpr = {
    .name          = "gbk",
    .FontInit      = GBKFontInit,
    .GetFontBitmap = GBKGetFontBitmap,
};
static int g_iFdHZK;
static unsigned char *g_pucHZKMem;
static unsigned char *g_pucHZKMemEnd;
/**********************************************************************
 * 函数名称: GBKFontInit
 * 功能描述: GBK字体模块的初始化函数
 * 输入参数: pcFontFile - GBK字库文件
 *            dwFontSize - 字符尺寸,必须是16,否则失败(因为我们只有16x16位图)
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize)
{
    struct stat tStat;
    if (16 != dwFontSize)
    {
        DBG_PRINTF("GBK can't support %d fontsize\n", dwFontSize);
        return -1;
    }
    g_iFdHZK = open(pcFontFile, O_RDONLY);
    if (g_iFdHZK < 0)
    {
        DBG_PRINTF("can't open %s\n", pcFontFile);
        return -1;
    }
    if(fstat(g_iFdHZK, &tStat))
    {
        DBG_PRINTF("can't get fstat\n");
        return -1;
    }
    g_pucHZKMem = (unsigned char *)mmap(NULL , tStat.st_size, PROT_READ, MAP_SHARED, g_iFdHZK, 0);
    if (g_pucHZKMem == (unsigned char *)-1)
    {
        DBG_PRINTF("can't mmap for hzk16\n");
        return -1;
    }
    g_pucHZKMemEnd = g_pucHZKMem + tStat.st_size;
    return 0;
}
/**********************************************************************
 * 函数名称: GBKGetFontBitmap
 * 功能描述: 获得GBK字符的位图
 * 输入参数: dwCode       - 字符的GBK编码值
 * 输出参数: ptFontBitMap - 内含位图信息
 * 返 回 值: 0  - 成功
 *            -1 - 失败 
 ***********************************************************************/
static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iArea;
    int iWhere;
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;
    DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    if (dwCode & 0xffff0000)
    {
        DBG_PRINTF("don't support this code : 0x%x\n", dwCode);
        return -1;
    }    
    iArea  = (int)(dwCode & 0xff) - 0xA1;
    iWhere = (int)((dwCode >> 8) & 0xff) - 0xA1;
    if ((iArea < 0) || (iWhere < 0))
    {
        DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
        return -1;
    }
    ptFontBitMap->iXLeft    = iPenX;
    ptFontBitMap->iYTop     = iPenY - 16;
    ptFontBitMap->iXMax     = iPenX + 16;
    ptFontBitMap->iYMax     = iPenY;
    ptFontBitMap->iBpp      = 1;
    ptFontBitMap->iPitch    = 2;
    ptFontBitMap->pucBuffer = g_pucHZKMem + (iArea * 94 + iWhere)*32;;    
    if (ptFontBitMap->pucBuffer >= g_pucHZKMemEnd)
    {
        return -1;
    }
    ptFontBitMap->iNextOriginX = iPenX + 16;
    ptFontBitMap->iNextOriginY = iPenY;
    DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}
/**********************************************************************
 * 函数名称: GBKInit
 * 功能描述: 注册"GBK字体模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int GBKInit(void)
{
    return RegisterFontOpr(&g_tGBKFontOpr);
}

这段代码实现了针对 GBK 字体的初始化和字符位图获取功能。

首先定义了一个名为 g_tGBKFontOpr 的结构体变量,用于描述 GBK 字体的操作函数和名称。

然后定义了一些静态变量,包括文件描述符 g_iFdHZK,指向字库文件的内存映射指针 g_pucHZKMem,以及指向字库文件结尾的指针 g_pucHZKMemEnd。

实现了 GBKFontInit 函数,用于初始化 GBK 字体模块。它接受字库文件路径和字符尺寸作为参数。在函数内部,它会打开字库文件,获取文件状态信息,然后使用 mmap 函数将字库文件映射到内存中。最后,它返回一个表示初始化结果的整数值。

实现了 GBKGetFontBitmap 函数,用于获取指定 GBK 字符的位图信息。它接受一个 GBK 编码值和一个指向位图信息结构体的指针作为参数。在函数内部,根据 GBK 编码值计算字符所在的区和位,然后将位图信息填充到结构体中。最后,它返回一个表示获取结果的整数值。

最后,实现了 GBKInit 函数,用于注册 GBK 字体模块。它调用 RegisterFontOpr 函数将 g_tGBKFontOpr 结构体注册到全局字体操作表中。

该段代码主要用于支持 GBK 字体的初始化和字符位图获取,通过注册相应的函数实现对 GBK 字体的操作。

GBK字体模块的初始化函数

/**********************************************************************
 * 函数名称: GBKFontInit
 * 功能描述: GBK字体模块的初始化函数
 * 输入参数: pcFontFile - GBK字库文件
 *            dwFontSize - 字符尺寸,必须是16,否则失败(因为我们只有16x16位图)
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize)
{
    struct stat tStat;
    if (16 != dwFontSize)
    {
        DBG_PRINTF("GBK can't support %d fontsize\n", dwFontSize);
        return -1;
    }
    g_iFdHZK = open(pcFontFile, O_RDONLY);
    if (g_iFdHZK < 0)
    {
        DBG_PRINTF("can't open %s\n", pcFontFile);
        return -1;
    }
    if(fstat(g_iFdHZK, &tStat))
    {
        DBG_PRINTF("can't get fstat\n");
        return -1;
    }
    g_pucHZKMem = (unsigned char *)mmap(NULL , tStat.st_size, PROT_READ, MAP_SHARED, g_iFdHZK, 0);
    if (g_pucHZKMem == (unsigned char *)-1)
    {
        DBG_PRINTF("can't mmap for hzk16\n");
        return -1;
    }
    g_pucHZKMemEnd = g_pucHZKMem + tStat.st_size;
    return 0;
}

这段代码实现了针对 GBK 字体的初始化函数 GBKFontInit。函数接受字库文件路径和字符尺寸作为参数。

函数首先检查字符尺寸是否为 16,如果不是,则打印错误信息并返回 -1,表示初始化失败。

然后,函数通过 open 函数以只读方式打开字库文件。如果打开失败(返回的文件描述符小于 0),则打印错误信息并返回 -1。

接下来,函数使用 fstat 函数获取字库文件的状态信息,并将结果保存在 tStat 结构体中。如果获取状态信息失败,函数打印错误信息并返回 -1。

然后,函数使用 mmap 函数将字库文件映射到内存中。它使用文件描述符 g_iFdHZK、字库文件大小 tStat.st_size 以及 PROT_READ 和 MAP_SHARED 参数来执行映射。如果映射失败(返回的指针为 -1),函数打印错误信息并返回 -1。

最后,函数设置全局变量 g_pucHZKMem 指向映射后的字库内存起始位置,g_pucHZKMemEnd 指向字库内存的结尾位置。

如果以上所有步骤都成功执行,函数返回 0,表示初始化成功。

该函数主要用于打开和映射 GBK 字库文件到内存,为后续的字符位图获取操作提供支持。

获得GBK字符的位图

/**********************************************************************
 * 函数名称: GBKGetFontBitmap
 * 功能描述: 获得GBK字符的位图
 * 输入参数: dwCode       - 字符的GBK编码值
 * 输出参数: ptFontBitMap - 内含位图信息
 * 返 回 值: 0  - 成功
 *            -1 - 失败 
 ***********************************************************************/
static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iArea;
    int iWhere;
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;
    DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    if (dwCode & 0xffff0000)
    {
        DBG_PRINTF("don't support this code : 0x%x\n", dwCode);
        return -1;
    }    
    iArea  = (int)(dwCode & 0xff) - 0xA1;
    iWhere = (int)((dwCode >> 8) & 0xff) - 0xA1;
    if ((iArea < 0) || (iWhere < 0))
    {
        DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
        return -1;
    }
    ptFontBitMap->iXLeft    = iPenX;
    ptFontBitMap->iYTop     = iPenY - 16;
    ptFontBitMap->iXMax     = iPenX + 16;
    ptFontBitMap->iYMax     = iPenY;
    ptFontBitMap->iBpp      = 1;
    ptFontBitMap->iPitch    = 2;
    ptFontBitMap->pucBuffer = g_pucHZKMem + (iArea * 94 + iWhere)*32;;    
    if (ptFontBitMap->pucBuffer >= g_pucHZKMemEnd)
    {
        return -1;
    }
    ptFontBitMap->iNextOriginX = iPenX + 16;
    ptFontBitMap->iNextOriginY = iPenY;
    DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

这段代码实现了针对 GBK 字符的位图获取函数 GBKGetFontBitmap。函数接受一个 GBK 编码值和一个指向 FontBitMap 结构体的指针作为参数。

函数首先获取当前绘制原点的坐标 (iPenX 和 iPenY),这些坐标用于确定字符位图的位置。

接下来,函数检查给定的 GBK 编码值是否超出范围。如果 GBK 编码值超出范围 (高于 0xffff),则打印错误信息并返回 -1,表示不支持该编码值。

然后,函数计算 GBK 编码值的区位码。GBK 编码是由高字节和低字节组成的,高字节表示区号,低字节表示位号。通过位运算和减法操作,可以计算出区号 iArea 和位号 iWhere。如果计算得到的区号或位号小于 0,则打印错误信息并返回 -1。

接下来,函数设置 FontBitMap 结构体的各个字段,包括左上角坐标、右下角坐标、像素深度、扫描行距离以及位图数据缓冲区。左上角坐标由绘制原点和位图偏移量计算得到。右下角坐标为左上角坐标加上位图宽度和高度。像素深度为 1,表示单色位图。扫描行距离为 2,表示每行占用的字节数。位图数据缓冲区的计算通过使用 g_pucHZKMem 指针和区位码来获取。

如果计算得到的位图数据缓冲区的地址超出了字库内存的范围,即超过了 g_pucHZKMemEnd,则返回 -1,表示获取位图失败。

最后,函数设置下一个绘制原点的坐标,即将当前绘制原点向右移动 16 个像素。然后打印调试信息,并返回 0,表示获取位图成功。

该函数用于根据给定的 GBK 编码值获取对应的字符位图信息。它计算出位图在字库内存中的偏移量,并根据该偏移量获取位图数据。函数还根据位图的大小和绘制原点的位置设置了位图的相关信息,以便后续绘制操作使用。


目录
相关文章
|
3月前
|
存储
从源码角度分析Qt元对象系统1
从源码角度分析Qt元对象系统
79 0
|
3月前
从源码角度分析Qt元对象系统2
从源码角度分析Qt元对象系统
55 0
|
6月前
|
C语言
转载 - gcc/ld 动态连接库和静态连接库使用方法
本文介绍了如何在GCC中实现部分程序静态链接、部分动态链接。使用`-Wl`标志传递链接器参数,`-Bstatic`强制链接静态库,`-Bdynamic`强制链接动态库。
|
6月前
|
运维 Linux Apache
LAMP架构调优(三)——模块的安装与调用
LAMP架构调优(三)——模块的安装与调用
32 0
|
6月前
|
定位技术
R语言GD包地理探测器分析时报错、得不到结果等情况的解决方案
R语言GD包地理探测器分析时报错、得不到结果等情况的解决方案
171 1
|
存储
libjpeg库使用实例细节分析
libjpeg库使用实例细节分析
257 0
|
Scala 开发者
包对象注意事项和细节说明|学习笔记
快速学习包对象注意事项和细节说明。
包对象注意事项和细节说明|学习笔记
|
C语言 计算机视觉 C++
ffmpeg 纯静态编译,以及添加自定义库流程摘要
需求:    1. 纯静态编译ffmpeg ,即ldd ./ffmpeg 的结果是:not a dynamic executable    2.  修改ffmpeg 项目,添加自定义功能库    3. 自定义库由c++实现,要求能被纯c的ffmpeg项目调用    4. 自定义库必须使用g++ 的一些高级特性编译,要求g++支持c++11    5. 自定义库使用了pthread库 和openmp 库    6. 自定义库使用了opencv 3.0.0库,    7. 禁用所有的图形显示库x11,xcb,声音设备avdevice等等,静态链接这些库,会很痛苦。
4939 0
|
Java
编译freetype:如果链接路径中能找到libpng,就会自动依赖,没有也能编译通过
编译freetype:如果链接路径中能找到libpng,就会自动依赖,没有也能编译通过
185 0
|
编译器 Linux Android开发
图像库 libpng 编译与实践
在之前的文章中介绍了 stb_image 图像库,还顺带提到了 libpng 和 libjpeg ,这篇文章就是介绍如何在 Android 平台上用 CMake 编译 libpng 动态库以及 libpng 使用实践。
583 0
图像库 libpng 编译与实践