summaryrefslogtreecommitdiffstats
path: root/graphics/src/primitive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/primitive.rs')
-rw-r--r--graphics/src/primitive.rs176
1 files changed, 9 insertions, 167 deletions
diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs
index 187c6c6c..7592a410 100644
--- a/graphics/src/primitive.rs
+++ b/graphics/src/primitive.rs
@@ -1,19 +1,15 @@
//! Draw using different graphical primitives.
-use crate::color;
use crate::core::alignment;
use crate::core::image;
use crate::core::svg;
use crate::core::text;
-use crate::core::{Background, Color, Font, Rectangle, Size, Vector};
-use crate::gradient;
+use crate::core::{Background, Color, Font, Rectangle, Vector};
-use bytemuck::{Pod, Zeroable};
use std::sync::Arc;
/// A rendering primitive.
#[derive(Debug, Clone, PartialEq)]
-#[non_exhaustive]
-pub enum Primitive {
+pub enum Primitive<T> {
/// A text primitive
Text {
/// The contents of the text
@@ -66,65 +62,17 @@ pub enum Primitive {
/// The bounds of the viewport
bounds: Rectangle,
},
- /// A low-level primitive to render a mesh of triangles with a solid color.
- ///
- /// It can be used to render many kinds of geometry freely.
- SolidMesh {
- /// The vertices and indices of the mesh.
- buffers: Mesh2D<ColoredVertex2D>,
-
- /// The size of the drawable region of the mesh.
- ///
- /// Any geometry that falls out of this region will be clipped.
- size: Size,
- },
- /// A low-level primitive to render a mesh of triangles with a gradient.
- ///
- /// It can be used to render many kinds of geometry freely.
- GradientMesh {
- /// The vertices and indices of the mesh.
- buffers: Mesh2D<GradientVertex2D>,
-
- /// The size of the drawable region of the mesh.
- ///
- /// Any geometry that falls out of this region will be clipped.
- size: Size,
- },
- /// A [`tiny_skia`] path filled with some paint.
- #[cfg(feature = "tiny-skia")]
- Fill {
- /// The path to fill.
- path: tiny_skia::Path,
- /// The paint to use.
- paint: tiny_skia::Paint<'static>,
- /// The fill rule to follow.
- rule: tiny_skia::FillRule,
- /// The transform to apply to the path.
- transform: tiny_skia::Transform,
- },
- /// A [`tiny_skia`] path stroked with some paint.
- #[cfg(feature = "tiny-skia")]
- Stroke {
- /// The path to stroke.
- path: tiny_skia::Path,
- /// The paint to use.
- paint: tiny_skia::Paint<'static>,
- /// The stroke settings.
- stroke: tiny_skia::Stroke,
- /// The transform to apply to the path.
- transform: tiny_skia::Transform,
- },
/// A group of primitives
Group {
/// The primitives of the group
- primitives: Vec<Primitive>,
+ primitives: Vec<Primitive<T>>,
},
/// A clip primitive
Clip {
/// The bounds of the clip
bounds: Rectangle,
/// The content of the clip
- content: Box<Primitive>,
+ content: Box<Primitive<T>>,
},
/// A primitive that applies a translation
Translate {
@@ -132,7 +80,7 @@ pub enum Primitive {
translation: Vector,
/// The primitive to translate
- content: Box<Primitive>,
+ content: Box<Primitive<T>>,
},
/// A cached primitive.
///
@@ -140,11 +88,13 @@ pub enum Primitive {
/// generation is expensive.
Cache {
/// The cached primitive
- content: Arc<Primitive>,
+ content: Arc<Primitive<T>>,
},
+ /// A backend-specific primitive.
+ Custom(T),
}
-impl Primitive {
+impl<T> Primitive<T> {
/// Creates a [`Primitive::Group`].
pub fn group(primitives: Vec<Self>) -> Self {
Self::Group { primitives }
@@ -165,112 +115,4 @@ impl Primitive {
content: Box::new(self),
}
}
-
- /// Returns the bounds of the [`Primitive`].
- pub fn bounds(&self) -> Rectangle {
- match self {
- Self::Text {
- bounds,
- horizontal_alignment,
- vertical_alignment,
- ..
- } => {
- let mut bounds = *bounds;
-
- bounds.x = match horizontal_alignment {
- alignment::Horizontal::Left => bounds.x,
- alignment::Horizontal::Center => {
- bounds.x - bounds.width / 2.0
- }
- alignment::Horizontal::Right => bounds.x - bounds.width,
- };
-
- bounds.y = match vertical_alignment {
- alignment::Vertical::Top => bounds.y,
- alignment::Vertical::Center => {
- bounds.y - bounds.height / 2.0
- }
- alignment::Vertical::Bottom => bounds.y - bounds.height,
- };
-
- bounds.expand(1.5)
- }
- Self::Quad { bounds, .. }
- | Self::Image { bounds, .. }
- | Self::Svg { bounds, .. } => bounds.expand(1.0),
- Self::Clip { bounds, .. } => bounds.expand(1.0),
- Self::SolidMesh { size, .. } | Self::GradientMesh { size, .. } => {
- Rectangle::with_size(*size)
- }
- #[cfg(feature = "tiny-skia")]
- Self::Fill { path, .. } | Self::Stroke { path, .. } => {
- let bounds = path.bounds();
-
- Rectangle {
- x: bounds.x(),
- y: bounds.y(),
- width: bounds.width(),
- height: bounds.height(),
- }
- .expand(1.0)
- }
- Self::Group { primitives } => primitives
- .iter()
- .map(Self::bounds)
- .fold(Rectangle::with_size(Size::ZERO), |a, b| {
- Rectangle::union(&a, &b)
- }),
- Self::Translate {
- translation,
- content,
- } => content.bounds() + *translation,
- Self::Cache { content } => content.bounds(),
- }
- }
-}
-
-/// A set of [`Vertex2D`] and indices representing a list of triangles.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct Mesh2D<T> {
- /// The vertices of the mesh
- pub vertices: Vec<T>,
-
- /// The list of vertex indices that defines the triangles of the mesh.
- ///
- /// Therefore, this list should always have a length that is a multiple of 3.
- pub indices: Vec<u32>,
-}
-
-/// A two-dimensional vertex with a color.
-#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
-#[repr(C)]
-pub struct ColoredVertex2D {
- /// The vertex position in 2D space.
- pub position: [f32; 2],
-
- /// The color of the vertex in __linear__ RGBA.
- pub color: color::Packed,
-}
-
-/// A vertex which contains 2D position & packed gradient data.
-#[derive(Copy, Clone, Debug, PartialEq)]
-#[repr(C)]
-pub struct GradientVertex2D {
- /// The vertex position in 2D space.
- pub position: [f32; 2],
-
- /// The packed vertex data of the gradient.
- pub gradient: gradient::Packed,
-}
-
-#[allow(unsafe_code)]
-unsafe impl Zeroable for GradientVertex2D {}
-
-#[allow(unsafe_code)]
-unsafe impl Pod for GradientVertex2D {}
-
-impl From<()> for Primitive {
- fn from(_: ()) -> Self {
- Self::Group { primitives: vec![] }
- }
}