Skip to content

Commit

Permalink
Update to rusttype v0.9.2 (but requires patch)
Browse files Browse the repository at this point in the history
Also removes some unnecessary buffering of positioned glyphs.

The patch required fixes an otherwise inconsolable lifetime issue
related to the positioned glyphs yielded by a font's layout method.
  • Loading branch information
mitchmindtree committed Apr 7, 2021
1 parent 644f1c6 commit 12cb555
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 77 deletions.
3 changes: 2 additions & 1 deletion conrod_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ daggy = "0.5"
fnv = "1.0"
num = "0.2"
pistoncore-input = "1.0.0"
rusttype = { version = "0.8", features = ["gpu_cache"] }
#rusttype = { version = "0.9.2", features = ["gpu_cache"] }
rusttype = { path = "../../rusttype", features = ["gpu_cache"] }
instant = "0.1"
copypasta = "0.6"
13 changes: 9 additions & 4 deletions conrod_core/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Mesh {
glyph_cache_pixel_buffer: Vec<u8>,
commands: Vec<PreparedCommand>,
vertices: Vec<Vertex>,
positioned_glyphs: Vec<text::PositionedGlyph>,
}

/// Represents the scizzor in pixel coordinates.
Expand Down Expand Up @@ -138,11 +139,13 @@ impl Mesh {
let glyph_cache_pixel_buffer = vec![0u8; gc_width as usize * gc_height as usize];
let commands = vec![];
let vertices = vec![];
let positioned_glyphs = vec![];
Mesh {
glyph_cache,
glyph_cache_pixel_buffer,
commands,
vertices,
positioned_glyphs,
}
}

Expand Down Expand Up @@ -170,6 +173,7 @@ impl Mesh {
ref mut glyph_cache_pixel_buffer,
ref mut commands,
ref mut vertices,
ref mut positioned_glyphs,
} = *self;

commands.clear();
Expand Down Expand Up @@ -342,10 +346,11 @@ impl Mesh {
} => {
switch_to_plain_state!();

let positioned_glyphs = text.positioned_glyphs(dpi_factor as f32);
positioned_glyphs.clear();
positioned_glyphs.extend(text.positioned_glyphs(dpi_factor as f32));

// Queue the glyphs to be cached
for glyph in positioned_glyphs {
for glyph in positioned_glyphs.iter() {
glyph_cache.queue_glyph(font_id.index(), glyph.clone());
}

Expand Down Expand Up @@ -384,8 +389,8 @@ impl Mesh {
)) * 2.0,
};

