Chapter 81 · 字体与文本

TTF 字体加载

从文件或内存加载 TTF/OTF 字体,创建字体实例用于文本渲染。

81

API 速查

函数说明
int xgeFontFaceLoad(xge_font_face* ppFace, const char* sPath, const xge_font_face_desc_t* pDesc)加载字体文件
int xgeFontFaceLoadMemory(xge_font_face* ppFace, const void* pData, int iSize, const xge_font_face_desc_t* pDesc)从内存加载
int xgeFontFaceAddRef(xge_font_face pFace)增加引用
void xgeFontFaceFree(xge_font_face pFace)释放字体
int xgeFontCreate(xge_font pFont, xge_font_face pFace, const xge_font_instance_desc_t* pDesc)创建字体实例
int xgeFontLoad(xge_font pFont, const char* sPath, float fSize)快捷加载(文件)
int xgeFontLoadMemory(xge_font pFont, const void* pData, int iSize, float fSize)快捷加载(内存)
int xgeFontAddRef(xge_font pFont)增加引用
void xgeFontFree(xge_font pFont)释放实例

编译本章示例

gcc -O2 -I. -o ch81.exe ch81_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch81.exe

示例:加载字体并绘制

// 方式 1:快捷加载(推荐)
xge_font font = NULL;
xgeFontLoad(&font, "fonts/NotoSansSC.ttf", 24.0f);

// 方式 2:分步加载(更灵活)
xge_font_face face = NULL;
xgeFontFaceLoad(&face, "fonts/Roboto.ttf", NULL);

xge_font_instance_desc_t desc = { 0 };
desc.fSize = 32.0f;
xge_font font2 = NULL;
xgeFontCreate(&font2, face, &desc);
xgeFontFaceFree(face);  // Font 内部已 AddRef

// 方式 3:从内存加载(嵌入资源)
extern const uint8_t fontData[];
extern const int fontDataSize;
xge_font font3 = NULL;
xgeFontLoadMemory(&font3, fontData, fontDataSize, 18.0f);

// 释放
xgeFontFree(font);
xgeFontFree(font2);
xgeFontFree(font3);

完整代码

将以下代码保存为 ch81_main.c,编译后运行即可看到 TTF 字体加载与绘制效果:

#include "xge.h"

static xge_font g_font = NULL;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);

    // 绘制文字
    xgeTextDraw(g_font, "Hello XGE Font!", 100, 200, 0xFFFFFFFF)
    xgeTextDraw(g_font, "XGE 字体渲染测试", 100, 280, 0x4FD8C2FF)
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch81 - TTF Font Load";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);

    // 快捷加载 TTF 字体
    xgeFontLoad(&g_font, "fonts/NotoSansSC.ttf", 32.0f);

    xgeRun(onFrame, NULL);
    xgeFontFree(g_font);
    xgeUnit();
    return 0;
}

代码讲解

  • xgeFontLoad:快捷加载 TTF 文件,内部自动创建 Face + Font 实例。
  • fSize:字体大小(像素),决定光栅化分辨率。
  • xgeTextDraw:在指定位置绘制文字,支持中英文混排。
  • xgeFontFree:释放字体实例,内部自动释放 Face 引用。

要点与陷阱

  • FontLoad 快捷:内部自动创建 Face + Font,适合简单场景。
  • Face 共享:多个 Font 实例可共享同一 Face(不同大小)。
  • 引用计数:FontCreate 会对 Face AddRef,释放时自动 Free。
  • 内存加载:数据在加载后可释放,Font 内部已拷贝。

进阶练习

  1. 实现字体管理器:预加载常用字体 + 引用计数。
  2. 从 ZIP 包中读取字体文件并内存加载。
TTF 字体加载效果
图:TTF 字体加载渲染效果