summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/src/geometry.rs2
-rw-r--r--graphics/src/geometry/fill.rs14
-rw-r--r--graphics/src/geometry/style.rs3
-rw-r--r--graphics/src/gradient.rs88
-rw-r--r--graphics/src/lib.rs2
-rw-r--r--graphics/src/primitive.rs32
-rw-r--r--graphics/src/triangle.rs1
7 files changed, 124 insertions, 18 deletions
diff --git a/graphics/src/geometry.rs b/graphics/src/geometry.rs
index 88997288..729c3d44 100644
--- a/graphics/src/geometry.rs
+++ b/graphics/src/geometry.rs
@@ -12,7 +12,7 @@ pub use stroke::{LineCap, LineDash, LineJoin, Stroke};
pub use style::Style;
pub use text::Text;
-pub use crate::core::gradient::{self, Gradient};
+pub use crate::gradient::{self, Gradient};
use crate::Primitive;
diff --git a/graphics/src/geometry/fill.rs b/graphics/src/geometry/fill.rs
index 2e8c1669..b773c99b 100644
--- a/graphics/src/geometry/fill.rs
+++ b/graphics/src/geometry/fill.rs
@@ -1,8 +1,9 @@
//! Fill [crate::widget::canvas::Geometry] with a certain style.
-use iced_core::{Color, Gradient};
-
pub use crate::geometry::Style;
+use crate::core::Color;
+use crate::gradient::{self, Gradient};
+
/// The style used to fill geometry.
#[derive(Debug, Clone)]
pub struct Fill {
@@ -49,6 +50,15 @@ impl From<Gradient> for Fill {
}
}
+impl From<gradient::Linear> for Fill {
+ fn from(gradient: gradient::Linear) -> Self {
+ Fill {
+ style: Style::Gradient(Gradient::Linear(gradient)),
+ ..Default::default()
+ }
+ }
+}
+
/// The fill rule defines how to determine what is inside and what is outside of
/// a shape.
///
diff --git a/graphics/src/geometry/style.rs b/graphics/src/geometry/style.rs
index be9ee376..a0f4b08a 100644
--- a/graphics/src/geometry/style.rs
+++ b/graphics/src/geometry/style.rs
@@ -1,4 +1,5 @@
-use iced_core::{Color, Gradient};
+use crate::core::Color;
+use crate::geometry::Gradient;
/// The coloring style of some drawing.
#[derive(Debug, Clone, PartialEq)]
diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs
new file mode 100644
index 00000000..3e88d9de
--- /dev/null
+++ b/graphics/src/gradient.rs
@@ -0,0 +1,88 @@
+//! A gradient that can be used as a [`Fill`] for some geometry.
+//!
+//! For a gradient that you can use as a background variant for a widget, see [`Gradient`].
+//!
+//! [`Gradient`]: crate::core::Gradient;
+use crate::core::gradient::ColorStop;
+use crate::core::{Color, Point};
+use std::cmp::Ordering;
+
+#[derive(Debug, Clone, PartialEq)]
+/// A fill which linearly interpolates colors along a direction.
+///
+/// For a gradient which can be used as a fill for a background of a widget, see [`crate::core::Gradient`].
+pub enum Gradient {
+ /// A linear gradient interpolates colors along a direction from its `start` to its `end`
+ /// point.
+ Linear(Linear),
+}
+
+impl From<Linear> for Gradient {
+ fn from(gradient: Linear) -> Self {
+ Self::Linear(gradient)
+ }
+}
+
+/// A linear gradient that can be used in the style of [`Fill`] or [`Stroke`].
+///
+/// [`Fill`]: crate::geometry::Fill;
+/// [`Stroke`]: crate::geometry::Stroke;
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub struct Linear {
+ /// The absolute starting position of the gradient.
+ pub start: Point,
+
+ /// The absolute ending position of the gradient.
+ pub end: Point,
+
+ /// [`ColorStop`]s along the linear gradient direction.
+ pub stops: [Option<ColorStop>; 8],
+}
+
+impl Linear {
+ /// Creates a new [`Builder`].
+ pub fn new(start: Point, end: Point) -> Self {
+ Self {
+ start,
+ end,
+ stops: [None; 8],
+ }
+ }
+
+ /// Adds a new [`ColorStop`], defined by an offset and a color, to the gradient.
+ ///
+ /// Any `offset` that is not within `0.0..=1.0` will be silently ignored.
+ ///
+ /// Any stop added after the 8th will be silently ignored.
+ pub fn add_stop(mut self, offset: f32, color: Color) -> Self {
+ if offset.is_finite() && (0.0..=1.0).contains(&offset) {
+ let (Ok(index) | Err(index)) =
+ self.stops.binary_search_by(|stop| match stop {
+ None => Ordering::Greater,
+ Some(stop) => stop.offset.partial_cmp(&offset).unwrap(),
+ });
+
+ if index < 8 {
+ self.stops[index] = Some(ColorStop { offset, color });
+ }
+ } else {
+ log::warn!("Gradient: ColorStop must be within 0.0..=1.0 range.");
+ };
+
+ self
+ }
+
+ /// Adds multiple [`ColorStop`]s to the gradient.
+ ///
+ /// Any stop added after the 8th will be silently ignored.
+ pub fn add_stops(
+ mut self,
+ stops: impl IntoIterator<Item = ColorStop>,
+ ) -> Self {
+ for stop in stops.into_iter() {
+ self = self.add_stop(stop.offset, stop.color)
+ }
+
+ self
+ }
+}
diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs
index 12fc54f6..bfaac19f 100644
--- a/graphics/src/lib.rs
+++ b/graphics/src/lib.rs
@@ -29,6 +29,7 @@ mod viewport;
pub mod backend;
pub mod compositor;
pub mod damage;
+pub mod gradient;
pub mod primitive;
pub mod renderer;
@@ -42,6 +43,7 @@ pub use antialiasing::Antialiasing;
pub use backend::Backend;
pub use compositor::Compositor;
pub use error::Error;
+pub use gradient::Gradient;
pub use primitive::Primitive;
pub use renderer::Renderer;
pub use transformation::Transformation;
diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs
index d4446c87..9728db39 100644
--- a/graphics/src/primitive.rs
+++ b/graphics/src/primitive.rs
@@ -3,7 +3,7 @@ use crate::core::alignment;
use crate::core::image;
use crate::core::svg;
use crate::core::text;
-use crate::core::{Background, Color, Font, Gradient, Rectangle, Size, Vector};
+use crate::core::{Background, Color, Font, Rectangle, Size, Vector};
use bytemuck::{Pod, Zeroable};
use std::sync::Arc;
@@ -39,7 +39,7 @@ pub enum Primitive {
bounds: Rectangle,
/// The background of the quad
background: Background,
- /// The border radius of the quad
+ /// The border radii of the quad
border_radius: [f32; 4],
/// The border width of the quad
border_width: f32,
@@ -81,15 +81,12 @@ pub enum Primitive {
/// It can be used to render many kinds of geometry freely.
GradientMesh {
/// The vertices and indices of the mesh.
- buffers: Mesh2D<Vertex2D>,
+ 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,
-
- /// The [`Gradient`] to apply to the mesh.
- gradient: Gradient,
},
/// A [`tiny_skia`] path filled with some paint.
#[cfg(feature = "tiny-skia")]
@@ -242,25 +239,34 @@ pub struct Mesh2D<T> {
pub indices: Vec<u32>,
}
-/// A two-dimensional vertex.
+/// A two-dimensional vertex with a color.
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
#[repr(C)]
-pub struct Vertex2D {
+pub struct ColoredVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],
+
+ /// The color of the vertex in __linear__ RGBA.
+ pub color: [f32; 4],
}
-/// A two-dimensional vertex with a color.
-#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
+/// A vertex which contains 2D position & packed gradient data.
+#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(C)]
-pub struct ColoredVertex2D {
+pub struct GradientVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],
- /// The color of the vertex in __linear__ RGBA.
- pub color: [f32; 4],
+ /// The packed vertex data of the gradient.
+ pub gradient: [f32; 44],
}
+#[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![] }
diff --git a/graphics/src/triangle.rs b/graphics/src/triangle.rs
deleted file mode 100644
index 09b61767..00000000
--- a/graphics/src/triangle.rs
+++ /dev/null
@@ -1 +0,0 @@
-//! Draw geometry using meshes of triangles.