for g in positioned_glyphs {
if let Ok(Some((uv_rect, screen_rect))) = glyph_cache.rect_for(cache_id, g)
for g in positioned_glyphs.drain(..) {
if let Ok(Some((uv_rect, screen_rect))) = glyph_cache.rect_for(cache_id, &g)
{
let vk_rect = to_vk_rect(screen_rect);
let v = |p, t| Vertex {
Expand Down
50 changes: 16 additions & 34 deletions conrod_core/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ pub struct Primitives<'a> {
window_rect: Rect,
/// A buffer to use for triangulating polygons and lines for the `Triangles`.
triangles: Vec<Triangle<Point>>,
/// The slice of rusttype `PositionedGlyph`s to re-use for the `Text` primitive.
positioned_glyphs: Vec<text::PositionedGlyph>,
}

/// An owned alternative to the `Primitives` type.
Expand All @@ -50,7 +48,6 @@ pub struct OwnedPrimitives {
primitives: Vec<OwnedPrimitive>,
triangles_single_color: Vec<Triangle<Point>>,
triangles_multi_color: Vec<Triangle<ColoredPoint>>,
max_glyphs: usize,
line_infos: Vec<text::line::Info>,
texts_string: String,
}
Expand Down Expand Up @@ -157,7 +154,6 @@ pub enum PrimitiveKind<'a> {
/// We produce this type rather than the `&[PositionedGlyph]`s directly so that we can properly
/// handle "HiDPI" scales when caching glyphs.
pub struct Text<'a> {
positioned_glyphs: &'a mut Vec<text::PositionedGlyph>,
window_dim: Dimensions,
text: &'a str,
line_infos: &'a [text::line::Info],
Expand Down Expand Up @@ -221,7 +217,6 @@ pub struct WalkOwnedPrimitives<'a> {
triangles_multi_color: &'a [Triangle<ColoredPoint>],
line_infos: &'a [text::line::Info],
texts_str: &'a str,
positioned_glyphs: Vec<text::PositionedGlyph>,
}

impl<'a> Text<'a> {
Expand All @@ -236,9 +231,9 @@ impl<'a> Text<'a> {
/// out text. This is because conrod positioning uses a "pixel-agnostic" `Scalar` value
/// representing *perceived* distances for its positioning and layout, rather than pixel
/// values. During rendering however, the pixel density must be known
pub fn positioned_glyphs(self, dpi_factor: f32) -> &'a [text::PositionedGlyph] {
pub fn positioned_glyphs(self, dpi_factor: f32)
-> impl 'a + Iterator<Item = rusttype::PositionedGlyph<'static>> {
let Text {
positioned_glyphs,
window_dim,
text,
line_infos,
Expand All @@ -248,31 +243,31 @@ impl<'a> Text<'a> {
justify,
y_align,
line_spacing,
..
} = self;

// Convert conrod coordinates to pixel coordinates.
let trans_x = |x: Scalar| (x + window_dim[0] / 2.0) * dpi_factor as Scalar;
let trans_y = |y: Scalar| ((-y) + window_dim[1] / 2.0) * dpi_factor as Scalar;
let trans_x = move |x: Scalar| (x + window_dim[0] / 2.0) * dpi_factor as Scalar;
let trans_y = move |y: Scalar| ((-y) + window_dim[1] / 2.0) * dpi_factor as Scalar;

// Produce the text layout iterators.
let line_infos = line_infos.iter().cloned();
let lines = line_infos.clone().map(|info| &text[info.byte_range()]);
let lines = line_infos.clone().map(move |info| &text[info.byte_range()]);
let line_rects =
text::line::rects(line_infos, font_size, rect, justify, y_align, line_spacing);

// Clear the existing glyphs and fill the buffer with glyphs for this Text.
positioned_glyphs.clear();
let scale = text::f32_pt_to_scale(font_size as f32 * dpi_factor);
for (line, line_rect) in lines.zip(line_rects) {
let (x, y) = (
trans_x(line_rect.left()) as f32,
trans_y(line_rect.bottom()) as f32,
);
let point = text::rt::Point { x: x, y: y };
positioned_glyphs.extend(font.layout(line, scale, point).map(|g| g.standalone()));
}

positioned_glyphs
lines
.zip(line_rects)
.flat_map(move |(line, line_rect)| {
let (x, y) = (
trans_x(line_rect.left()) as f32,
trans_y(line_rect.bottom()) as f32,
);
let point = text::rt::Point { x: x, y: y };
font.layout(line, scale, point)
})
}
}

Expand All @@ -293,7 +288,6 @@ impl<'a> Primitives<'a> {
fonts: fonts,
window_rect: Rect::from_xy_dim([0.0, 0.0], window_dim),
triangles: Vec::new(),
positioned_glyphs: Vec::new(),
}
}

Expand All @@ -303,7 +297,6 @@ impl<'a> Primitives<'a> {
ref mut crop_stack,
ref mut depth_order,
ref mut triangles,
ref mut positioned_glyphs,
graph,
theme,
fonts,
Expand Down Expand Up @@ -598,7 +591,6 @@ impl<'a> Primitives<'a> {
let y_align = Align::End;

let text = Text {
positioned_glyphs: positioned_glyphs,
window_dim: window_rect.dim(),
text: &state.string,
line_infos: &state.line_infos,
Expand Down Expand Up @@ -652,7 +644,6 @@ impl<'a> Primitives<'a> {
let mut primitive_triangles_single_color = Vec::new();
let mut primitive_line_infos = Vec::new();
let mut texts_string = String::new();
let mut max_glyphs = 0;

while let Some(Primitive {
id,
Expand Down Expand Up @@ -726,10 +717,6 @@ impl<'a> Primitives<'a> {
..
} = text;

// Keep a rough estimate of the maximum number of glyphs so that we know what
// capacity we should allocate the `PositionedGlyph` buffer with.
max_glyphs = std::cmp::max(max_glyphs, text.len());

// Pack the `texts_string`.
let start_str_byte = texts_string.len();
texts_string.push_str(text);
Expand Down Expand Up @@ -769,7 +756,6 @@ impl<'a> Primitives<'a> {
primitives: primitives,
triangles_single_color: primitive_triangles_single_color,
triangles_multi_color: primitive_triangles_multi_color,
max_glyphs: max_glyphs,
line_infos: primitive_line_infos,
texts_string: texts_string,
}
Expand All @@ -785,15 +771,13 @@ impl OwnedPrimitives {
ref triangles_multi_color,
ref line_infos,
ref texts_string,
max_glyphs,
} = *self;
WalkOwnedPrimitives {
primitives: primitives.iter(),
triangles_single_color: triangles_single_color,
triangles_multi_color: triangles_multi_color,
line_infos: line_infos,
texts_str: texts_string,
positioned_glyphs: Vec::with_capacity(max_glyphs),
}
}
}
Expand All @@ -803,7 +787,6 @@ impl<'a> WalkOwnedPrimitives<'a> {
pub fn next(&mut self) -> Option<Primitive> {
let WalkOwnedPrimitives {
ref mut primitives,
ref mut positioned_glyphs,
triangles_single_color,
triangles_multi_color,
line_infos,
Expand Down Expand Up @@ -869,7 +852,6 @@ impl<'a> WalkOwnedPrimitives<'a> {
let line_infos = &line_infos[line_infos_range.clone()];

let text = Text {
positioned_glyphs: positioned_glyphs,
window_dim: window_dim,
text: text_str,
line_infos: line_infos,
Expand Down
42 changes: 5 additions & 37 deletions conrod_core/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ pub mod rt {
pub use rusttype::{gpu_cache, point, vector, Point, Rect, Vector};
}

/// The RustType `FontCollection` type used by conrod.
pub type FontCollection = ::rusttype::FontCollection<'static>;
/// The RustType `Font` type used by conrod.
pub type Font = ::rusttype::Font<'static>;
/// The RustType `PositionedGlyph` type used by conrod.
Expand Down Expand Up @@ -136,7 +134,7 @@ pub mod font {
/// Returned when loading new fonts from file or bytes.
#[derive(Debug)]
pub enum Error {
/// Some error occurred while loading a `FontCollection` from a file.
/// Some error occurred while loading a `Font` from a file.
IO(std::io::Error),
/// No `Font`s could be yielded from the `FontCollection`.
NoFont,
Expand Down Expand Up @@ -181,23 +179,6 @@ pub mod font {
Ok(self.insert(font))
}

// /// Adds each font in the given `rusttype::FontCollection` to the `Map` and returns an
// /// iterator yielding a unique `Id` for each.
// pub fn insert_collection(&mut self, collection: super::FontCollection) -> NewIds {
// let start_index = self.next_index;
// let mut end_index = start_index;
// for index in 0.. {
// match collection.font_at(index) {
// Some(font) => {
// self.insert(font);
// end_index += 1;
// }
// None => break,
// }
// }
// NewIds { index_range: start_index..end_index }
// }

/// Produces an iterator yielding the `Id` for each `Font` within the `Map`.
pub fn ids(&self) -> Ids {
Ids {
Expand All @@ -206,26 +187,13 @@ pub mod font {
}
}

/// Load a `super::FontCollection` from a file at a given path.
pub fn collection_from_file<P>(path: P) -> Result<super::FontCollection, std::io::Error>
where
P: AsRef<std::path::Path>,
{
use std::io::Read;
let path = path.as_ref();
let mut file = std::fs::File::open(path)?;
let mut file_buffer = Vec::new();
file.read_to_end(&mut file_buffer)?;
Ok(super::FontCollection::from_bytes(file_buffer)?)
}

/// Load a single `Font` from a file at the given path.
pub fn from_file<P>(path: P) -> Result<super::Font, Error>
where
P: AsRef<std::path::Path>,
{
let collection = collection_from_file(path)?;
collection.into_font().or(Err(Error::NoFont))
let bytes = std::fs::read(path)?;
super::Font::try_from_vec(bytes).ok_or(Error::NoFont)
}

impl Iterator for NewIds {
Expand Down Expand Up @@ -288,7 +256,7 @@ pub mod glyph {
/// The position of the next `Rect`'s left edge along the *x* axis.
next_left: Scalar,
/// `PositionedGlyphs` yielded by the RustType `LayoutIter`.
layout: super::LayoutIter<'a, 'b>,
layout: super::LayoutIter<'a, 'static, 'b>,
}

/// An iterator that, for every `(line, line_rect)` pair yielded by the given iterator,
Expand Down Expand Up @@ -538,7 +506,7 @@ pub mod cursor {
/// `Xs` iterators are produced by the `XysPerLine` iterator.
pub struct Xs<'a, 'b> {
next_x: Option<Scalar>,
layout: super::LayoutIter<'a, 'b>,
layout: super::LayoutIter<'a, 'static, 'b>,
}

/// An index representing the position of a cursor within some text.
Expand Down
2 changes: 1 addition & 1 deletion conrod_core/src/widget/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ where
line_num += 1;
}
}};
};
}

for axis in lines {
match axis {
Expand Down

0 comments on commit 12cb555

Please sign in to comment.