text-measurer-harfbuzz 0.1.0

A text measurer using harfbuzz_rs
Documentation
use log::info;

use crate::error::Error;
use harfbuzz_rs::{self, shape, Face, Font, UnicodeBuffer};

pub fn measure_text_width(font: Vec<u8>, font_size: u32, text: &str) -> Result<f64, Error> {
    let face = Face::from_bytes(&font, 0);

    let face_upem = face.upem() as f64;

    let font = Font::new(face);

    let scale_factor = font_size as f64 / face_upem;

    let buffer = UnicodeBuffer::new().add_str(text);
    let output = shape(&font, buffer, &[]);

    let positions = output.get_glyph_positions();
    let infos = output.get_glyph_infos();

    assert_eq!(positions.len(), infos.len());

    let mut width = 0f64;

    // iterate over the shaped glyphs
    for (position, info) in positions.iter().zip(infos) {
        let gid = info.codepoint;
        let cluster = info.cluster;
        let x_advance = position.x_advance as f64 * scale_factor;
        let x_offset = position.x_offset as f64 * scale_factor;
        let y_offset = position.y_offset as f64 * scale_factor;

        // Here you would usually draw the glyphs.
        info!(
            "gid{:?}={:?}@{:?},{:?}+{:?}",
            gid, cluster, x_advance, x_offset, y_offset
        );

        width += x_advance - x_offset;
    }

    Ok(width)
}