From 0ceee1cf3ae49f5bd0e3f2b346a4b34076e4523a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 4 Aug 2024 03:28:43 +0200 Subject: Implement image support for `canvas` widget --- graphics/Cargo.toml | 1 + graphics/src/geometry/frame.rs | 72 ++++++++++++++++++++++++++++++++++++++---- graphics/src/image.rs | 6 ++++ 3 files changed, 72 insertions(+), 7 deletions(-) (limited to 'graphics') diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index e8d27d07..7e2d767b 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [features] geometry = ["lyon_path"] image = ["dep:image", "kamadak-exif"] +svg = [] web-colors = [] fira-sans = [] diff --git a/graphics/src/geometry/frame.rs b/graphics/src/geometry/frame.rs index 377589d7..d53d1331 100644 --- a/graphics/src/geometry/frame.rs +++ b/graphics/src/geometry/frame.rs @@ -1,5 +1,7 @@ //! Draw and generate geometry. -use crate::core::{Point, Radians, Rectangle, Size, Vector}; +use crate::core::image; +use crate::core::svg; +use crate::core::{Color, Point, Radians, Rectangle, Size, Vector}; use crate::geometry::{self, Fill, Path, Stroke, Text}; /// The region of a surface that can be used to draw geometry. @@ -75,6 +77,25 @@ where self.raw.fill_text(text); } + /// Draws the given image on the [`Frame`] inside the given bounds. + #[cfg(feature = "image")] + pub fn draw_image( + &mut self, + handle: &image::Handle, + bounds: Rectangle, + filter_method: image::FilterMethod, + rotation: impl Into, + opacity: f32, + ) { + self.raw.draw_image( + handle, + bounds, + filter_method, + rotation.into(), + opacity, + ); + } + /// Stores the current transform of the [`Frame`] and executes the given /// drawing operations, restoring the transform afterwards. /// @@ -116,8 +137,7 @@ where let mut frame = self.draft(region); let result = f(&mut frame); - - self.paste(frame, Point::new(region.x, region.y)); + self.paste(frame); result } @@ -134,8 +154,8 @@ where } /// Draws the contents of the given [`Frame`] with origin at the given [`Point`]. - fn paste(&mut self, frame: Self, at: Point) { - self.raw.paste(frame.raw, at); + fn paste(&mut self, frame: Self) { + self.raw.paste(frame.raw); } /// Applies a translation to the current transform of the [`Frame`]. @@ -186,7 +206,7 @@ pub trait Backend: Sized { fn scale_nonuniform(&mut self, scale: impl Into); fn draft(&mut self, clip_bounds: Rectangle) -> Self; - fn paste(&mut self, frame: Self, at: Point); + fn paste(&mut self, frame: Self); fn stroke<'a>(&mut self, path: &Path, stroke: impl Into>); @@ -199,6 +219,24 @@ pub trait Backend: Sized { fill: impl Into, ); + fn draw_image( + &mut self, + handle: &image::Handle, + bounds: Rectangle, + filter_method: image::FilterMethod, + rotation: Radians, + opacity: f32, + ); + + fn draw_svg( + &mut self, + handle: &svg::Handle, + bounds: Rectangle, + color: Option, + rotation: Radians, + opacity: f32, + ); + fn into_geometry(self) -> Self::Geometry; } @@ -231,7 +269,7 @@ impl Backend for () { fn scale_nonuniform(&mut self, _scale: impl Into) {} fn draft(&mut self, _clip_bounds: Rectangle) -> Self {} - fn paste(&mut self, _frame: Self, _at: Point) {} + fn paste(&mut self, _frame: Self) {} fn stroke<'a>(&mut self, _path: &Path, _stroke: impl Into>) {} @@ -246,4 +284,24 @@ impl Backend for () { } fn into_geometry(self) -> Self::Geometry {} + + fn draw_image( + &mut self, + _handle: &image::Handle, + _bounds: Rectangle, + _filter_method: image::FilterMethod, + _rotation: Radians, + _opacity: f32, + ) { + } + + fn draw_svg( + &mut self, + _handle: &svg::Handle, + _bounds: Rectangle, + _color: Option, + _rotation: Radians, + _opacity: f32, + ) { + } } diff --git a/graphics/src/image.rs b/graphics/src/image.rs index 318592be..0e8f2fe3 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -23,6 +23,12 @@ pub enum Image { /// The opacity of the image. opacity: f32, + + /// If set to `true`, the image will be snapped to the pixel grid. + /// + /// This can avoid graphical glitches, specially when using a + /// [`image::FilterMethod::Nearest`]. + snap: bool, }, /// A vector image. Vector { -- cgit