【问题标题】:rusttype get text width for Fontrusttype 获取字体的文本宽度
【发布时间】:2021-09-10 01:23:17
【问题描述】:

动机

我正在尝试使用imageprocImage 上呈现动态长度的String

问题

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

附加说明

rusttype是imageproc使用的字体库。

【问题讨论】:

    标签: image image-processing rust fonts


    【解决方案1】:

    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,同时还需要使用非整数大小。所以在过去,我在示例中创建了自己的版本本质上

    一个重要的注意事项是,当您只需要大小时,传递给布局的位置真的并不重要。但是,如果您确实需要渲染字形,则位置很重要,否则结果将包含锯齿伪影。

    // 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(),然后将行高和行间距相加。

    【讨论】:

    • 只需将.last() 移动到一个队列即可提高大型字符串的性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 2019-12-14
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 2022-12-25
    相关资源
    最近更新 更多