Chapter 83 · 字体与文本

字体缓存加载

FontLoadCached 智能加载:优先使用 XRF 缓存,不存在时从 TTF 生成并缓存。

83

API 速查

函数说明
int xgeFontLoadCached(xge_font pFont, const char* sTTFPath, const char* sXRFPath, float fSize, uint32_t iFirstCodepoint, uint32_t iCount)缓存加载

编译本章示例

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

示例:智能缓存加载

// 首次运行:从 TTF 生成 XRF 缓存
// 后续运行:直接加载 XRF(快 10 倍+)
xge_font font = NULL;
xgeFontLoadCached(&font,
    "fonts/NotoSansSC.ttf",   // TTF 源
    "cache/NotoSans24.xrf",  // XRF 缓存路径
    24.0f,                    // 字号
    0x20, 95);                // ASCII 范围

// 加载逻辑:
// 1. 检查 XRF 是否存在且版本匹配
// 2. 存在 → 直接加载 XRF
// 3. 不存在 → 加载 TTF → 生成 XRF → 保存

// 适合中文字体:首次慢,后续秒开
xge_font cnFont = NULL;
xgeFontLoadCached(&cnFont,
    "fonts/NotoSansSC.ttf",
    "cache/NotoSansSC16.xrf",
    16.0f,
    0x4E00, 3000);  // 常用汉字

完整代码

将以下代码保存为 ch83_main.c,编译后运行即可看到缓存加载效果(首次运行生成 XRF,后续秒开):

#include "xge.h"

static xge_font g_font = NULL;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xgeTextDraw(g_font, "Cached Font Load!", 100, 250, 0xFFFFFFFF)
    xgeTextDraw(g_font, "First run: slow, Next: fast", 100, 310, 0x4FD8C2FF)
    return XGE_OK;
}

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

    // 智能缓存加载
    xgeFontLoadCached(&g_font,
        "fonts/NotoSansSC.ttf",
        "cache/NotoSans24.xrf",
        24.0f, 0x20, 95);

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

代码讲解

  • FontLoadCached:自动检查 XRF 缓存是否存在,存在则直接加载,否则从 TTF 生成。
  • 版本检查:TTF 修改后缓存自动失效重建。
  • 启动优化:中文字体首次加载可能耗时,后续秒开。
  • 路径可写:确保 cache/ 目录存在且有写权限。

要点与陷阱

  • 自动缓存:无需手动管理 XRF 生成,首次自动生成。
  • 版本检查:TTF 修改后缓存自动失效重建。
  • 路径可写:确保 XRF 缓存目录有写权限。
  • 启动优化:中文字体首次加载可能耗时,显示加载提示。

进阶练习

  1. 实现字体预热:启动时后台线程生成缓存。
  2. 多字号缓存:为常用字号预生成 XRF。
字体缓存加载效果
图:字体缓存加载渲染效果