gpu_cache::Cache returning incorrectly positioned rects
Hello,
I'm having some issues using the gpu caching feature. I have followed the example very closely, and I almost have everything working, but the vertical positions of the screen_rect
s that I am getting back seem to be incorrect.
Here is a screenshot of rendering the string ba, ye'
(to demonstrate weird comma and apostrophe placement)
And here is a screenshot of me explicitly using 0 as the y position, and ignoring the returned screen_rect.min.y. This works better, but still isn't quite correct. It looks like there are some minor height differences between characters that should be sitting next to each other, and the comma isn't placed below the line correctly.
This is the code that I use to layout the glyphs, it is very similar to the code in the example, except this is just for a single line, not an entire paragraph or multiple lines:
fn layout_text(&self, text: &str, size: f32) -> Vec<PositionedGlyph<'static>> {
use unicode_normalization::UnicodeNormalization;
let mut glyphs: Vec<PositionedGlyph> = Vec::new();
let scale = Scale::uniform(size);
let v_metrics = self.rt_font.v_metrics(scale);
let mut caret = point(0.0, v_metrics.ascent);
let mut last_glyph_id: Option<GlyphId> = None;
for c in text.nfc() {
if c.is_control() {
// TODO
// Support newlines and other control characters
continue;
}
let base_glyph = self.rt_font.glyph(c).standalone();
if let Some(id) = last_glyph_id.take() {
caret.x += self.rt_font.pair_kerning(scale, id, base_glyph.id());
}
last_glyph_id = Some(base_glyph.id());
let mut final_glyph = base_glyph.scaled(scale).positioned(caret);
caret.x += final_glyph.unpositioned().h_metrics().advance_width;
glyphs.push(final_glyph);
}
glyphs
}
After laying out with this function, each glyph should have the same y position (v_metrics.ascent) because I never move the caret up or down when doing positioning. But after caching these glyphs, and retrieving them from the cache with rect_for, that is no longer the case and each glyph is given an incorrect y position.
Here's the code that I use to turn the rusttype::Rect into my own rect struct, right before rendering:
for glyph in &glyphs {
if let Ok(Some((uv_rect, screen_rect))) = self.rt_cache.rect_for(0, glyph) {
let uv_rect = Rect::new(uv_rect.min.x as f32, uv_rect.min.y as f32, uv_rect.width() as f32, uv_rect.height() as f32);
let screen_rect = Rect::new(screen_rect.min.x as f32, screen_rect.min.y as f32, screen_rect.width() as f32, screen_rect.height() as f32);
rects.push((uv_rect, screen_rect));
}
}