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 --- tiny_skia/src/geometry.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) (limited to 'tiny_skia/src/geometry.rs') diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 02b6e1b9..398b54f7 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -1,10 +1,12 @@ +use crate::core::image; +use crate::core::svg; use crate::core::text::LineHeight; -use crate::core::{Pixels, Point, Radians, Rectangle, Size, Vector}; +use crate::core::{Color, Pixels, Point, Radians, Rectangle, Size, Vector}; use crate::graphics::cache::{self, Cached}; use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::stroke::{self, Stroke}; use crate::graphics::geometry::{self, Path, Style}; -use crate::graphics::{Gradient, Text}; +use crate::graphics::{Gradient, Image, Text}; use crate::Primitive; use std::rc::Rc; @@ -13,6 +15,7 @@ use std::rc::Rc; pub enum Geometry { Live { text: Vec, + images: Vec, primitives: Vec, clip_bounds: Rectangle, }, @@ -22,6 +25,7 @@ pub enum Geometry { #[derive(Debug, Clone)] pub struct Cache { pub text: Rc<[Text]>, + pub images: Rc<[Image]>, pub primitives: Rc<[Primitive]>, pub clip_bounds: Rectangle, } @@ -37,10 +41,12 @@ impl Cached for Geometry { match self { Self::Live { primitives, + images, text, clip_bounds, } => Cache { primitives: Rc::from(primitives), + images: Rc::from(images), text: Rc::from(text), clip_bounds, }, @@ -55,6 +61,7 @@ pub struct Frame { transform: tiny_skia::Transform, stack: Vec, primitives: Vec, + images: Vec, text: Vec, } @@ -68,6 +75,7 @@ impl Frame { clip_bounds, stack: Vec::new(), primitives: Vec::new(), + images: Vec::new(), text: Vec::new(), transform: tiny_skia::Transform::from_translate( clip_bounds.x, @@ -238,7 +246,7 @@ impl geometry::frame::Backend for Frame { Self::with_clip(clip_bounds) } - fn paste(&mut self, frame: Self, _at: Point) { + fn paste(&mut self, frame: Self) { self.primitives.extend(frame.primitives); self.text.extend(frame.text); } @@ -269,10 +277,82 @@ impl geometry::frame::Backend for Frame { fn into_geometry(self) -> Geometry { Geometry::Live { primitives: self.primitives, + images: self.images, text: self.text, clip_bounds: self.clip_bounds, } } + + fn draw_image( + &mut self, + handle: &image::Handle, + bounds: Rectangle, + filter_method: image::FilterMethod, + rotation: Radians, + opacity: f32, + ) { + let (bounds, external_rotation) = + transform_rectangle(bounds, self.transform); + + self.images.push(Image::Raster { + handle: handle.clone(), + filter_method, + bounds, + rotation: rotation + external_rotation, + opacity, + snap: false, + }); + } + + fn draw_svg( + &mut self, + handle: &svg::Handle, + bounds: Rectangle, + color: Option, + rotation: Radians, + opacity: f32, + ) { + let (bounds, external_rotation) = + transform_rectangle(bounds, self.transform); + + self.images.push(Image::Vector { + handle: handle.clone(), + bounds, + color, + rotation: rotation + external_rotation, + opacity, + }); + } +} + +fn transform_rectangle( + rectangle: Rectangle, + transform: tiny_skia::Transform, +) -> (Rectangle, Radians) { + let mut top_left = tiny_skia::Point { + x: rectangle.x, + y: rectangle.y, + }; + + let mut top_right = tiny_skia::Point { + x: rectangle.x + rectangle.width, + y: rectangle.y, + }; + + let mut bottom_left = tiny_skia::Point { + x: rectangle.x, + y: rectangle.y + rectangle.height, + }; + + transform.map_point(&mut top_left); + transform.map_point(&mut top_right); + transform.map_point(&mut bottom_left); + + Rectangle::with_vertices( + Point::new(top_left.x, top_left.y), + Point::new(top_right.x, top_right.y), + Point::new(bottom_left.x, bottom_left.y), + ) } fn convert_path(path: &Path) -> Option { -- cgit From 92bd3ecd6b4a6618f0fc725dea3694c3b40e5314 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 4 Aug 2024 04:30:12 +0200 Subject: Introduce `Image` struct in `core::image` --- tiny_skia/src/geometry.rs | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'tiny_skia/src/geometry.rs') diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 398b54f7..7b0e68f4 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -1,12 +1,11 @@ -use crate::core::image; use crate::core::svg; use crate::core::text::LineHeight; use crate::core::{Color, Pixels, Point, Radians, Rectangle, Size, Vector}; use crate::graphics::cache::{self, Cached}; use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::stroke::{self, Stroke}; -use crate::graphics::geometry::{self, Path, Style}; -use crate::graphics::{Gradient, Image, Text}; +use crate::graphics::geometry::{self, Image, Path, Style}; +use crate::graphics::{self, Gradient, Text}; use crate::Primitive; use std::rc::Rc; @@ -15,7 +14,7 @@ use std::rc::Rc; pub enum Geometry { Live { text: Vec, - images: Vec, + images: Vec, primitives: Vec, clip_bounds: Rectangle, }, @@ -25,7 +24,7 @@ pub enum Geometry { #[derive(Debug, Clone)] pub struct Cache { pub text: Rc<[Text]>, - pub images: Rc<[Image]>, + pub images: Rc<[graphics::Image]>, pub primitives: Rc<[Primitive]>, pub clip_bounds: Rectangle, } @@ -61,7 +60,7 @@ pub struct Frame { transform: tiny_skia::Transform, stack: Vec, primitives: Vec, - images: Vec, + images: Vec, text: Vec, } @@ -283,25 +282,15 @@ impl geometry::frame::Backend for Frame { } } - fn draw_image( - &mut self, - handle: &image::Handle, - bounds: Rectangle, - filter_method: image::FilterMethod, - rotation: Radians, - opacity: f32, - ) { + fn draw_image(&mut self, bounds: Rectangle, image: impl Into) { + let mut image = image.into(); + let (bounds, external_rotation) = transform_rectangle(bounds, self.transform); - self.images.push(Image::Raster { - handle: handle.clone(), - filter_method, - bounds, - rotation: rotation + external_rotation, - opacity, - snap: false, - }); + image.rotation += external_rotation; + + self.images.push(graphics::Image::Raster(image, bounds)); } fn draw_svg( @@ -315,7 +304,7 @@ impl geometry::frame::Backend for Frame { let (bounds, external_rotation) = transform_rectangle(bounds, self.transform); - self.images.push(Image::Vector { + self.images.push(graphics::Image::Vector { handle: handle.clone(), bounds, color, -- cgit From d4b08462e5a25929ec4df32f242898986902af56 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 4 Aug 2024 04:52:55 +0200 Subject: Introduce `Svg` struct in `core::svg` --- tiny_skia/src/geometry.rs | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'tiny_skia/src/geometry.rs') diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 7b0e68f4..659612d1 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -1,11 +1,10 @@ -use crate::core::svg; use crate::core::text::LineHeight; -use crate::core::{Color, Pixels, Point, Radians, Rectangle, Size, Vector}; +use crate::core::{self, Pixels, Point, Radians, Rectangle, Size, Svg, Vector}; use crate::graphics::cache::{self, Cached}; use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::stroke::{self, Stroke}; -use crate::graphics::geometry::{self, Image, Path, Style}; -use crate::graphics::{self, Gradient, Text}; +use crate::graphics::geometry::{self, Path, Style}; +use crate::graphics::{self, Gradient, Image, Text}; use crate::Primitive; use std::rc::Rc; @@ -282,7 +281,7 @@ impl geometry::frame::Backend for Frame { } } - fn draw_image(&mut self, bounds: Rectangle, image: impl Into) { + fn draw_image(&mut self, bounds: Rectangle, image: impl Into) { let mut image = image.into(); let (bounds, external_rotation) = @@ -293,24 +292,15 @@ impl geometry::frame::Backend for Frame { self.images.push(graphics::Image::Raster(image, bounds)); } - fn draw_svg( - &mut self, - handle: &svg::Handle, - bounds: Rectangle, - color: Option, - rotation: Radians, - opacity: f32, - ) { + fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into) { + let mut svg = svg.into(); + let (bounds, external_rotation) = transform_rectangle(bounds, self.transform); - self.images.push(graphics::Image::Vector { - handle: handle.clone(), - bounds, - color, - rotation: rotation + external_rotation, - opacity, - }); + svg.rotation += external_rotation; + + self.images.push(Image::Vector(svg, bounds)); } } -- cgit