rusttype 获取字体的文本宽度

rusttype get text width for Font

动机

我正在尝试在 Image using imageproc 上呈现 String 的动态长度。

问题

我需要一种方法或函数来计算使用特定 FontScale 渲染时文本的宽度以使文本在图像上居中。

补充说明

rusttype是imageproc使用的字体库

rusttype 存储库包含一个示例 (examples/image.rs),它测量一行文本的边界并将其呈现为图像。 除了居中部分外,基本上就是您要搜索的内容。

// rusttype = "0.9.2"
use rusttype::{point, Font, Scale};

let v_metrics = font.v_metrics(scale);

let glyphs: Vec<_> = font.layout(text, scale, point(0.0, 0.0)).collect();
let glyphs_height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
let glyphs_width = {
    let min_x = glyphs
        .first()
        .map(|g| g.pixel_bounding_box().unwrap().min.x)
        .unwrap();
    let max_x = glyphs
        .last()
        .map(|g| g.pixel_bounding_box().unwrap().max.x)
        .unwrap();
    (max_x - min_x) as u32
};

我不喜欢总是需要收集到 Vec,同时还需要使用非整数大小。所以在过去,我创建了我自己的示例中 essentially 的版本。

一个重要的注意事项是,当您只需要尺寸时,传递给布局的位置真的无关紧要。但是,如果您确实需要渲染字形,那么位置很重要,否则结果将包含锯齿。

// rusttype = "0.9.2"
use rusttype::{point, Font, Scale};

fn measure_line(font: &Font, text: &str, scale: Scale) -> (f32, f32) {
    let width = font
        .layout(text, scale, point(0.0, 0.0))
        .map(|g| g.position().x + g.unpositioned().h_metrics().advance_width)
        .last()
        .unwrap_or(0.0);

    let v_metrics = font.v_metrics(scale);
    let height = v_metrics.ascent - v_metrics.descent + v_metrics.line_gap;

    (width, height)
}

如果文本有多行,那么您需要手动对字符串使用 .lines(),然后对行高和行间距求和。