mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 10:44:56 +03:00
woohoo, dismantle screenspace glyphs entirely
This commit is contained in:
parent
7f0539bcac
commit
234689533a
@ -1,17 +1,11 @@
|
||||
use crate::{ScreenDims, ScreenPt, Text};
|
||||
use glium::Rect;
|
||||
use glium_glyph::glyph_brush::rusttype::{Font, Scale};
|
||||
use glium_glyph::glyph_brush::{FontId, GlyphCruncher};
|
||||
use crate::{ScreenDims, Text};
|
||||
use glium_glyph::glyph_brush::FontId;
|
||||
use glium_glyph::{GlyphBrush, GlyphBrushBuilder};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// TODO We don't need refcell maybe
|
||||
pub struct Assets {
|
||||
pub screenspace_glyphs: RefCell<GlyphBrush<'static, 'static>>,
|
||||
pub mapspace_glyphs: RefCell<GlyphBrush<'static, 'static>>,
|
||||
pub screenspace_clip_glyphs: RefCell<Option<(Rect, Vec<(ScreenPt, Text, ScreenDims)>)>>,
|
||||
line_height_per_font_size: RefCell<HashMap<(FontId, usize), f64>>,
|
||||
pub default_line_height: f64,
|
||||
pub font_size: usize,
|
||||
}
|
||||
@ -19,16 +13,6 @@ pub struct Assets {
|
||||
impl Assets {
|
||||
pub fn new(display: &glium::Display, font_size: usize) -> Assets {
|
||||
let dejavu: &[u8] = include_bytes!("assets/DejaVuSans.ttf");
|
||||
let roboto: &[u8] = include_bytes!("assets/Roboto-Regular.ttf");
|
||||
let roboto_bold: &[u8] = include_bytes!("assets/Roboto-Bold.ttf");
|
||||
let screenspace_glyphs = GlyphBrush::new(
|
||||
display,
|
||||
vec![
|
||||
Font::from_bytes(dejavu).unwrap(),
|
||||
Font::from_bytes(roboto).unwrap(),
|
||||
Font::from_bytes(roboto_bold).unwrap(),
|
||||
],
|
||||
);
|
||||
let mapspace_glyphs = GlyphBrushBuilder::using_font_bytes(dejavu)
|
||||
.params(glium::DrawParameters {
|
||||
blend: glium::Blend::alpha_blending(),
|
||||
@ -42,10 +26,7 @@ impl Assets {
|
||||
.build(display);
|
||||
|
||||
let mut a = Assets {
|
||||
screenspace_glyphs: RefCell::new(screenspace_glyphs),
|
||||
mapspace_glyphs: RefCell::new(mapspace_glyphs),
|
||||
screenspace_clip_glyphs: RefCell::new(None),
|
||||
line_height_per_font_size: RefCell::new(HashMap::new()),
|
||||
default_line_height: 0.0,
|
||||
font_size,
|
||||
};
|
||||
@ -58,17 +39,8 @@ impl Assets {
|
||||
}
|
||||
|
||||
// Don't call this while screenspace_glyphs is mutably borrowed.
|
||||
pub fn line_height(&self, font: FontId, font_size: usize) -> f64 {
|
||||
let mut hash = self.line_height_per_font_size.borrow_mut();
|
||||
let key = (font, font_size);
|
||||
if hash.contains_key(&key) {
|
||||
return hash[&key];
|
||||
}
|
||||
let vmetrics = self.screenspace_glyphs.borrow().fonts()[font.0]
|
||||
.v_metrics(Scale::uniform(font_size as f32));
|
||||
// TODO This works for this font, but could be more paranoid with abs()
|
||||
let line_height = f64::from(vmetrics.ascent - vmetrics.descent + vmetrics.line_gap);
|
||||
hash.insert(key, line_height);
|
||||
line_height
|
||||
pub fn line_height(&self, _: FontId, font_size: usize) -> f64 {
|
||||
// TODO Ahhh this stops working.
|
||||
font_size as f64
|
||||
}
|
||||
}
|
||||
|
@ -230,11 +230,6 @@ impl<'a> LoadingScreen<'a> {
|
||||
&txt,
|
||||
(HorizontalAlignment::Center, VerticalAlignment::Center),
|
||||
);
|
||||
self.assets
|
||||
.screenspace_glyphs
|
||||
.borrow_mut()
|
||||
.draw_queued(self.prerender.display, &mut target);
|
||||
// LoadingScreen doesn't use mapspace_glyphs
|
||||
target.finish().unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -159,33 +159,6 @@ impl<G: GUI> State<G> {
|
||||
.borrow_mut()
|
||||
.draw_queued_with_transform(transform, display, g.target);
|
||||
}
|
||||
// The depth buffer doesn't seem to work between mapspace_glyphs and screenspace_glyphs. :\
|
||||
// So draw screenspace_glyphs last.
|
||||
{
|
||||
let transform = ortho(
|
||||
(0.0, self.canvas.window_width as f32),
|
||||
(0.0, self.canvas.window_height as f32),
|
||||
1.0,
|
||||
);
|
||||
self.assets
|
||||
.screenspace_glyphs
|
||||
.borrow_mut()
|
||||
.draw_queued_with_transform(transform, display, g.target);
|
||||
|
||||
// And the clipping version.
|
||||
if let Some((rect, list)) = self.assets.screenspace_clip_glyphs.borrow_mut().take() {
|
||||
g.params.scissor = Some(rect.clone());
|
||||
for (pt, txt, dims) in list {
|
||||
text::draw_text_bubble(&mut g, pt, &txt, dims, false);
|
||||
}
|
||||
g.params.scissor = None;
|
||||
|
||||
let mut glyphs = self.assets.screenspace_glyphs.borrow_mut();
|
||||
glyphs.params.scissor = Some(rect);
|
||||
glyphs.draw_queued_with_transform(transform, display, g.target);
|
||||
glyphs.params.scissor = None;
|
||||
}
|
||||
}
|
||||
|
||||
target.finish().unwrap();
|
||||
naming_hint
|
||||
|
@ -196,82 +196,6 @@ impl Text {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_text_bubble(
|
||||
g: &mut GfxCtx,
|
||||
top_left: ScreenPt,
|
||||
txt: &Text,
|
||||
// Callers almost always calculate this anyway
|
||||
total_dims: ScreenDims,
|
||||
defer_clipping: bool,
|
||||
) -> ScreenRectangle {
|
||||
// TODO Such nonsense.
|
||||
if g.params.scissor.is_some() && defer_clipping {
|
||||
let mut defer = g.assets.screenspace_clip_glyphs.borrow_mut();
|
||||
if let Some((ref rect, ref mut list)) = *defer {
|
||||
assert_eq!(rect, g.params.scissor.as_ref().unwrap());
|
||||
list.push((top_left, txt.clone(), total_dims));
|
||||
} else {
|
||||
*defer = Some((
|
||||
g.params.scissor.clone().unwrap(),
|
||||
vec![(top_left, txt.clone(), total_dims)],
|
||||
));
|
||||
}
|
||||
return ScreenRectangle::top_left(top_left, total_dims);
|
||||
}
|
||||
|
||||
// TODO Is it expensive to constantly change uniforms and the shader program?
|
||||
g.fork_screenspace();
|
||||
|
||||
if let Some(c) = txt.bg_color {
|
||||
g.draw_polygon(
|
||||
c,
|
||||
&Polygon::rectangle(total_dims.width, total_dims.height)
|
||||
.translate(top_left.x, top_left.y),
|
||||
);
|
||||
}
|
||||
|
||||
let mut y = top_left.y;
|
||||
for (line_color, line) in &txt.lines {
|
||||
let mut max_size = 0;
|
||||
let section = VariedSection {
|
||||
screen_position: (top_left.x as f32, y as f32),
|
||||
z: 0.5,
|
||||
text: line
|
||||
.iter()
|
||||
.map(|span| {
|
||||
max_size = max_size.max(span.size.unwrap_or(g.assets.font_size));
|
||||
SectionText {
|
||||
text: &span.text,
|
||||
color: match span.fg_color {
|
||||
Color::RGBA(r, g, b, a) => [r, g, b, a],
|
||||
_ => unreachable!(),
|
||||
},
|
||||
scale: Scale::uniform(span.size.unwrap_or(g.assets.font_size) as f32),
|
||||
..SectionText::default()
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
..VariedSection::default()
|
||||
};
|
||||
// TODO Assume the same font for all spans
|
||||
let height = g.line_height(line[0].font, max_size);
|
||||
|
||||
if let Some(c) = line_color {
|
||||
g.draw_polygon(
|
||||
*c,
|
||||
&Polygon::rectangle(total_dims.width, height).translate(top_left.x, y),
|
||||
);
|
||||
}
|
||||
|
||||
y += height;
|
||||
g.assets.screenspace_glyphs.borrow_mut().queue(section);
|
||||
}
|
||||
|
||||
g.unfork();
|
||||
|
||||
ScreenRectangle::top_left(top_left, total_dims)
|
||||
}
|
||||
|
||||
pub fn draw_text_bubble_mapspace(
|
||||
g: &mut GfxCtx,
|
||||
top_left: Pt2D,
|
||||
|
Loading…
Reference in New Issue
Block a user