让 Emoji 进入与普通文字相同的整形、测量、基线、命中测试和绘制路径,而不是在布局完成后额外贴一张图片。
完成本章后,你可以加载内建 Emoji 包、把 Emoji 交给 xgeTextShape 整形,并理解肤色修饰符、变体选择符和 ZWJ 家庭序列为什么都必须作为一个逻辑文本项目处理。
xgeEmojiPackLoadBuiltin 提供 SVG 图形及度量;也可以用 xgeEmojiPackAddSvgMemory 加入应用自己的序列。XGE_TEXT_SHAPE_EMOJI 启用 Emoji 识别,XGE_TEXT_SHAPE_DEFAULT 同时启用 kerning 和 Emoji。| API / 常量 | 用途 |
|---|---|
xgeEmojiPackLoadBuiltin | 加载内建 SVG Emoji 资源包。 |
xgeEmojiPackMatch | 检查 UTF-8 字节位置是否匹配完整 Emoji 序列。 |
xgeTextShape | 将文字与 Emoji 统一为 xge_glyph_run_t。 |
XGE_EMOJI_LINE_STABLE | 保持常规文字行高,适合编辑器和列表。 |
examples\xge_emoji\build.bat
build\xge_emoji.exe --capture tutorial\img\ch211_1.png
# 教程镜像入口:包含同一份已验证实现
gcc -O2 -I. -o build\ch211_main1.exe examples\tutorial_capture\ch211_main1.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
build\ch211_main1.exe --capture tutorial\img\ch211_1.pngxge_text_shape_desc_t desc = { 0 };
xge_glyph_run_t run = { 0 };
desc.iSize = sizeof(desc); desc.pFont = font;
desc.sText = "Hello 😀 Rocket 🚀"; desc.iTextSize = -1;
desc.iFlags = XGE_TEXT_SHAPE_DEFAULT;
desc.iEmojiPresentation = XGE_EMOJI_PRESENTATION_AUTO;
desc.iEmojiLinePolicy = XGE_EMOJI_LINE_STABLE;
if (xgeTextShape(&desc, &run) == XGE_OK) {
xgeGlyphRunDraw(&run, x, y, color, XGE_DRAW_SCREEN_SPACE);
xgeGlyphRunFree(&run); // 释放整形结果
}权威实现是 examples/xge_emoji/main.c;教程的 examples/tutorial_capture/ch211_main1.c 直接包含它,因此网页、教程构建入口和示例库始终使用同一份已验证代码。示例以 16、24、40 与 72 px 同时渲染普通文字、单码点 Emoji、肤色修饰符、变体选择符、国旗和 ZWJ 家庭序列,并画出测量框与基线。
👍🏽、❤️、国旗和 ZWJ 家庭都由多个码点组成;编辑、选择和光标移动应依赖 GlyphRun 的 cluster 映射。pFont 与 fallback 链处理;Emoji artwork 来自 pack。xgeEmojiPackFree。XGE_EMOJI_PRESENTATION_TEXT,比较 VS15/VS16 序列。XGE_EMOJI_LINE_EXPAND,观察大号 Emoji 对行盒的影响。xgeEmojiPackMatch 扫描聊天消息,统计完整 Emoji 数而非 UTF-8 字节数。