使用Harfbuzz与Freetype实现竖排文本中横排英文的正确渲染
解决Harfbuzz+FreeType韩语竖排文本与旋转英文的对齐问题
针对你遇到的竖排韩语文本中旋转英文对齐偏差问题,核心是处理竖排文本的负x_offset影响,以下是几种可行的解决方案:
方案一:手动反转竖排文本的x_offset方向
Harfbuzz在竖排(HB_DIRECTION_TB)布局时,会根据字体GPOS表的竖排元数据生成x_offset,用于调整字形在竖排中的对齐。你可以在布局完成后直接遍历字形位置,反转x_offset的符号,抵消其对对齐的影响:
// 假设已完成竖排文本的Harfbuzz布局 unsigned int glyph_count; hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(vt_buffer, &glyph_count); hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(vt_buffer, &glyph_count); // 反转每个字形的x_offset for (unsigned int i = 0; i < glyph_count; i++) { glyph_pos[i].x_offset *= -1; // 若竖排文本存在x_advance,也需同步反转(部分字体可能需要) // glyph_pos[i].x_advance *= -1; }
调整后,竖排文本的偏移方向反转,此时将横排渲染后旋转90度的英文直接放置到对应位置,即可实现对齐。
方案二:修正旋转英文的位置偏移
如果不想修改竖排文本的布局,可以提取竖排文本的x_offset总和(或单个字符的偏移值),在绘制旋转后的英文时,给英文的x坐标加上对应的正偏移值,抵消竖排文本的负偏移:
// 提取竖排文本的目标x_offset(以第一个字符为例,或取所有字符的偏移平均值) int vt_x_offset = glyph_pos[0].x_offset; // 绘制旋转后的英文时,调整x坐标抵消竖排偏移 draw_rotated_text(eng_x - vt_x_offset, eng_y, rotated_eng_surface);
这种方式更灵活,适合仅部分字符需要对齐的场景,但需要注意不同字体的x_offset可能存在差异,需根据实际布局调整。
方案三:利用Harfbuzz的字体特性调整竖排偏移
部分字体支持通过Harfbuzz的字体特性(feature)调整竖排偏移,可尝试启用vert(竖排替代字形)特性,看是否能改变偏移方向:
hb_feature_t features[] = {{HB_TAG('v','e','r','t'), 1, 0, UINT_MAX}}; hb_shape(font, vt_buffer, features, ARRAY_LENGTH(features));
不过该方案依赖字体本身的特性支持,通用性较弱,建议优先尝试前两种方案。
额外注意事项
- 旋转英文时,需确保旋转原点与竖排文本的字形对齐基准一致(通常是字形的中心或基线),避免出现上下偏移。
- 测试时建议使用标准韩语字体(如Noto Sans KR),这类字体的竖排元数据更规范,偏移调整效果更稳定。
内容的提问来源于stack exchange,提问作者Lazy1
相关产品推荐
相关产品推荐

