API 参考:Shaper(文本整形)
Shaper 类负责文本整形:将 Unicode 字符字符串转换为字体中一组定位字形(glyph)的过程。
概述
文本整形是必要的,用于:
- 连字:将 "f" + "i" 转换为单个 "fi" 字形。
- 字距调整:调整特定字符对(如 "AV")之间的间距。
- 复杂文字:处理阿拉伯文、天城文或泰文等字形会随相邻字符而变化的文字。
- 双向文本:处理混合的左到右(拉丁文)和右到左(阿拉伯文/希伯来文)文本。
基础整形
要简单地获取一个可用于绘制的 TextBlob(一组定位字形),请使用 shape() 方法。
java
try (Shaper shaper = Shaper.make()) {
Font font = new Font(typeface, 24);
// 简单整形(无宽度限制)
TextBlob blob = shaper.shape("Hello, Skija!", font);
canvas.drawTextBlob(blob, 20, 50, paint);
}换行与多行整形
Shaper 还可以根据最大宽度计算换行。
java
float maxWidth = 300f;
TextBlob multiLineBlob = shaper.shape(
"This is a long sentence that will be wrapped by the shaper.",
font,
maxWidth
);
// 注意:生成的 TextBlob 包含所有行,且各行相对于彼此正确定位。
canvas.drawTextBlob(multiLineBlob, 20, 100, paint);整形选项
您可以使用 ShapingOptions 来控制整形行为(例如文本方向)。
java
ShapingOptions options = ShapingOptions.DEFAULT.withLeftToRight(false); // 从右到左
TextBlob blob = shaper.shape("مرحبا", font, options, Float.POSITIVE_INFINITY, Point.ZERO);高级整形(RunHandler)
如果您需要完全控制整形过程(例如,为了实现自己的文本选择或自定义多样式布局),可以使用 RunHandler。
java
shaper.shape(text, font, ShapingOptions.DEFAULT, maxWidth, new RunHandler() {
@Override
public void beginLine() { ... }
@Override
public void runInfo(RunInfo info) {
// 获取当前字形序列的信息
System.out.println("Glyph count: " + info.getGlyphCount());
}
@Override
public void commitRunInfo() { ... }
@Override
public Point commitLine() { return Point.ZERO; }
// ... 更多方法 ...
});性能
- 缓存:文本整形是一项计算密集型操作(涉及 HarfBuzz)。如果您的文本是静态的,请将其整形一次并存储生成的
TextBlob。 - Shaper 实例:创建
Shaper涉及初始化 HarfBuzz。建议创建一个Shaper实例并在整个应用程序中重复使用(通常可以安全地重复使用,但如果使用多线程,请检查线程安全性)。
Shaper 与 Paragraph 对比
- 使用
Shaper用于高性能、单一风格的文本块,或者当您需要低级访问字形时。 - 使用 Paragraph 用于富文本(一个块中有不同的颜色/字体)、复杂的 UI 布局以及标准的文本编辑器行为。