diff options
-rw-r--r-- | glow/src/backend.rs | 5 | ||||
-rw-r--r-- | graphics/src/backend.rs | 2 | ||||
-rw-r--r-- | graphics/src/primitive.rs | 2 | ||||
-rw-r--r-- | graphics/src/widget/image.rs | 5 | ||||
-rw-r--r-- | native/src/image.rs | 122 | ||||
-rw-r--r-- | native/src/lib.rs | 1 | ||||
-rw-r--r-- | native/src/widget/image.rs | 131 | ||||
-rw-r--r-- | native/src/widget/image/viewer.rs | 2 | ||||
-rw-r--r-- | src/widget.rs | 3 | ||||
-rw-r--r-- | wgpu/src/backend.rs | 5 | ||||
-rw-r--r-- | wgpu/src/image.rs | 2 | ||||
-rw-r--r-- | wgpu/src/image/raster.rs | 2 |
12 files changed, 139 insertions, 143 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 89f8db9b..337d2e17 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -237,10 +237,7 @@ impl backend::Text for Backend { #[cfg(feature = "image")] impl backend::Image for Backend { - fn dimensions( - &self, - _handle: &iced_native::widget::image::Handle, - ) -> (u32, u32) { + fn dimensions(&self, _handle: &iced_native::image::Handle) -> (u32, u32) { (50, 50) } } diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 533ac15f..e9f3801a 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -1,6 +1,6 @@ //! Write a graphics backend. +use iced_native::image; use iced_native::text; -use iced_native::widget::image; use iced_native::widget::svg; use iced_native::{Font, Point, Size}; diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 16046387..c46c212e 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -1,4 +1,4 @@ -use iced_native::widget::image; +use iced_native::image; use iced_native::widget::svg; use iced_native::{Background, Color, Font, Rectangle, Size, Vector}; diff --git a/graphics/src/widget/image.rs b/graphics/src/widget/image.rs index 0131dd82..ad8159de 100644 --- a/graphics/src/widget/image.rs +++ b/graphics/src/widget/image.rs @@ -4,9 +4,10 @@ pub mod viewer; use crate::backend::{self, Backend}; use crate::{Primitive, Rectangle, Renderer}; -use iced_native::widget::image; +use iced_native::image; -pub use iced_native::widget::image::{Handle, Image, Viewer}; +pub use iced_native::widget::image::{Image, Viewer}; +pub use image::Handle; impl<B> image::Renderer for Renderer<B> where diff --git a/native/src/image.rs b/native/src/image.rs new file mode 100644 index 00000000..05e086de --- /dev/null +++ b/native/src/image.rs @@ -0,0 +1,122 @@ +use crate::{Hasher, Rectangle}; + +use std::hash::{Hash, Hasher as _}; +use std::path::PathBuf; +use std::sync::Arc; + +/// An [`Image`] handle. +#[derive(Debug, Clone)] +pub struct Handle { + id: u64, + data: Arc<Data>, +} + +impl Handle { + /// Creates an image [`Handle`] pointing to the image of the given path. + /// + /// Makes an educated guess about the image format by examining the data in the file. + pub fn from_path<T: Into<PathBuf>>(path: T) -> Handle { + Self::from_data(Data::Path(path.into())) + } + + /// Creates an image [`Handle`] containing the image pixels directly. This + /// function expects the input data to be provided as a `Vec<u8>` of BGRA + /// pixels. + /// + /// This is useful if you have already decoded your image. + pub fn from_pixels(width: u32, height: u32, pixels: Vec<u8>) -> Handle { + Self::from_data(Data::Pixels { + width, + height, + pixels, + }) + } + + /// Creates an image [`Handle`] containing the image data directly. + /// + /// Makes an educated guess about the image format by examining the given data. + /// + /// This is useful if you already have your image loaded in-memory, maybe + /// because you downloaded or generated it procedurally. + pub fn from_memory(bytes: Vec<u8>) -> Handle { + Self::from_data(Data::Bytes(bytes)) + } + + fn from_data(data: Data) -> Handle { + let mut hasher = Hasher::default(); + data.hash(&mut hasher); + + Handle { + id: hasher.finish(), + data: Arc::new(data), + } + } + + /// Returns the unique identifier of the [`Handle`]. + pub fn id(&self) -> u64 { + self.id + } + + /// Returns a reference to the image [`Data`]. + pub fn data(&self) -> &Data { + &self.data + } +} + +impl<T> From<T> for Handle +where + T: Into<PathBuf>, +{ + fn from(path: T) -> Handle { + Handle::from_path(path.into()) + } +} + +impl Hash for Handle { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.id.hash(state); + } +} + +/// The data of an [`Image`]. +#[derive(Clone, Hash)] +pub enum Data { + /// File data + Path(PathBuf), + + /// In-memory data + Bytes(Vec<u8>), + + /// Decoded image pixels in BGRA format. + Pixels { + /// The width of the image. + width: u32, + /// The height of the image. + height: u32, + /// The pixels. + pixels: Vec<u8>, + }, +} + +impl std::fmt::Debug for Data { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Data::Path(path) => write!(f, "Path({:?})", path), + Data::Bytes(_) => write!(f, "Bytes(...)"), + Data::Pixels { width, height, .. } => { + write!(f, "Pixels({} * {})", width, height) + } + } + } +} + +/// A [`Renderer`] that can render images. +/// +/// [renderer]: crate::renderer +pub trait Renderer: crate::Renderer { + /// Returns the dimensions of an [`Image`] located on the given path. + fn dimensions(&self, handle: &Handle) -> (u32, u32); + + // Draws an [`Image`]. + fn draw(&mut self, handle: Handle, bounds: Rectangle); +} diff --git a/native/src/lib.rs b/native/src/lib.rs index 6fd0d757..704a9873 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -36,6 +36,7 @@ pub mod clipboard; pub mod command; pub mod event; +pub mod image; pub mod keyboard; pub mod layout; pub mod mouse; diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index d23d393a..66e95265 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -2,15 +2,12 @@ pub mod viewer; pub use viewer::Viewer; +use crate::image::{self, Handle}; use crate::layout; use crate::renderer; use crate::{Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget}; -use std::{ - hash::{Hash, Hasher as _}, - path::PathBuf, - sync::Arc, -}; +use std::hash::Hash; /// A frame that displays an image while keeping aspect ratio. /// @@ -55,7 +52,7 @@ impl Image { impl<Message, Renderer> Widget<Message, Renderer> for Image where - Renderer: self::Renderer, + Renderer: image::Renderer, { fn width(&self) -> Length { self.width @@ -111,129 +108,9 @@ where } } -/// An [`Image`] handle. -#[derive(Debug, Clone)] -pub struct Handle { - id: u64, - data: Arc<Data>, -} - -impl Handle { - /// Creates an image [`Handle`] pointing to the image of the given path. - /// - /// Makes an educated guess about the image format by examining the data in the file. - pub fn from_path<T: Into<PathBuf>>(path: T) -> Handle { - Self::from_data(Data::Path(path.into())) - } - - /// Creates an image [`Handle`] containing the image pixels directly. This - /// function expects the input data to be provided as a `Vec<u8>` of BGRA - /// pixels. - /// - /// This is useful if you have already decoded your image. - pub fn from_pixels(width: u32, height: u32, pixels: Vec<u8>) -> Handle { - Self::from_data(Data::Pixels { - width, - height, - pixels, - }) - } - - /// Creates an image [`Handle`] containing the image data directly. - /// - /// Makes an educated guess about the image format by examining the given data. - /// - /// This is useful if you already have your image loaded in-memory, maybe - /// because you downloaded or generated it procedurally. - pub fn from_memory(bytes: Vec<u8>) -> Handle { - Self::from_data(Data::Bytes(bytes)) - } - - fn from_data(data: Data) -> Handle { - let mut hasher = Hasher::default(); - data.hash(&mut hasher); - - Handle { - id: hasher.finish(), - data: Arc::new(data), - } - } - - /// Returns the unique identifier of the [`Handle`]. - pub fn id(&self) -> u64 { - self.id - } - - /// Returns a reference to the image [`Data`]. - pub fn data(&self) -> &Data { - &self.data - } -} - -impl<T> From<T> for Handle -where - T: Into<PathBuf>, -{ - fn from(path: T) -> Handle { - Handle::from_path(path.into()) - } -} - -impl Hash for Handle { - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { - self.id.hash(state); - } -} - -/// The data of an [`Image`]. -#[derive(Clone, Hash)] -pub enum Data { - /// File data - Path(PathBuf), - - /// In-memory data - Bytes(Vec<u8>), - - /// Decoded image pixels in BGRA format. - Pixels { - /// The width of the image. - width: u32, - /// The height of the image. - height: u32, - /// The pixels. - pixels: Vec<u8>, - }, -} - -impl std::fmt::Debug for Data { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Data::Path(path) => write!(f, "Path({:?})", path), - Data::Bytes(_) => write!(f, "Bytes(...)"), - Data::Pixels { width, height, .. } => { - write!(f, "Pixels({} * {})", width, height) - } - } - } -} - -/// The renderer of an [`Image`]. -/// -/// Your [renderer] will need to implement this trait before being able to use -/// an [`Image`] in your user interface. -/// -/// [renderer]: crate::renderer -pub trait Renderer: crate::Renderer { - /// Returns the dimensions of an [`Image`] located on the given path. - fn dimensions(&self, handle: &Handle) -> (u32, u32); - - // Draws an [`Image`]. - fn draw(&mut self, handle: Handle, bounds: Rectangle); -} - impl<'a, Message, Renderer> From<Image> for Element<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: image::Renderer, { fn from(image: Image) -> Element<'a, Message, Renderer> { Element::new(image) diff --git a/native/src/widget/image/viewer.rs b/native/src/widget/image/viewer.rs index d3c794a7..d9eccfad 100644 --- a/native/src/widget/image/viewer.rs +++ b/native/src/widget/image/viewer.rs @@ -1,9 +1,9 @@ //! Zoom and pan on an image. use crate::event::{self, Event}; +use crate::image; use crate::layout; use crate::mouse; use crate::renderer; -use crate::widget::image; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, diff --git a/src/widget.rs b/src/widget.rs index c731cf65..f2bd18cf 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -38,8 +38,9 @@ mod platform { #[cfg_attr(docsrs, doc(cfg(feature = "image")))] pub mod image { //! Display images in your user interface. + pub use crate::runtime::image::Handle; pub use crate::runtime::widget::image::viewer; - pub use crate::runtime::widget::image::{Handle, Image, Viewer}; + pub use crate::runtime::widget::image::{Image, Viewer}; } #[cfg_attr(docsrs, doc(cfg(feature = "svg")))] diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 7d7a26f4..0f4c35c3 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -302,10 +302,7 @@ impl backend::Text for Backend { #[cfg(feature = "image_rs")] impl backend::Image for Backend { - fn dimensions( - &self, - handle: &iced_native::widget::image::Handle, - ) -> (u32, u32) { + fn dimensions(&self, handle: &iced_native::image::Handle) -> (u32, u32) { self.image_pipeline.dimensions(handle) } } diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index ca31791c..01af2571 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -17,7 +17,7 @@ use std::mem; use bytemuck::{Pod, Zeroable}; #[cfg(feature = "image_rs")] -use iced_native::widget::image; +use iced_native::image; #[cfg(feature = "svg")] use iced_native::widget::svg; diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs index 76459fe5..e13987b4 100644 --- a/wgpu/src/image/raster.rs +++ b/wgpu/src/image/raster.rs @@ -1,5 +1,5 @@ use crate::image::atlas::{self, Atlas}; -use iced_native::widget::image; +use iced_native::image; use std::collections::{HashMap, HashSet}; use bitflags::bitflags; |