如何在COSMIC-Text中准确测量文本实际尺寸?
如何正确在COSMIC-Text中测量文本尺寸?
你的代码中宽度测量不准确的核心原因有两个:
- 未设置足够大的换行宽度,导致文本被自动换行,
run.line_w仅返回换行后的行宽而非实际文本总宽度; - 遍历字形累加宽度的方式忽略了字距调整(kerning)和字形间距,导致结果偏小。
以下是修正后的实现:
pub fn measure_text(text: &str, attrs: Attrs, buffer: &mut Buffer) -> Option<Size> { // 设置无限换行宽度,确保文本不会自动换行 buffer.set_wrap_width(f32::INFINITY); buffer.set_text(&mut font_system(), text, attrs, Shaping::Advanced); buffer.shape_until_scroll(&mut font_system()); let mut total_width = 0.0; let mut min_y = f32::MAX; let mut max_y = f32::MIN; for run in buffer.layout_runs() { // 无换行时,run.line_w即为该行文本的实际总宽度 total_width = total_width.max(run.line_w); // 用line_top和line_bottom覆盖文本的完整垂直范围 min_y = min_y.min(run.line_top); max_y = max_y.max(run.line_bottom); } Some(Size::from_wh(total_width, max_y - min_y)) }
关键修正点说明
- 设置换行宽度:通过
buffer.set_wrap_width(f32::INFINITY)禁用自动换行,确保文本以单行完整显示,此时run.line_w会返回文本的实际总宽度。 - 正确计算高度:使用
run.line_top和run.line_bottom替代之前的run.line_y,这两个值直接对应文本行的顶部和底部边界,能准确覆盖字形的上升、下降部分。 - 避免手动累加字形宽度:COSMIC-Text在布局时已经计算好了包含字距、间距的总宽度,直接使用
run.line_w即可,无需手动遍历字形计算。
如果需要处理多行文本,上述代码依然有效:total_width会取所有行的最大宽度,max_y - min_y会返回所有行的总高度。
内容的提问来源于stack exchange,提问作者Jan Diederich
相关产品推荐
相关产品推荐

