diff options
| author | 2021-10-31 16:20:50 +0700 | |
|---|---|---|
| committer | 2021-10-31 16:20:50 +0700 | |
| commit | c4186a71b746b603984e5fe1926a8cef6e8dcfcb (patch) | |
| tree | 147a1ca9b5ee523a2b90f55257374b1531f55f26 /native/src/image.rs | |
| parent | b3a01973c6c726e6539be959659f4306ef3234c6 (diff) | |
| download | iced-c4186a71b746b603984e5fe1926a8cef6e8dcfcb.tar.gz iced-c4186a71b746b603984e5fe1926a8cef6e8dcfcb.tar.bz2 iced-c4186a71b746b603984e5fe1926a8cef6e8dcfcb.zip  | |
Introduce first-class `image` module in `iced_native`
Diffstat (limited to 'native/src/image.rs')
| -rw-r--r-- | native/src/image.rs | 122 | 
1 files changed, 122 insertions, 0 deletions
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); +}  | 
