TextShape 将字符串转换为字形序列(GlyphRun),处理连字、字距调整和复杂文字布局。
| 函数 | 说明 |
|---|---|
int xgeTextShape(const xge_text_shape_desc_t* pDesc, xge_glyph_run_t* pRun) | 文本整形 |
void xgeGlyphRunFree(xge_glyph_run_t* pRun) | 释放字形序列 |
xge_vec2_t xgeGlyphRunMeasure(const xge_glyph_run_t* pRun) | 测量尺寸 |
int xgeGlyphRunHitTest(const xge_glyph_run_t* pRun, float fX, float fY, uint32_t* pCluster, int* pTrailing) | 命中测试 |
gcc -O2 -I. -o ch88.exe ch88_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch88.exe
xge_font font = NULL;
xgeFontLoad(&font, "Roboto.ttf", 24.0f);
// 构建整形描述
xge_text_shape_desc_t desc = { 0 };
desc.pFont = font;
desc.sText = "Hello, 世界!";
desc.fFontSize = 24.0f;
// 执行整形
xge_glyph_run_t run;
xgeTextShape(&desc, &run);
// 测量文本尺寸
xge_vec2_t size = xgeGlyphRunMeasure(&run);
// size.x = 宽度, size.y = 高度
// 命中测试(点击位置 → 字符索引)
uint32_t cluster;
int trailing;
xgeGlyphRunHitTest(&run, 50.0f, 12.0f,
&cluster, &trailing);
// 释放
xgeGlyphRunFree(&run);将以下代码保存为 ch88_main.c,编译后运行即可看到文本整形、测量与命中测试效果:
#include "xge.h"
#include <stdio.h>
static xge_font g_font = NULL;
static xge_glyph_run_t g_run;
static int g_hasRun = 0;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
if (!g_hasRun) return XGE_OK;
// 测量文本尺寸
xge_vec2_t size = xgeGlyphRunMeasure(&g_run);
char buf[256];
sprintf(buf, "Text size: %.1f x %.1f", size.x, size.y);
xgeTextDraw(g_font, buf, 20.0f, 20.0f, 0xFFFFFFFF)
// 绘制整形后的文本
float baseX = 20.0f, baseY = 80.0f;
xgeTextDraw(g_font, "Hello, 世界!", baseX, baseY,
0xFFFFFFFF)
// 绘制文本包围盒
xgeShapeRectStroke((xge_rect_t){baseX, baseY, size.x, size.y}, 1.0f, 0x44FF8844)
// 命中测试:模拟点击 x=50 位置
uint32_t cluster;
int trailing;
if (xgeGlyphRunHitTest(&g_run, 50.0f, 12.0f,
&cluster, &trailing) == XGE_OK) {
sprintf(buf, "HitTest(50,12): cluster=%u trailing=%d",
cluster, trailing);
xgeTextDraw(g_font, buf, 20.0f, 140.0f,
0xFF88FF88)
}
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch88 - Text Shape & HitTest";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xgeFontLoad(&g_font, "Roboto.ttf", 24.0f);
// 执行文本整形
xge_text_shape_desc_t desc = { 0 };
desc.pFont = g_font;
desc.sText = "Hello, 世界!";
desc.fFontSize = 24.0f;
if (xgeTextShape(&desc, &g_run) == XGE_OK)
g_hasRun = 1;
xgeRun(onFrame, NULL);
xgeGlyphRunFree(&g_run);
xgeFontFree(g_font);
xgeUnit();
return 0;
}