alexheretic / glyph-brush

Fast GPU cached text rendering
Apache License 2.0
688 stars 52 forks source link

Can't draw text #152

Closed samchouse closed 2 years ago

samchouse commented 2 years ago

I'm trying to update all the dependencies of https://github.com/codepunkt/wasm-layout-text and now the text isn't drawing. I'm not entirely sure what I'm doing and it seems like a lot of the methods are gone and me replacing with them with what I think is their counterparts hasn't gone well.

// lib.rs
#[wasm_bindgen]
pub fn render(
    text: &Text,
    size: &Dimension,
    bounds: &Dimension,
    position: &Position,
    alignment: &Alignment,
) -> Vec<u8> {
    let font = text.font.to_vec();
    let fonts =
        vec![FontRef::try_from_slice(&font).expect("Error constructing Font")];

    let layout = Layout::default()
        .h_align(match alignment.horizontal {
            HorizontalAlign::Left => HAlign::Left,
            HorizontalAlign::Center => HAlign::Center,
            HorizontalAlign::Right => HAlign::Right,
        })
        .v_align(match alignment.vertical {
            VerticalAlign::Top => VAlign::Top,
            VerticalAlign::Center => VAlign::Center,
            VerticalAlign::Bottom => VAlign::Bottom,
        });

    let section_glyphs = layout.calculate_glyphs(
        &fonts,
        &SectionGeometry {
            screen_position: (position.x as f32, position.y as f32),
            bounds: (bounds.width as f32, bounds.height as f32),
            ..SectionGeometry::default()
        },
        &[SectionText {
            text: text.text.as_str(),
            scale: PxScale::from(text.size as f32),
            font_id: FontId(0),
        }],
    );

    let mut image =
        DynamicImage::ImageRgba8(RgbaImage::new(size.width as u32, size.height as u32)).to_rgba8();

    for section_glyph in section_glyphs {
        image.put_pixel(
            section_glyph.glyph.position.x as u32,
            section_glyph.glyph.position.y as u32,
            Rgba([
                text.color.red,
                text.color.green,
                text.color.blue,
                (section_glyph.byte_index * 255) as u8,
            ]),
        )
    }

    return image.to_vec();
}

First of all, how would I draw the text? I'm also a little confused about bounds, I'm not entirely sure what they are. How would I re-implement them into the updated code, I can't find any similar methods attached to section_glyph? Would it be something like this?

    let section_geometry = SectionGeometry {
        screen_position: (position.x as f32, position.y as f32),
        bounds: (bounds.width as f32, bounds.height as f32),
        ..SectionGeometry::default()
    };

    let section_glyphs = layout.calculate_glyphs(
        &fonts,
        &section_geometry,
        // ...
    )

   // ...

    for section_glyph in section_glyphs {
        let bounds = layout.bounds_rect(&section_geometry);
        image.put_pixel(
            (section_glyph.glyph.position.x + bounds.min.x) as u32,
            (section_glyph.glyph.position.y + bounds.min.y) as u32,
            Rgba([
                text.color.red,
                text.color.green,
                text.color.blue,
                (section_glyph.byte_index * 255) as u8,
            ]),
        )
    }
alexheretic commented 2 years ago

I think you are encountering a difference between rusttype and _abglyph APIs. You cannot draw pixels using the glyph position & char byte index.

calculate_glyphs here is providing you with positioned glyphs. To draw you use the ab_glyph font to outline_glyph and then OutlinedGlyph::px_bounds & OutlinedGlyph::draw.

For drawing glyphs into an image I would look at the ab_glyph image example

Also see the ab_glyph readme example & docs.