summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-08-04 04:30:12 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-08-04 04:30:12 +0200
commit92bd3ecd6b4a6618f0fc725dea3694c3b40e5314 (patch)
tree8040fe0f758eb41cbf587119c5d972f5ebaa8567
parent974ae6d1e7cd9df6967762a6d308106f4fe03edc (diff)
downloadiced-92bd3ecd6b4a6618f0fc725dea3694c3b40e5314.tar.gz
iced-92bd3ecd6b4a6618f0fc725dea3694c3b40e5314.tar.bz2
iced-92bd3ecd6b4a6618f0fc725dea3694c3b40e5314.zip
Introduce `Image` struct in `core::image`
-rw-r--r--core/src/image.rs79
-rw-r--r--core/src/lib.rs1
-rw-r--r--core/src/renderer/null.rs14
-rw-r--r--examples/solar_system/src/main.rs15
-rw-r--r--graphics/src/geometry.rs1
-rw-r--r--graphics/src/geometry/frame.rs39
-rw-r--r--graphics/src/image.rs28
-rw-r--r--renderer/src/fallback.rs48
-rw-r--r--tiny_skia/src/engine.rs17
-rw-r--r--tiny_skia/src/geometry.rs35
-rw-r--r--tiny_skia/src/layer.rs57
-rw-r--r--tiny_skia/src/lib.rs22
-rw-r--r--wgpu/src/geometry.rs35
-rw-r--r--wgpu/src/image/mod.rs19
-rw-r--r--wgpu/src/layer.rs51
-rw-r--r--wgpu/src/lib.rs23
-rw-r--r--widget/src/canvas.rs4
-rw-r--r--widget/src/image.rs15
-rw-r--r--widget/src/image/viewer.rs15
19 files changed, 184 insertions, 334 deletions
diff --git a/core/src/image.rs b/core/src/image.rs
index 77ff7500..99d7f3ef 100644
--- a/core/src/image.rs
+++ b/core/src/image.rs
@@ -7,6 +7,73 @@ use rustc_hash::FxHasher;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
+/// A raster image that can be drawn.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Image<H = Handle> {
+ /// The handle of the image.
+ pub handle: H,
+
+ /// The filter method of the image.
+ pub filter_method: FilterMethod,
+
+ /// The rotation to be applied to the image, from its center.
+ pub rotation: Radians,
+
+ /// The opacity of the image.
+ ///
+ /// 0 means transparent. 1 means opaque.
+ pub opacity: f32,
+
+ /// If set to `true`, the image will be snapped to the pixel grid.
+ ///
+ /// This can avoid graphical glitches, specially when using a
+ /// [`FilterMethod::Nearest`].
+ pub snap: bool,
+}
+
+impl Image<Handle> {
+ /// Creates a new [`Image`] with the given handle.
+ pub fn new(handle: impl Into<Handle>) -> Self {
+ Self {
+ handle: handle.into(),
+ filter_method: FilterMethod::default(),
+ rotation: Radians(0.0),
+ opacity: 1.0,
+ snap: false,
+ }
+ }
+
+ /// Sets the filter method of the [`Image`].
+ pub fn filter_method(mut self, filter_method: FilterMethod) -> Self {
+ self.filter_method = filter_method;
+ self
+ }
+
+ /// Sets the rotation of the [`Image`].
+ pub fn rotation(mut self, rotation: impl Into<Radians>) -> Self {
+ self.rotation = rotation.into();
+ self
+ }
+
+ /// Sets the opacity of the [`Image`].
+ pub fn opacity(mut self, opacity: impl Into<f32>) -> Self {
+ self.opacity = opacity.into();
+ self
+ }
+
+ /// Sets whether the [`Image`] should be snapped to the pixel grid.
+ pub fn snap(mut self, snap: bool) -> Self {
+ self.snap = snap;
+ self
+ }
+}
+
+impl From<&Handle> for Image {
+ fn from(handle: &Handle) -> Self {
+ Image::new(handle.clone())
+ }
+}
+
/// A handle of some image data.
#[derive(Clone, PartialEq, Eq)]
pub enum Handle {
@@ -172,14 +239,6 @@ pub trait Renderer: crate::Renderer {
/// Returns the dimensions of an image for the given [`Handle`].
fn measure_image(&self, handle: &Self::Handle) -> Size<u32>;
- /// Draws an image with the given [`Handle`] and inside the provided
- /// `bounds`.
- fn draw_image(
- &mut self,
- handle: Self::Handle,
- filter_method: FilterMethod,
- bounds: Rectangle,
- rotation: Radians,
- opacity: f32,
- );
+ /// Draws an [`Image`] inside the provided `bounds`.
+ fn draw_image(&mut self, image: Image<Self::Handle>, bounds: Rectangle);
}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 40a288e5..0e17d430 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -57,6 +57,7 @@ pub use element::Element;
pub use event::Event;
pub use font::Font;
pub use gradient::Gradient;
+pub use image::Image;
pub use layout::Layout;
pub use length::Length;
pub use overlay::Overlay;
diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs
index 5c7513c6..e71117da 100644
--- a/core/src/renderer/null.rs
+++ b/core/src/renderer/null.rs
@@ -1,5 +1,5 @@
use crate::alignment;
-use crate::image;
+use crate::image::{self, Image};
use crate::renderer::{self, Renderer};
use crate::svg;
use crate::text::{self, Text};
@@ -178,20 +178,14 @@ impl text::Editor for () {
}
impl image::Renderer for () {
- type Handle = ();
+ type Handle = image::Handle;
fn measure_image(&self, _handle: &Self::Handle) -> Size<u32> {
Size::default()
}
- fn draw_image(
- &mut self,
- _handle: Self::Handle,
- _filter_method: image::FilterMethod,
- _bounds: Rectangle,
- _rotation: Radians,
- _opacity: f32,
- ) {
+ fn draw_image(&mut self, _image: Image, _bounds: Rectangle) {
+ todo!()
}
}
diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs
index a4931465..9da9fd34 100644
--- a/examples/solar_system/src/main.rs
+++ b/examples/solar_system/src/main.rs
@@ -160,11 +160,8 @@ impl<Message> canvas::Program<Message> for State {
frame.translate(Vector::new(center.x, center.y));
frame.draw_image(
- &self.sun,
Rectangle::with_radius(Self::SUN_RADIUS),
- image::FilterMethod::Linear,
- 0,
- 1.0,
+ &self.sun,
);
let orbit = Path::circle(Point::ORIGIN, Self::ORBIT_RADIUS);
@@ -189,22 +186,16 @@ impl<Message> canvas::Program<Message> for State {
frame.translate(Vector::new(Self::ORBIT_RADIUS, 0.0));
frame.draw_image(
- &self.earth,
Rectangle::with_radius(Self::EARTH_RADIUS),
- image::FilterMethod::Linear,
- rotation * 20.0,
- 1.0,
+ canvas::Image::new(&self.earth).rotation(rotation * 20.0),
);
frame.rotate(rotation * 10.0);
frame.translate(Vector::new(0.0, Self::MOON_DISTANCE));
frame.draw_image(
- &self.moon,
Rectangle::with_radius(Self::MOON_RADIUS),
- image::FilterMethod::Linear,
- 0,
- 1.0,
+ &self.moon,
);
});
diff --git a/graphics/src/geometry.rs b/graphics/src/geometry.rs
index ab4a7a36..c7515e46 100644
--- a/graphics/src/geometry.rs
+++ b/graphics/src/geometry.rs
@@ -16,6 +16,7 @@ pub use stroke::{LineCap, LineDash, LineJoin, Stroke};
pub use style::Style;
pub use text::Text;
+pub use crate::core::Image;
pub use crate::gradient::{self, Gradient};
use crate::cache::Cached;
diff --git a/graphics/src/geometry/frame.rs b/graphics/src/geometry/frame.rs
index d53d1331..1a7af8e6 100644
--- a/graphics/src/geometry/frame.rs
+++ b/graphics/src/geometry/frame.rs
@@ -1,8 +1,7 @@
//! Draw and generate geometry.
-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};
+use crate::geometry::{self, Fill, Image, Path, Stroke, Text};
/// The region of a surface that can be used to draw geometry.
#[allow(missing_debug_implementations)]
@@ -79,21 +78,8 @@ where
/// 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<Radians>,
- opacity: f32,
- ) {
- self.raw.draw_image(
- handle,
- bounds,
- filter_method,
- rotation.into(),
- opacity,
- );
+ pub fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>) {
+ self.raw.draw_image(bounds, image);
}
/// Stores the current transform of the [`Frame`] and executes the given
@@ -219,14 +205,7 @@ pub trait Backend: Sized {
fill: impl Into<Fill>,
);
- 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<Image>);
fn draw_svg(
&mut self,
@@ -285,15 +264,7 @@ 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_image(&mut self, _bounds: Rectangle, _image: impl Into<Image>) {}
fn draw_svg(
&mut self,
diff --git a/graphics/src/image.rs b/graphics/src/image.rs
index 0e8f2fe3..2e4f4b5a 100644
--- a/graphics/src/image.rs
+++ b/graphics/src/image.rs
@@ -8,28 +8,8 @@ use crate::core::{image, svg, Color, Radians, Rectangle};
#[derive(Debug, Clone, PartialEq)]
pub enum Image {
/// A raster image.
- Raster {
- /// The handle of a raster image.
- handle: image::Handle,
+ Raster(image::Image, Rectangle),
- /// The filter method of a raster image.
- filter_method: image::FilterMethod,
-
- /// The bounds of the image.
- bounds: Rectangle,
-
- /// The rotation of the image.
- rotation: Radians,
-
- /// 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 {
/// The handle of a vector image.
@@ -53,10 +33,8 @@ impl Image {
/// Returns the bounds of the [`Image`].
pub fn bounds(&self) -> Rectangle {
match self {
- Image::Raster {
- bounds, rotation, ..
- }
- | Image::Vector {
+ Image::Raster(image, bounds) => bounds.rotate(image.rotation),
+ Image::Vector {
bounds, rotation, ..
} => bounds.rotate(*rotation),
}
diff --git a/renderer/src/fallback.rs b/renderer/src/fallback.rs
index 73e91dc6..dc8a4107 100644
--- a/renderer/src/fallback.rs
+++ b/renderer/src/fallback.rs
@@ -3,7 +3,8 @@ use crate::core::image;
use crate::core::renderer;
use crate::core::svg;
use crate::core::{
- self, Background, Color, Point, Radians, Rectangle, Size, Transformation,
+ self, Background, Color, Image, Point, Radians, Rectangle, Size,
+ Transformation,
};
use crate::graphics;
use crate::graphics::compositor;
@@ -149,25 +150,8 @@ where
delegate!(self, renderer, renderer.measure_image(handle))
}
- fn draw_image(
- &mut self,
- handle: Self::Handle,
- filter_method: image::FilterMethod,
- bounds: Rectangle,
- rotation: Radians,
- opacity: f32,
- ) {
- delegate!(
- self,
- renderer,
- renderer.draw_image(
- handle,
- filter_method,
- bounds,
- rotation,
- opacity
- )
- );
+ fn draw_image(&mut self, image: Image<A::Handle>, bounds: Rectangle) {
+ delegate!(self, renderer, renderer.draw_image(image, bounds));
}
}
@@ -441,11 +425,10 @@ where
#[cfg(feature = "geometry")]
mod geometry {
use super::Renderer;
- use crate::core::image;
use crate::core::svg;
use crate::core::{Color, Point, Radians, Rectangle, Size, Vector};
use crate::graphics::cache::{self, Cached};
- use crate::graphics::geometry::{self, Fill, Path, Stroke, Text};
+ use crate::graphics::geometry::{self, Fill, Image, Path, Stroke, Text};
impl<A, B> geometry::Renderer for Renderer<A, B>
where
@@ -574,25 +557,8 @@ mod geometry {
delegate!(self, frame, frame.fill_text(text));
}
- fn draw_image(
- &mut self,
- handle: &image::Handle,
- bounds: Rectangle,
- filter_method: image::FilterMethod,
- rotation: Radians,
- opacity: f32,
- ) {
- delegate!(
- self,
- frame,
- frame.draw_image(
- handle,
- bounds,
- filter_method,
- rotation,
- opacity
- )
- );
+ fn draw_image(&mut self, bounds: Rectangle, image: impl Into<Image>) {
+ delegate!(self, frame, frame.draw_image(bounds, image));
}
fn draw_svg(
diff --git a/tiny_skia/src/engine.rs b/tiny_skia/src/engine.rs
index c5c4d494..88e8a9b1 100644
--- a/tiny_skia/src/engine.rs
+++ b/tiny_skia/src/engine.rs
@@ -550,14 +550,7 @@ impl Engine {
) {
match image {
#[cfg(feature = "image")]
- Image::Raster {
- handle,
- filter_method,
- bounds,
- rotation,
- opacity,
- snap: _,
- } => {
+ Image::Raster(raster, bounds) => {
let physical_bounds = *bounds * _transformation;
if !_clip_bounds.intersects(&physical_bounds) {
@@ -568,7 +561,7 @@ impl Engine {
.then_some(_clip_mask as &_);
let center = physical_bounds.center();
- let radians = f32::from(*rotation);
+ let radians = f32::from(raster.rotation);
let transform = into_transform(_transformation).post_rotate_at(
radians.to_degrees(),
@@ -577,10 +570,10 @@ impl Engine {
);
self.raster_pipeline.draw(
- handle,
- *filter_method,
+ &raster.handle,
+ raster.filter_method,
*bounds,
- *opacity,
+ raster.opacity,
_pixels,
transform,
clip_mask,
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<Text>,
- images: Vec<Image>,
+ images: Vec<graphics::Image>,
primitives: Vec<Primitive>,
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<tiny_skia::Transform>,
primitives: Vec<Primitive>,
- images: Vec<Image>,
+ images: Vec<graphics::Image>,
text: Vec<Text>,
}
@@ -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<Image>) {
+ 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,
diff --git a/tiny_skia/src/layer.rs b/tiny_skia/src/layer.rs
index 9a169f46..33df0a86 100644
--- a/tiny_skia/src/layer.rs
+++ b/tiny_skia/src/layer.rs
@@ -1,11 +1,12 @@
+use crate::core::renderer::Quad;
+use crate::core::svg;
use crate::core::{
- image, renderer::Quad, svg, Background, Color, Point, Radians, Rectangle,
- Transformation,
+ Background, Color, Image, Point, Radians, Rectangle, Transformation,
};
+use crate::graphics;
use crate::graphics::damage;
use crate::graphics::layer;
use crate::graphics::text::{Editor, Paragraph, Text};
-use crate::graphics::{self, Image};
use crate::Primitive;
use std::rc::Rc;
@@ -18,7 +19,7 @@ pub struct Layer {
pub quads: Vec<(Quad, Background)>,
pub primitives: Vec<Item<Primitive>>,
pub text: Vec<Item<Text>>,
- pub images: Vec<Image>,
+ pub images: Vec<graphics::Image>,
}
impl Layer {
@@ -117,28 +118,14 @@ impl Layer {
pub fn draw_image(
&mut self,
- image: &Image,
+ image: graphics::Image,
transformation: Transformation,
) {
match image {
- Image::Raster {
- handle,
- filter_method,
- bounds,
- rotation,
- opacity,
- snap: _,
- } => {
- self.draw_raster(
- handle.clone(),
- *filter_method,
- *bounds,
- transformation,
- *rotation,
- *opacity,
- );
+ graphics::Image::Raster(raster, bounds) => {
+ self.draw_raster(raster.clone(), bounds, transformation);
}
- Image::Vector {
+ graphics::Image::Vector {
handle,
color,
bounds,
@@ -147,11 +134,11 @@ impl Layer {
} => {
self.draw_svg(
handle.clone(),
- *color,
- *bounds,
+ color,
+ bounds,
transformation,
- *rotation,
- *opacity,
+ rotation,
+ opacity,
);
}
}
@@ -159,21 +146,11 @@ impl Layer {
pub fn draw_raster(
&mut self,
- handle: image::Handle,
- filter_method: image::FilterMethod,
+ image: Image,
bounds: Rectangle,
transformation: Transformation,
- rotation: Radians,
- opacity: f32,
) {
- let image = Image::Raster {
- handle,
- filter_method,
- bounds: bounds * transformation,
- rotation,
- opacity,
- snap: false,
- };
+ let image = graphics::Image::Raster(image, bounds * transformation);
self.images.push(image);
}
@@ -187,7 +164,7 @@ impl Layer {
rotation: Radians,
opacity: f32,
) {
- let svg = Image::Vector {
+ let svg = graphics::Image::Vector {
handle,
color,
bounds: bounds * transformation,
@@ -304,7 +281,7 @@ impl Layer {
&previous.images,
&current.images,
|image| vec![image.bounds().expand(1.0)],
- Image::eq,
+ graphics::Image::eq,
);
damage.extend(text);
diff --git a/tiny_skia/src/lib.rs b/tiny_skia/src/lib.rs
index f09e5aa3..00864c11 100644
--- a/tiny_skia/src/lib.rs
+++ b/tiny_skia/src/lib.rs
@@ -341,7 +341,7 @@ impl graphics::geometry::Renderer for Renderer {
);
for image in images {
- layer.draw_image(&image, transformation);
+ layer.draw_image(image, transformation);
}
layer.draw_text_group(text, clip_bounds, transformation);
@@ -354,7 +354,7 @@ impl graphics::geometry::Renderer for Renderer {
);
for image in cache.images.iter() {
- layer.draw_image(image, transformation);
+ layer.draw_image(image.clone(), transformation);
}
layer.draw_text_cache(
@@ -381,23 +381,9 @@ impl core::image::Renderer for Renderer {
self.engine.raster_pipeline.dimensions(handle)
}
- fn draw_image(
- &mut self,
- handle: Self::Handle,
- filter_method: core::image::FilterMethod,
- bounds: Rectangle,
- rotation: core::Radians,
- opacity: f32,
- ) {
+ fn draw_image(&mut self, image: core::Image, bounds: Rectangle) {
let (layer, transformation) = self.layers.current_mut();
- layer.draw_raster(
- handle,
- filter_method,
- bounds,
- transformation,
- rotation,
- opacity,
- );
+ layer.draw_raster(image, bounds, transformation);
}
}
diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs
index cb629b3e..6b1bb074 100644
--- a/wgpu/src/geometry.rs
+++ b/wgpu/src/geometry.rs
@@ -1,5 +1,4 @@
//! Build and draw geometry.
-use crate::core::image;
use crate::core::svg;
use crate::core::text::LineHeight;
use crate::core::{
@@ -9,11 +8,11 @@ use crate::graphics::cache::{self, Cached};
use crate::graphics::color;
use crate::graphics::geometry::fill::{self, Fill};
use crate::graphics::geometry::{
- self, LineCap, LineDash, LineJoin, Path, Stroke, Style,
+ self, Image, LineCap, LineDash, LineJoin, Path, Stroke, Style,
};
use crate::graphics::gradient::{self, Gradient};
use crate::graphics::mesh::{self, Mesh};
-use crate::graphics::{self, Image, Text};
+use crate::graphics::{self, Text};
use crate::text;
use crate::triangle;
@@ -27,7 +26,7 @@ use std::sync::Arc;
pub enum Geometry {
Live {
meshes: Vec<Mesh>,
- images: Vec<Image>,
+ images: Vec<graphics::Image>,
text: Vec<Text>,
},
Cached(Cache),
@@ -36,7 +35,7 @@ pub enum Geometry {
#[derive(Debug, Clone)]
pub struct Cache {
pub meshes: Option<triangle::Cache>,
- pub images: Option<Arc<[Image]>>,
+ pub images: Option<Arc<[graphics::Image]>>,
pub text: Option<text::Cache>,
}
@@ -99,7 +98,7 @@ pub struct Frame {
clip_bounds: Rectangle,
buffers: BufferStack,
meshes: Vec<Mesh>,
- images: Vec<Image>,
+ images: Vec<graphics::Image>,
text: Vec<Text>,
transforms: Transforms,
fill_tessellator: tessellation::FillTessellator,
@@ -377,25 +376,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<Image>) {
+ let mut image = image.into();
+
let (bounds, external_rotation) =
self.transforms.current.transform_rectangle(bounds);
- 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(
@@ -409,7 +398,7 @@ impl geometry::frame::Backend for Frame {
let (bounds, external_rotation) =
self.transforms.current.transform_rectangle(bounds);
- self.images.push(Image::Vector {
+ self.images.push(graphics::Image::Vector {
handle: handle.clone(),
color,
bounds,
diff --git a/wgpu/src/image/mod.rs b/wgpu/src/image/mod.rs
index ea34e4ec..2b0d6251 100644
--- a/wgpu/src/image/mod.rs
+++ b/wgpu/src/image/mod.rs
@@ -220,25 +220,18 @@ impl Pipeline {
for image in images {
match &image {
#[cfg(feature = "image")]
- Image::Raster {
- handle,
- filter_method,
- bounds,
- rotation,
- opacity,
- snap,
- } => {
+ Image::Raster(image, bounds) => {
if let Some(atlas_entry) =
- cache.upload_raster(device, encoder, handle)
+ cache.upload_raster(device, encoder, &image.handle)
{
add_instances(
[bounds.x, bounds.y],
[bounds.width, bounds.height],
- f32::from(*rotation),
- *opacity,
- *snap,
+ f32::from(image.rotation),
+ image.opacity,
+ image.snap,
atlas_entry,
- match filter_method {
+ match image.filter_method {
crate::core::image::FilterMethod::Nearest => {
nearest_instances
}
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs
index e714e281..71fa0250 100644
--- a/wgpu/src/layer.rs
+++ b/wgpu/src/layer.rs
@@ -1,5 +1,6 @@
use crate::core::{
- renderer, Background, Color, Point, Radians, Rectangle, Transformation,
+ self, renderer, Background, Color, Point, Radians, Rectangle,
+ Transformation,
};
use crate::graphics;
use crate::graphics::color;
@@ -112,29 +113,10 @@ impl Layer {
self.pending_text.push(text);
}
- pub fn draw_image(
- &mut self,
- image: &Image,
- transformation: Transformation,
- ) {
+ pub fn draw_image(&mut self, image: Image, transformation: Transformation) {
match image {
- Image::Raster {
- handle,
- filter_method,
- bounds,
- rotation,
- opacity,
- snap,
- } => {
- self.draw_raster(
- handle.clone(),
- *filter_method,
- *bounds,
- transformation,
- *rotation,
- *opacity,
- *snap,
- );
+ Image::Raster(image, bounds) => {
+ self.draw_raster(image, bounds, transformation);
}
Image::Vector {
handle,
@@ -145,11 +127,11 @@ impl Layer {
} => {
self.draw_svg(
handle.clone(),
- *color,
- *bounds,
+ color,
+ bounds,
transformation,
- *rotation,
- *opacity,
+ rotation,
+ opacity,
);
}
}
@@ -157,22 +139,11 @@ impl Layer {
pub fn draw_raster(
&mut self,
- handle: crate::core::image::Handle,
- filter_method: crate::core::image::FilterMethod,
+ image: core::Image,
bounds: Rectangle,
transformation: Transformation,
- rotation: Radians,
- opacity: f32,
- snap: bool,
) {
- let image = Image::Raster {
- handle,
- filter_method,
- bounds: bounds * transformation,
- rotation,
- opacity,
- snap,
- };
+ let image = Image::Raster(image, bounds * transformation);
self.images.push(image);
}
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 24e60979..e5f45ad2 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -527,24 +527,9 @@ impl core::image::Renderer for Renderer {
self.image_cache.borrow_mut().measure_image(handle)
}
- fn draw_image(
- &mut self,
- handle: Self::Handle,
- filter_method: core::image::FilterMethod,
- bounds: Rectangle,
- rotation: core::Radians,
- opacity: f32,
- ) {
+ fn draw_image(&mut self, image: core::Image, bounds: Rectangle) {
let (layer, transformation) = self.layers.current_mut();
- layer.draw_raster(
- handle,
- filter_method,
- bounds,
- transformation,
- rotation,
- opacity,
- true,
- );
+ layer.draw_raster(image, bounds, transformation);
}
}
@@ -602,7 +587,7 @@ impl graphics::geometry::Renderer for Renderer {
layer.draw_mesh_group(meshes, transformation);
for image in images {
- layer.draw_image(&image, transformation);
+ layer.draw_image(image, transformation);
}
layer.draw_text_group(text, transformation);
@@ -613,7 +598,7 @@ impl graphics::geometry::Renderer for Renderer {
}
if let Some(images) = cache.images {
- for image in images.iter() {
+ for image in images.iter().cloned() {
layer.draw_image(image, transformation);
}
}
diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs
index 73cef087..185fa082 100644
--- a/widget/src/canvas.rs
+++ b/widget/src/canvas.rs
@@ -8,8 +8,8 @@ pub use program::Program;
pub use crate::graphics::cache::Group;
pub use crate::graphics::geometry::{
- fill, gradient, path, stroke, Fill, Gradient, LineCap, LineDash, LineJoin,
- Path, Stroke, Style, Text,
+ fill, gradient, path, stroke, Fill, Gradient, Image, LineCap, LineDash,
+ LineJoin, Path, Stroke, Style, Text,
};
use crate::core;
diff --git a/widget/src/image.rs b/widget/src/image.rs
index f1571400..55dd9816 100644
--- a/widget/src/image.rs
+++ b/widget/src/image.rs
@@ -8,8 +8,8 @@ use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::Tree;
use crate::core::{
- ContentFit, Element, Layout, Length, Point, Rectangle, Rotation, Size,
- Vector, Widget,
+ self, ContentFit, Element, Layout, Length, Point, Rectangle, Rotation,
+ Size, Vector, Widget,
};
pub use image::{FilterMethod, Handle};
@@ -181,11 +181,14 @@ pub fn draw<Renderer, Handle>(
let render = |renderer: &mut Renderer| {
renderer.draw_image(
- handle.clone(),
- filter_method,
+ core::Image {
+ handle: handle.clone(),
+ filter_method,
+ rotation: rotation.radians(),
+ opacity,
+ snap: true,
+ },
drawing_bounds,
- rotation.radians(),
- opacity,
);
};
diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs
index b8b69b60..b1aad22c 100644
--- a/widget/src/image/viewer.rs
+++ b/widget/src/image/viewer.rs
@@ -6,8 +6,8 @@ use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
- Clipboard, ContentFit, Element, Layout, Length, Pixels, Point, Radians,
- Rectangle, Shell, Size, Vector, Widget,
+ Clipboard, ContentFit, Element, Image, Layout, Length, Pixels, Point,
+ Radians, Rectangle, Shell, Size, Vector, Widget,
};
/// A frame that displays an image with the ability to zoom in/out and pan.
@@ -349,11 +349,14 @@ where
let render = |renderer: &mut Renderer| {
renderer.with_translation(translation, |renderer| {
renderer.draw_image(
- self.handle.clone(),
- self.filter_method,
+ Image {
+ handle: self.handle.clone(),
+ filter_method: self.filter_method,
+ rotation: Radians(0.0),
+ opacity: 1.0,
+ snap: true,
+ },
drawing_bounds,
- Radians(0.0),
- 1.0,
);
});
};