summaryrefslogtreecommitdiffstats
path: root/graphics/src/widget/canvas/frame.rs
diff options
context:
space:
mode:
authorLibravatar shan <shankern@protonmail.com>2022-09-29 10:52:58 -0700
committerLibravatar shan <shankern@protonmail.com>2022-09-29 10:52:58 -0700
commit00a8a167122301983753a2f4b43d136c79a7d5cb (patch)
tree99596e40da4150eab2d9e862d84373fcf02a548d /graphics/src/widget/canvas/frame.rs
parent97f385e093711c269df315b28f76e66e0220e22a (diff)
downloadiced-00a8a167122301983753a2f4b43d136c79a7d5cb.tar.gz
iced-00a8a167122301983753a2f4b43d136c79a7d5cb.tar.bz2
iced-00a8a167122301983753a2f4b43d136c79a7d5cb.zip
Adds linear gradient support to 2D meshes in the canvas widget.
Diffstat (limited to 'graphics/src/widget/canvas/frame.rs')
-rw-r--r--graphics/src/widget/canvas/frame.rs111
1 files changed, 40 insertions, 71 deletions
diff --git a/graphics/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs
index 516539ca..df2db98f 100644
--- a/graphics/src/widget/canvas/frame.rs
+++ b/graphics/src/widget/canvas/frame.rs
@@ -3,11 +3,13 @@ use std::borrow::Cow;
use iced_native::{Point, Rectangle, Size, Vector};
use crate::triangle;
-use crate::widget::canvas::path;
-use crate::widget::canvas::{Fill, Geometry, Path, Stroke, Text};
+use crate::widget::canvas::{Fill, Geometry, Path, Stroke, Text, path};
use crate::Primitive;
+use crate::triangle::{Vertex2D};
+use crate::shader::Shader;
use lyon::tessellation;
+use lyon::tessellation::geometry_builder::Positions;
/// The frame of a [`Canvas`].
///
@@ -15,7 +17,7 @@ use lyon::tessellation;
#[allow(missing_debug_implementations)]
pub struct Frame {
size: Size,
- buffers: lyon::tessellation::VertexBuffers<triangle::Vertex2D, u32>,
+ buffers: Vec<(tessellation::VertexBuffers<lyon::math::Point, u32>, Shader)>,
primitives: Vec<Primitive>,
transforms: Transforms,
fill_tessellator: tessellation::FillTessellator,
@@ -42,7 +44,7 @@ impl Frame {
pub fn new(size: Size) -> Frame {
Frame {
size,
- buffers: lyon::tessellation::VertexBuffers::new(),
+ buffers: Vec::new(),
primitives: Vec::new(),
transforms: Transforms {
previous: Vec::new(),
@@ -82,18 +84,18 @@ impl Frame {
/// Draws the given [`Path`] on the [`Frame`] by filling it with the
/// provided style.
- pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
- let Fill { color, rule } = fill.into();
+ pub fn fill<'a>(&mut self, path: &Path, fill: impl Into<Fill<'a>>) {
+ let Fill { style, rule } = fill.into();
- let mut buffers = tessellation::BuffersBuilder::new(
- &mut self.buffers,
- FillVertex(color.into_linear()),
- );
+ let mut buf = tessellation::VertexBuffers::new();
+
+ let mut buffers =
+ tessellation::BuffersBuilder::new(&mut buf, Positions);
let options =
tessellation::FillOptions::default().with_fill_rule(rule.into());
- let result = if self.transforms.current.is_identity {
+ if self.transforms.current.is_identity {
self.fill_tessellator.tessellate_path(
path.raw(),
&options,
@@ -107,25 +109,24 @@ impl Frame {
&options,
&mut buffers,
)
- };
+ }.expect("Tessellate path.");
- result.expect("Tessellate path");
+ self.buffers.push((buf, style.into()))
}
/// Draws an axis-aligned rectangle given its top-left corner coordinate and
/// its `Size` on the [`Frame`] by filling it with the provided style.
- pub fn fill_rectangle(
+ pub fn fill_rectangle<'a>(
&mut self,
top_left: Point,
size: Size,
- fill: impl Into<Fill>,
+ fill: impl Into<Fill<'a>>,
) {
- let Fill { color, rule } = fill.into();
+ let Fill { style, rule } = fill.into();
+
+ let mut buf = tessellation::VertexBuffers::new();
- let mut buffers = tessellation::BuffersBuilder::new(
- &mut self.buffers,
- FillVertex(color.into_linear()),
- );
+ let mut buffers = tessellation::BuffersBuilder::new(&mut buf, Positions);
let top_left =
self.transforms.current.raw.transform_point(
@@ -147,6 +148,8 @@ impl Frame {
&mut buffers,
)
.expect("Fill rectangle");
+
+ self.buffers.push((buf, style.into()))
}
/// Draws the stroke of the given [`Path`] on the [`Frame`] with the
@@ -154,10 +157,9 @@ impl Frame {
pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>) {
let stroke = stroke.into();
- let mut buffers = tessellation::BuffersBuilder::new(
- &mut self.buffers,
- StrokeVertex(stroke.color.into_linear()),
- );
+ let mut buf = tessellation::VertexBuffers::new();
+
+ let mut buffers = tessellation::BuffersBuilder::new(&mut buf, Positions);
let mut options = tessellation::StrokeOptions::default();
options.line_width = stroke.width;
@@ -171,7 +173,7 @@ impl Frame {
Cow::Owned(path::dashed(path, stroke.line_dash))
};
- let result = if self.transforms.current.is_identity {
+ if self.transforms.current.is_identity {
self.stroke_tessellator.tessellate_path(
path.raw(),
&options,
@@ -185,9 +187,9 @@ impl Frame {
&options,
&mut buffers,
)
- };
+ }.expect("Stroke path");
- result.expect("Stroke path");
+ self.buffers.push((buf, stroke.style.into()))
}
/// Draws the characters of the given [`Text`] on the [`Frame`], filling
@@ -331,52 +333,19 @@ impl Frame {
}
fn into_primitives(mut self) -> Vec<Primitive> {
- if !self.buffers.indices.is_empty() {
- self.primitives.push(Primitive::Mesh2D {
- buffers: triangle::Mesh2D {
- vertices: self.buffers.vertices,
- indices: self.buffers.indices,
- },
- size: self.size,
- });
+ if !self.primitives.is_empty() {
+ for (buffer, shader) in self.buffers {
+ self.primitives.push(Primitive::Mesh2D {
+ buffers: triangle::Mesh2D {
+ vertices: Vertex2D::from(buffer.vertices),
+ indices: buffer.indices
+ },
+ size: self.size,
+ shader
+ })
+ }
}
self.primitives
}
}
-
-struct FillVertex([f32; 4]);
-
-impl lyon::tessellation::FillVertexConstructor<triangle::Vertex2D>
- for FillVertex
-{
- fn new_vertex(
- &mut self,
- vertex: lyon::tessellation::FillVertex<'_>,
- ) -> triangle::Vertex2D {
- let position = vertex.position();
-
- triangle::Vertex2D {
- position: [position.x, position.y],
- color: self.0,
- }
- }
-}
-
-struct StrokeVertex([f32; 4]);
-
-impl lyon::tessellation::StrokeVertexConstructor<triangle::Vertex2D>
- for StrokeVertex
-{
- fn new_vertex(
- &mut self,
- vertex: lyon::tessellation::StrokeVertex<'_, '_>,
- ) -> triangle::Vertex2D {
- let position = vertex.position();
-
- triangle::Vertex2D {
- position: [position.x, position.y],
- color: self.0,
- }
- }
-}