[epaint] Replace tuple (Rect, Shape) with tuple-struct ClippedShape

This commit is contained in:
Emil Ernerfeldt 2021-01-17 01:35:14 +01:00
parent 7b318887ee
commit 8598c365a1
7 changed files with 37 additions and 27 deletions

View file

@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Center window titles. * Center window titles.
* Tweak size and alignment of some emojis to match other text. * Tweak size and alignment of some emojis to match other text.
* Rename `PaintCmd` to `Shape`. * Rename `PaintCmd` to `Shape`.
* Replace tuple `(Rect, Shape)` with tuple-struct `ClippedShape`.
* Rename feature `"serde"` to `"persistence"`. * Rename feature `"serde"` to `"persistence"`.
* Break out the modules `math` and `paint` into separate crates `emath` and `epaint`. * Break out the modules `math` and `paint` into separate crates `emath` and `epaint`.

View file

@ -596,7 +596,7 @@ impl Context {
/// You can transform the returned shapes into triangles with a call to /// You can transform the returned shapes into triangles with a call to
/// `Context::tessellate`. /// `Context::tessellate`.
#[must_use] #[must_use]
pub fn end_frame(&self) -> (Output, Vec<(Rect, Shape)>) { pub fn end_frame(&self) -> (Output, Vec<ClippedShape>) {
if self.input.wants_repaint() { if self.input.wants_repaint() {
self.request_repaint(); self.request_repaint();
} }
@ -613,13 +613,13 @@ impl Context {
(output, shapes) (output, shapes)
} }
fn drain_paint_lists(&self) -> Vec<(Rect, Shape)> { fn drain_paint_lists(&self) -> Vec<ClippedShape> {
let memory = self.memory(); let memory = self.memory();
self.graphics().drain(memory.areas.order()).collect() self.graphics().drain(memory.areas.order()).collect()
} }
/// Tessellate the given shapes into triangle meshes. /// Tessellate the given shapes into triangle meshes.
pub fn tessellate(&self, shapes: Vec<(Rect, Shape)>) -> PaintJobs { pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> PaintJobs {
let mut tessellation_options = self.memory().options.tessellation_options; let mut tessellation_options = self.memory().options.tessellation_options;
tessellation_options.aa_size = 1.0 / self.pixels_per_point(); tessellation_options.aa_size = 1.0 / self.pixels_per_point();
let paint_stats = PaintStats::from_shapes(&shapes); // TODO: internal allocations let paint_stats = PaintStats::from_shapes(&shapes); // TODO: internal allocations

View file

@ -1,6 +1,6 @@
use crate::{math::Rect, Id, *};
use epaint::ahash::AHashMap; use epaint::ahash::AHashMap;
use epaint::{ClippedShape, Shape};
use crate::{math::Rect, paint::Shape, Id, *};
/// Different layer categories /// Different layer categories
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
@ -76,7 +76,7 @@ pub struct ShapeIdx(usize);
/// A list of [`Shape`]s paired with a clip rectangle. /// A list of [`Shape`]s paired with a clip rectangle.
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct PaintList(Vec<(Rect, Shape)>); pub struct PaintList(Vec<ClippedShape>);
impl PaintList { impl PaintList {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
@ -86,13 +86,13 @@ impl PaintList {
/// Returns the index of the new [`Shape`] that can be used with `PaintList::set`. /// Returns the index of the new [`Shape`] that can be used with `PaintList::set`.
pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx { pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx {
let idx = ShapeIdx(self.0.len()); let idx = ShapeIdx(self.0.len());
self.0.push((clip_rect, shape)); self.0.push(ClippedShape(clip_rect, shape));
idx idx
} }
pub fn extend(&mut self, clip_rect: Rect, mut shapes: Vec<Shape>) { pub fn extend(&mut self, clip_rect: Rect, mut shapes: Vec<Shape>) {
self.0 self.0
.extend(shapes.drain(..).map(|shape| (clip_rect, shape))) .extend(shapes.drain(..).map(|shape| ClippedShape(clip_rect, shape)))
} }
/// Modify an existing [`Shape`]. /// Modify an existing [`Shape`].
@ -104,12 +104,12 @@ impl PaintList {
/// and then later setting it using `paint_list.set(idx, cr, frame);`. /// and then later setting it using `paint_list.set(idx, cr, frame);`.
pub fn set(&mut self, idx: ShapeIdx, clip_rect: Rect, shape: Shape) { pub fn set(&mut self, idx: ShapeIdx, clip_rect: Rect, shape: Shape) {
assert!(idx.0 < self.0.len()); assert!(idx.0 < self.0.len());
self.0[idx.0] = (clip_rect, shape); self.0[idx.0] = ClippedShape(clip_rect, shape);
} }
/// Translate each [`Shape`] and clip rectangle by this much, in-place /// Translate each [`Shape`] and clip rectangle by this much, in-place
pub fn translate(&mut self, delta: Vec2) { pub fn translate(&mut self, delta: Vec2) {
for (clip_rect, shape) in &mut self.0 { for ClippedShape(clip_rect, shape) in &mut self.0 {
*clip_rect = clip_rect.translate(delta); *clip_rect = clip_rect.translate(delta);
shape.translate(delta); shape.translate(delta);
} }
@ -126,10 +126,7 @@ impl GraphicLayers {
.or_default() .or_default()
} }
pub fn drain( pub fn drain(&mut self, area_order: &[LayerId]) -> impl ExactSizeIterator<Item = ClippedShape> {
&mut self,
area_order: &[LayerId],
) -> impl ExactSizeIterator<Item = (Rect, Shape)> {
let mut all_shapes: Vec<_> = Default::default(); let mut all_shapes: Vec<_> = Default::default();
for &order in &Order::ALL { for &order in &Order::ALL {

View file

@ -61,7 +61,7 @@ pub use {
shape::Shape, shape::Shape,
stats::PaintStats, stats::PaintStats,
stroke::Stroke, stroke::Stroke,
tessellator::{PaintJob, PaintJobs, TessellationOptions}, tessellator::TessellationOptions,
text::{Galley, TextStyle}, text::{Galley, TextStyle},
texture_atlas::{Texture, TextureAtlas}, texture_atlas::{Texture, TextureAtlas},
triangles::{Triangles, Vertex}, triangles::{Triangles, Vertex},
@ -101,3 +101,21 @@ pub(crate) struct PaintRect {
pub fill: Color32, pub fill: Color32,
pub stroke: Stroke, pub stroke: Stroke,
} }
/// A [`Shape`] within a clip rectangle.
///
/// Everything is using logical points.
#[derive(Clone, Debug)]
pub struct ClippedShape(
/// Clip / scissor rectangle.
/// Only show the part of the [`shape`] that falls within this.
pub emath::Rect,
/// The shape
pub Shape,
);
/// A clip triangle and some textured triangles, all in points (logical pixels).
pub type PaintJob = (emath::Rect, Triangles);
/// Grouped by clip rectangles, in points (logical pixels).
pub type PaintJobs = Vec<PaintJob>;

View file

@ -1,4 +1,4 @@
use {crate::*, emath::*}; use crate::*;
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
enum ElementSize { enum ElementSize {
@ -146,13 +146,13 @@ pub struct PaintStats {
} }
impl PaintStats { impl PaintStats {
pub fn from_shapes(shapes: &[(Rect, Shape)]) -> Self { pub fn from_shapes(shapes: &[ClippedShape]) -> Self {
let mut stats = Self::default(); let mut stats = Self::default();
stats.shape_path.element_size = ElementSize::Heterogenous; // nicer display later stats.shape_path.element_size = ElementSize::Heterogenous; // nicer display later
stats.shape_vec.element_size = ElementSize::Heterogenous; // nicer display later stats.shape_vec.element_size = ElementSize::Heterogenous; // nicer display later
stats.shapes = AllocInfo::from_slice(shapes); stats.shapes = AllocInfo::from_slice(shapes);
for (_, shape) in shapes { for ClippedShape(_, shape) in shapes {
stats.add(shape); stats.add(shape);
} }
stats stats

View file

@ -9,12 +9,6 @@ use crate::{text::Fonts, *};
use emath::*; use emath::*;
use std::f32::consts::TAU; use std::f32::consts::TAU;
/// A clip triangle and some textured triangles.
pub type PaintJob = (Rect, Triangles);
/// Grouped by clip rectangles, in pixel coordinates
pub type PaintJobs = Vec<PaintJob>;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -670,14 +664,14 @@ impl Tessellator {
/// ## Returns /// ## Returns
/// A list of clip rectangles with matching [`Triangles`]. /// A list of clip rectangles with matching [`Triangles`].
pub fn tessellate_shapes( pub fn tessellate_shapes(
shapes: Vec<(Rect, Shape)>, shapes: Vec<ClippedShape>,
options: TessellationOptions, options: TessellationOptions,
fonts: &Fonts, fonts: &Fonts,
) -> Vec<(Rect, Triangles)> { ) -> Vec<(Rect, Triangles)> {
let mut tessellator = Tessellator::from_options(options); let mut tessellator = Tessellator::from_options(options);
let mut jobs = PaintJobs::default(); let mut jobs = PaintJobs::default();
for (clip_rect, shape) in shapes { for ClippedShape(clip_rect, shape) in shapes {
let start_new_job = match jobs.last() { let start_new_job = match jobs.last() {
None => true, None => true,
Some(job) => job.0 != clip_rect || job.1.texture_id != shape.texture_id(), Some(job) => job.0 != clip_rect || job.1.texture_id != shape.texture_id(),

View file

@ -29,7 +29,7 @@ pub struct Triangles {
/// The vertex data indexed by `indices`. /// The vertex data indexed by `indices`.
pub vertices: Vec<Vertex>, pub vertices: Vec<Vertex>,
/// The texture to use when drawing these triangles /// The texture to use when drawing these triangles.
pub texture_id: TextureId, pub texture_id: TextureId,
} }