diff --git a/epaint/src/shape.rs b/epaint/src/shape.rs index 1409bfb4444..3a72bc32488 100644 --- a/epaint/src/shape.rs +++ b/epaint/src/shape.rs @@ -13,6 +13,11 @@ pub use crate::{CubicBezierShape, QuadraticBezierShape}; /// A paint primitive such as a circle or a piece of text. /// Coordinates are all screen space points (not physical pixels). +/// +/// You should generally recreate your [`Shape`]s each frame, +/// but storing them should also be fine with one exception: +/// [`Shape::Text`] depends on the current `pixels_per_point` (dpi scale) +/// and so must be recreated every time `pixels_per_point` changes. #[must_use = "Add a Shape to a Painter"] #[derive(Clone, Debug, PartialEq)] pub enum Shape { @@ -37,6 +42,8 @@ pub enum Shape { Rect(RectShape), /// Text. + /// + /// This needs to be recreated if `pixels_per_point` (dpi scale) changes. Text(TextShape), /// A general triangle mesh. @@ -604,6 +611,8 @@ impl Rounding { // ---------------------------------------------------------------------------- /// How to paint some text on screen. +/// +/// This needs to be recreated if `pixels_per_point` (dpi scale) changes. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct TextShape { diff --git a/epaint/src/tessellator.rs b/epaint/src/tessellator.rs index 32826f4ee84..7eb4089df01 100644 --- a/epaint/src/tessellator.rs +++ b/epaint/src/tessellator.rs @@ -1334,6 +1334,11 @@ impl Tessellator { return; } + if galley.pixels_per_point != self.pixels_per_point { + eprintln!("epaint: WARNING: pixels_per_point (dpi scale) have changed between text layout and tessellation. \ + You must recreate your text shapes if pixels_per_point changes."); + } + out.vertices.reserve(galley.num_vertices); out.indices.reserve(galley.num_indices); diff --git a/epaint/src/text/text_layout.rs b/epaint/src/text/text_layout.rs index 3b2220912ac..801ea3ec8dc 100644 --- a/epaint/src/text/text_layout.rs +++ b/epaint/src/text/text_layout.rs @@ -478,6 +478,7 @@ fn galley_from_rows(point_scale: PointScale, job: Arc, mut rows: Vec< mesh_bounds, num_vertices, num_indices, + pixels_per_point: point_scale.pixels_per_point, } } diff --git a/epaint/src/text/text_layout_types.rs b/epaint/src/text/text_layout_types.rs index 830acb842c9..07472e23a69 100644 --- a/epaint/src/text/text_layout_types.rs +++ b/epaint/src/text/text_layout_types.rs @@ -309,6 +309,8 @@ impl Default for TextWrapping { /// Text that has been layed out, ready for painting. /// /// You can create a [`Galley`] using [`crate::Fonts::layout_job`]; +/// +/// This needs to be recreated if `pixels_per_point` (dpi scale) changes. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Galley { @@ -341,6 +343,12 @@ pub struct Galley { /// Total number of indices in all the row meshes. pub num_indices: usize, + + /// The number of physical pixels for each logical point. + /// Since this affects the layout, we keep track of it + /// so that we can warn if this has changed once we get to + /// tessellation. + pub pixels_per_point: f32, } #[derive(Clone, Debug, PartialEq)]