多语言字体与 CJK 支持

多语言文本动画的核心挑战在于 CJK(中日韩)字符的正确分割与 Unicode 码点处理。Texturge 通过 FCharBreakIteratorTexturge::Unicode 工具与码元/字形双向映射解决这些问题。

NOTE

Texturge 不存在 UTexturgeFontAsset、字体图集烘焙或 SDF 字形缓存。字符渲染由 UMG/Slate 的标准字体管线处理,插件仅负责动画曲线逻辑与字形分割。

字形分割管线

为什么需要特殊处理

  • CJK 文本不使用空格分词,每个字符独立表意
  • UTF-16 码元(TCHAR)不等于 Unicode 码点:Emoji 等增补平面字符由代理对(2 个码元)组成
  • 逐字形动画必须以码点为单位,而非码元

FCharBreakIterator

FCharBreakIterator 实现 IBreakIterator 接口,在 SetString预计算全部断点

// 实现 IBreakIterator 接口
FCharBreakIterator Iterator;
Iterator.SetString(InText);          // 预计算断点数组(含 0 与末尾)
int32 Pos = Iterator.ResetToBeginning();
while ((Pos = Iterator.MoveToNext()) != INDEX_NONE)
{
    // 每个断点 = 一个字形边界
}

主要能力:

  1. 代理对安全——增补平面字符(Emoji 🎮 等)作为一个字形,不分裂
  2. CJK 附着——CJK 标点正确归属(IsCJKPunctuation
  3. 韩文音节——谚文音节块作为整体处理
  4. GetCurrentPosition() / MoveToPrevious() / MoveToCandidateBefore / MoveToCandidateAfter 完整游标接口

码元 ↔ 字形双向映射

UTextAnimator 维护两个映射数组(0.2.0 引入,全文按码点索引统一):

映射说明
CodeUnitToGlyphIndex码元索引 → 字形索引(代理对两码元映射同一字形)
GlyphIndexToCodeUnit字形索引 → 码元索引

GetGlyphIndexForCodeUnit(int32) 公开查询接口。打字机揭示、富文本段落截取(SerializeSubstring)均按码点索引工作。

与传统方法对比

方法拉丁字符CJKEmoji(代理对)
按 TCHAR(UTF-16 码元)切分正确正确错误(分裂为 2 字形)
按字节切分错误错误错误
FCharBreakIterator + 码点索引正确正确正确

Unicode 工具类

Texturge::Unicode 命名空间提供码点级分类函数(UnicodeUtils.h,全部 FORCEINLINE):

函数判定范围
IsCJKUnifiedIdeographs(uint32)主区块 + 扩展 A~F/I + 兼容表意(0x3400-0x2FA1F)
IsHiragana(uint32)平假名 0x3040-0x309F
IsKatakana(uint32)片假名 0x30A0-0x30FF、0x31F0-0x31FF
IsHangulSyllables(uint32)谚文音节 0xAC00-0xD7AF、谚文字母 0x1100-0x11FF
IsCJKPunctuation(uint32)CJK 标点 0x3000-0x303F、0xFE30-0xFE4F、0xFF01-0xFF60、0xFFE0-0xFFEE
IsCJK(uint32)以上五者聚合
IsHighSurrogate(TCHAR) / IsLowSurrogate(TCHAR)UTF-16 代理区判定
ComposeSurrogatePair(TCHAR, TCHAR)代理对合成 32 位码点

这些工具在 BuildScheduleInfos 中用于分类每个字形(bIsWhitespace / bIsPunctuation / bIsCJK / bIsDecorator),决定其调度行为。

字体回退

Texturge 不直接管理字体资产,依赖 UMG 字体管线:

  1. UAnimatedTextBlock / UAnimatedRichTextBlockFont 属性(继承自基类)设置主字体
  2. UE5 复合字体(Composite Font)系统自动处理缺失字符回退
  3. 覆盖多语言的复杂场景,使用复合字体的子字体(Sub-Font)功能分别指定各书写系统的字体

TIP

对于覆盖多语言的项目,使用复合字体的子字体功能分别为各书写系统指定字体,而非依赖多控件叠加。

测试 CJK 动画

推荐测试文本

STextAnimationDesignerView 的预览文本框(UTexturgePreviewSceneConfig::PreviewText)输入以下混合文本验证支持:

English 日本語 한국어 中文 العربية हिन्दी
Emoji: 🎮🎯✨
全角:ABCD1234

验证检查项

  1. 字形计数正确——每个 CJK 字 / Emoji 计为一个字形(代理对不分裂)
  2. 调度延迟均匀——逐字动画节奏不因字符编码长度变化而跳帧
  3. 分类正确——空白 / 标点 / CJK / 装饰器分类在 BuildScheduleInfos 输出中正确
  4. RTL 文本——阿拉伯文从右到左正确排列(布局由 Slate 处理)
images/cjk-animation-preview.png — CJK 文本动画预览截图:设计器视口中混合文本(English 日本語 한국어 中文 العربية)逐字揭示,下方标注字形计数与码点索引,Emoji 显示为单字形 — CJK animation preview screenshot: mixed text (English 日本語 한국어 中文 العربية) revealed per-glyph in the designer viewport, with glyph count and code point indices annotated below, Emoji shown as a single glyph