summaryrefslogtreecommitdiffstats
path: root/wgpu/src/widget/canvas/frame.rs
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/widget/canvas/frame.rs')
-rw-r--r--wgpu/src/widget/canvas/frame.rs367
1 files changed, 0 insertions, 367 deletions
diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs
deleted file mode 100644
index 5262ab4e..00000000
--- a/wgpu/src/widget/canvas/frame.rs
+++ /dev/null
@@ -1,367 +0,0 @@
-use iced_native::{Point, Rectangle, Size, Vector};
-
-use crate::{
- canvas::{Fill, Geometry, Path, Stroke, Text},
- triangle, Primitive,
-};
-
-/// The frame of a [`Canvas`].
-///
-/// [`Canvas`]: struct.Canvas.html
-#[derive(Debug)]
-pub struct Frame {
- size: Size,
- buffers: lyon::tessellation::VertexBuffers<triangle::Vertex2D, u32>,
- primitives: Vec<Primitive>,
- transforms: Transforms,
-}
-
-#[derive(Debug)]
-struct Transforms {
- previous: Vec<Transform>,
- current: Transform,
-}
-
-#[derive(Debug, Clone, Copy)]
-struct Transform {
- raw: lyon::math::Transform,
- is_identity: bool,
-}
-
-impl Frame {
- /// Creates a new empty [`Frame`] with the given dimensions.
- ///
- /// The default coordinate system of a [`Frame`] has its origin at the
- /// top-left corner of its bounds.
- ///
- /// [`Frame`]: struct.Frame.html
- pub fn new(size: Size) -> Frame {
- Frame {
- size,
- buffers: lyon::tessellation::VertexBuffers::new(),
- primitives: Vec::new(),
- transforms: Transforms {
- previous: Vec::new(),
- current: Transform {
- raw: lyon::math::Transform::identity(),
- is_identity: true,
- },
- },
- }
- }
-
- /// Returns the width of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn width(&self) -> f32 {
- self.size.width
- }
-
- /// Returns the width of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn height(&self) -> f32 {
- self.size.height
- }
-
- /// Returns the dimensions of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn size(&self) -> Size {
- self.size
- }
-
- /// Returns the coordinate of the center of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn center(&self) -> Point {
- Point::new(self.size.width / 2.0, self.size.height / 2.0)
- }
-
- /// Draws the given [`Path`] on the [`Frame`] by filling it with the
- /// provided style.
- ///
- /// [`Path`]: path/struct.Path.html
- /// [`Frame`]: struct.Frame.html
- pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
- use lyon::tessellation::{
- BuffersBuilder, FillOptions, FillTessellator,
- };
-
- let mut buffers = BuffersBuilder::new(
- &mut self.buffers,
- FillVertex(match fill.into() {
- Fill::Color(color) => color.into_linear(),
- }),
- );
-
- let mut tessellator = FillTessellator::new();
-
- let result = if self.transforms.current.is_identity {
- tessellator.tessellate_path(
- path.raw(),
- &FillOptions::default(),
- &mut buffers,
- )
- } else {
- let path = path.transformed(&self.transforms.current.raw);
-
- tessellator.tessellate_path(
- path.raw(),
- &FillOptions::default(),
- &mut buffers,
- )
- };
-
- let _ = result.expect("Tessellate path");
- }
-
- /// Draws an axis-aligned rectangle given its top-left corner coordinate and
- /// its `Size` on the [`Frame`] by filling it with the provided style.
- ///
- /// [`Frame`]: struct.Frame.html
- pub fn fill_rectangle(
- &mut self,
- top_left: Point,
- size: Size,
- fill: impl Into<Fill>,
- ) {
- use lyon::tessellation::{BuffersBuilder, FillOptions};
-
- let mut buffers = BuffersBuilder::new(
- &mut self.buffers,
- FillVertex(match fill.into() {
- Fill::Color(color) => color.into_linear(),
- }),
- );
-
- let top_left =
- self.transforms.current.raw.transform_point(
- lyon::math::Point::new(top_left.x, top_left.y),
- );
-
- let size =
- self.transforms.current.raw.transform_vector(
- lyon::math::Vector::new(size.width, size.height),
- );
-
- let _ = lyon::tessellation::basic_shapes::fill_rectangle(
- &lyon::math::Rect::new(top_left, size.into()),
- &FillOptions::default(),
- &mut buffers,
- )
- .expect("Fill rectangle");
- }
-
- /// Draws the stroke of the given [`Path`] on the [`Frame`] with the
- /// provided style.
- ///
- /// [`Path`]: path/struct.Path.html
- /// [`Frame`]: struct.Frame.html
- pub fn stroke(&mut self, path: &Path, stroke: impl Into<Stroke>) {
- use lyon::tessellation::{
- BuffersBuilder, StrokeOptions, StrokeTessellator,
- };
-
- let stroke = stroke.into();
-
- let mut buffers = BuffersBuilder::new(
- &mut self.buffers,
- StrokeVertex(stroke.color.into_linear()),
- );
-
- let mut tessellator = StrokeTessellator::new();
-
- let mut options = StrokeOptions::default();
- options.line_width = stroke.width;
- options.start_cap = stroke.line_cap.into();
- options.end_cap = stroke.line_cap.into();
- options.line_join = stroke.line_join.into();
-
- let result = if self.transforms.current.is_identity {
- tessellator.tessellate_path(path.raw(), &options, &mut buffers)
- } else {
- let path = path.transformed(&self.transforms.current.raw);
-
- tessellator.tessellate_path(path.raw(), &options, &mut buffers)
- };
-
- let _ = result.expect("Stroke path");
- }
-
- /// Draws the characters of the given [`Text`] on the [`Frame`], filling
- /// them with the given color.
- ///
- /// __Warning:__ Text currently does not work well with rotations and scale
- /// transforms! The position will be correctly transformed, but the
- /// resulting glyphs will not be rotated or scaled properly.
- ///
- /// Additionally, all text will be rendered on top of all the layers of
- /// a [`Canvas`]. Therefore, it is currently only meant to be used for
- /// overlays, which is the most common use case.
- ///
- /// Support for vectorial text is planned, and should address all these
- /// limitations.
- ///
- /// [`Text`]: struct.Text.html
- /// [`Frame`]: struct.Frame.html
- /// [`Canvas`]: struct.Canvas.html
- pub fn fill_text(&mut self, text: impl Into<Text>) {
- use std::f32;
-
- let text = text.into();
-
- let position = if self.transforms.current.is_identity {
- text.position
- } else {
- let transformed = self.transforms.current.raw.transform_point(
- lyon::math::Point::new(text.position.x, text.position.y),
- );
-
- Point::new(transformed.x, transformed.y)
- };
-
- // TODO: Use vectorial text instead of primitive
- self.primitives.push(Primitive::Text {
- content: text.content,
- bounds: Rectangle {
- x: position.x,
- y: position.y,
- width: f32::INFINITY,
- height: f32::INFINITY,
- },
- color: text.color,
- size: text.size,
- font: text.font,
- horizontal_alignment: text.horizontal_alignment,
- vertical_alignment: text.vertical_alignment,
- });
- }
-
- /// Stores the current transform of the [`Frame`] and executes the given
- /// drawing operations, restoring the transform afterwards.
- ///
- /// This method is useful to compose transforms and perform drawing
- /// operations in different coordinate systems.
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn with_save(&mut self, f: impl FnOnce(&mut Frame)) {
- self.transforms.previous.push(self.transforms.current);
-
- f(self);
-
- self.transforms.current = self.transforms.previous.pop().unwrap();
- }
-
- /// Applies a translation to the current transform of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn translate(&mut self, translation: Vector) {
- self.transforms.current.raw = self
- .transforms
- .current
- .raw
- .pre_translate(lyon::math::Vector::new(
- translation.x,
- translation.y,
- ));
- self.transforms.current.is_identity = false;
- }
-
- /// Applies a rotation to the current transform of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn rotate(&mut self, angle: f32) {
- self.transforms.current.raw = self
- .transforms
- .current
- .raw
- .pre_rotate(lyon::math::Angle::radians(-angle));
- self.transforms.current.is_identity = false;
- }
-
- /// Applies a scaling to the current transform of the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- #[inline]
- pub fn scale(&mut self, scale: f32) {
- self.transforms.current.raw =
- self.transforms.current.raw.pre_scale(scale, scale);
- self.transforms.current.is_identity = false;
- }
-
- /// Produces the [`Geometry`] representing everything drawn on the [`Frame`].
- ///
- /// [`Frame`]: struct.Frame.html
- /// [`Geometry`]: struct.Geometry.html
- pub fn into_geometry(mut self) -> Geometry {
- if !self.buffers.indices.is_empty() {
- self.primitives.push(Primitive::Mesh2D {
- size: self.size,
- buffers: triangle::Mesh2D {
- vertices: self.buffers.vertices,
- indices: self.buffers.indices,
- },
- });
- }
-
- Geometry::from_primitive(Primitive::Group {
- primitives: self.primitives,
- })
- }
-}
-
-struct FillVertex([f32; 4]);
-
-impl lyon::tessellation::BasicVertexConstructor<triangle::Vertex2D>
- for FillVertex
-{
- fn new_vertex(
- &mut self,
- position: lyon::math::Point,
- ) -> triangle::Vertex2D {
- triangle::Vertex2D {
- position: [position.x, position.y],
- color: self.0,
- }
- }
-}
-
-impl lyon::tessellation::FillVertexConstructor<triangle::Vertex2D>
- for FillVertex
-{
- fn new_vertex(
- &mut self,
- position: lyon::math::Point,
- _attributes: lyon::tessellation::FillAttributes<'_>,
- ) -> triangle::Vertex2D {
- 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,
- position: lyon::math::Point,
- _attributes: lyon::tessellation::StrokeAttributes<'_, '_>,
- ) -> triangle::Vertex2D {
- triangle::Vertex2D {
- position: [position.x, position.y],
- color: self.0,
- }
- }
-}