Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text extents says y size is 0 #633

Closed
jgarvin opened this issue Jun 24, 2020 · 3 comments · Fixed by #642
Closed

Text extents says y size is 0 #633

jgarvin opened this issue Jun 24, 2020 · 3 comments · Fixed by #642
Labels
bug Some API breaks the contract it establishes subsystem-graphics

Comments

@jgarvin
Copy link

jgarvin commented Jun 24, 2020

Describe the bug
layout_glyphs sometimes returns a Vector with y value 0. I'm not sure why. The demo below renders random fragments of lorem ipsum, trying to move all the older fragments up each time to make room for the new fragment at the bottom. The dbg!() macro logs the extents returned by layout_glyphs. Notice I do old_chunk.position.y -= chunk.size.y + 50.0; instead of old_chunk.position.y -= chunk.size.y; because otherwise the zero y size causes the text to bunch up.

This doesn't seem to be a web issue, happens with regular Linux too. I see it either giving y=7 or y=0, not sure how it decides:

[game/src/main.rs:132] chunk.size = Vector {
    x: 48.71034,
    y: 0.0,
}
[game/src/main.rs:132] chunk.text.len() = 3
[game/src/main.rs:132] &chunk.text = "lab"

To Reproduce

EDIT: don't use this, see repo link in my next comment

#![deny(unused_must_use)] // otherwise can ignore errors from void functions
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]

use quicksilver::{
    geom::{Circle, Rectangle, Vector},
    graphics::{Color, FontRenderer, Image, PixelFormat, Surface, VectorFont},
    run, Graphics, Input, Result, Settings, Window,
};

fn main() {
    run(
        Settings {
            size: Vector::new(600.0, 480.0),
            title: "AGame",
            ..Settings::default()
        },
        app,
    );
}

struct RenderTools<'a> {
    gfx: &'a mut Graphics,
    font: &'a mut FontRenderer,
    size: Vector,
}

struct TextChunk {
    position: Vector,
    size: Vector,
    text: String,
}

impl TextChunk {
    fn new(render_tools: &mut RenderTools, text: String) -> Result<TextChunk> {
        let mut chunk = TextChunk {
            position: Vector::new(0.0, 0.0),
            size: Vector::new(0.0, 0.0),
            text: text,
        };
        chunk.size = render_tools.font.layout_glyphs(
            render_tools.gfx,
            &chunk.text,
            None,
            |gfx, layout| {},
        )?;
        dbg!(chunk.size, chunk.text.len(), &chunk.text);
        return Ok(chunk);
    }

    fn render(&mut self, render_tools: &mut RenderTools) -> Result<()> {
        self.size = render_tools.font.draw(
            render_tools.gfx,
            &*self.text,
            //            render_tools.size.x.into(),
            Color::BLACK,
            self.position,
        )?;
        Ok(())
    }
}

#[derive(Default)]
struct TextWindow {
    position: Vector,
    history: Vec<TextChunk>,
}

impl TextWindow {
    fn render(&mut self, render_tools: &mut RenderTools) -> Result<()> {
        for chunk in &mut self.history {
            chunk.render(render_tools)?;
        }
        Ok(())
    }

    fn append(&mut self, mut chunk: TextChunk) -> () {
        for old_chunk in &mut self.history {
            old_chunk.position.y -= chunk.size.y + 50.0;
        }
        //        while !self.history.is_empty() && self.history[0].position.y + self.history[0].size.y < 0.0 {
        //            self.history.remove(0);
        //        }
        while self.history.len() > 30 {
            self.history.remove(0);
        }
        chunk.position.y += 500.0;
        self.history.push(chunk);
    }
}

use stdweb::console;

async fn app(window: Window, mut gfx: Graphics, mut input: Input) -> Result<()> {
    let demo_text = "Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.Duisauteiruredolorinreprehenderitinvoluptatevelitessecillumdoloreeufugiatnullapariatur.Excepteursintoccaecatcupidatatnonproident,suntinculpaquiofficiadeseruntmollitanimidestlaborum.";

    let rect = Rectangle::new(Vector::new(350.0, 100.0), Vector::new(100.0, 100.0));
    let ttf = VectorFont::load("font.ttf").await?;

    let mut font = ttf.to_renderer(&gfx, 32.0)?;
    gfx.fit_to_window(&window);

    let mut render_tools = RenderTools {
        gfx: &mut gfx,
        font: &mut font,
        size: window.size().clone(),
    };
    let mut text_window = TextWindow::default();
    let mut i: u32 = 0;
    use rand::rngs::StdRng;
    use rand::Rng;
    use rand::SeedableRng;
    #[rustfmt::skip]
    let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
                0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];

    let mut rng = StdRng::from_seed(seed);
    loop {
        while let Some(_) = input.next_event().await {}
        render_tools.gfx.clear(Color::WHITE);
        text_window.render(&mut render_tools)?;
        i += 1;
        //        console!(log, "wtf?");
        if i % 10 == 0 {
            let start = rng.gen_range(0, demo_text.len());
            let finish = rng.gen_range(start, demo_text.len());
            let slice = demo_text[start..finish].trim();
            //            dbg!();
            //            dbg!(slice.len());
            let chunk = TextChunk::new(&mut render_tools, slice.into()).unwrap();
            text_window.append(chunk);
        }
        render_tools.gfx.present(&window)?;
    }
}

Environment and versions (please complete the following information):
Environment: Ubuntu 19.10, Chrome Version 81.0.4044.138 (Official Build) (64-bit)
Rust compiler version: rustc 1.44.0 (49cae5576 2020-06-01)
Quicksilver verison: quicksilver = "0.4.0-alpha0.5"

@jgarvin
Copy link
Author

jgarvin commented Jun 24, 2020

Sorry here is a full yet more minimal test case: https://github.com/jgarvin/txtbug

In making it I discovered it depends on using my specific font. If you get rid of the break statement in main you will actually get to see it render though, and it definitely renders with nonzero y size.

@jgarvin
Copy link
Author

jgarvin commented Jun 24, 2020

With the examples font, the y sizes still seem wrong, just not zero:

[game/src/main.rs:50] chunk.size = Vector {
    x: 113.84375,
    y: 1.0,
}
[game/src/main.rs:50] chunk.text.len() = 7
[game/src/main.rs:50] &chunk.text = "adeseru"

[game/src/main.rs:50] chunk.size = Vector {
    x: 2098.7344,
    y: 8.0,
}
[game/src/main.rs:50] chunk.text.len() = 147
[game/src/main.rs:50] &chunk.text = "orinreprehenderitinvoluptatevelitessecillumdoloreeufugiatnullapariatur.Excepteursintoccaecatcupidatatnonproident,suntinculpaquiofficiadeseruntmolli"

[game/src/main.rs:50] chunk.size = Vector {
    x: 1701.9063,
    y: 7.0,
}
[game/src/main.rs:50] chunk.text.len() = 112
[game/src/main.rs:50] &chunk.text = "iqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.Duisauteiruredol"

These are all rendered from the same font object, and I'm using draw rather than draw_wrapping, so I'd expect their y extents to always be the same, or maybe differ a little because of letters that drop below the horizontal line like 'p', but it says the first string is 1/8th the height of the second string which seems too dramatic. Also assuming the unit is pixels, the rendering is clearly more than 1 pixel high :)

@ryanisaacg ryanisaacg added bug Some API breaks the contract it establishes subsystem-graphics labels Jun 24, 2020
@ryanisaacg
Copy link
Owner

This seems like the same issue as #607; I hope that I will be able to replicate this one!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Some API breaks the contract it establishes subsystem-graphics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants