Rusttype rasterize font and display text

I am confused about the rusttype crate. I can understand how the simple example works to create ascii art from text by mapping characters as pixel points, but I just want to display text in a window. What would you do instead of this:

let mut pixel_data = vec![b'@'; width * pixel_height];

Which gui library are you using?

minifb

Right now the only way I'm getting text to display is by putting the text into a string formatted as SVG, use resvg to convert that to a png and then displaying the png in the minifb window. I recognize how very wrong that is but I've not been able to figure out how the various glyph libraries generate pixel buffers that minifb can read.

Iirc there's an "image" example that writes to a Vec pixel grid. Maybe that's closer to what you want?

I guess I'm not clear on how to get the information supplied by the png::Decoder in that example without first saving the svg as a png file. I think the png crate documentation assumes a level of baseline knowledge that I don't possess.

I assume you would use Window::update_with_buffer if you're using minifb? In that case you can create a vector of u32 for the image data, and then call draw on your glyph, and inside the closure, write into the vector.

It would probably look like this, but I have not tested it:

/// from update_with_buffer example
fn from_u8_rgb(r: u8, g: u8, b: u8) -> u32 {
    let (r, g, b) = (r as u32, g as u32, b as u32);
    (r << 16) | (g << 8) | b
}

let mut vec = vec![0; width * height];
glyph.draw(|x, y, v| {
    let idx = (x + width * y) as usize;
    let brightness = (v * 255.0) as u8;
    // same r, g and b gives grayscale
    vec[idx] = from_u8_rgb(brightness, brightness, brightness);
});

// Update window
window.update_with_buffer(&vec, width, height)?;
1 Like

Thanks. I think you've got me on the right track, but I'm having a hard time getting the proper values for width and height, I think. for a single glyph I'm using width and height of 13 and 12 and get an error of "Required size for 13 (13 stride) x 12 buffer is 624 bytes but the size of the input buffer has the size 156 bytes".

Sounds that you tried to allocate a byte for each pixel, but 4-byte pixel values was expected. So for a byte buffer (a Vec<u8>) you need lenght width*height*4. OR you might be able to use a Vec<u32> or even some kind of Vec<Pixel> instead.

That did the trick (mostly). Still working on some quirks like the text not being crisp and being repeated four times, but it displays.