98 lines · 2.6 KB · Rust
RawDownload
use crate::{size, DevicePixels, Result, SharedString, Size};use smallvec::SmallVec; use image::{Delay, Frame};use std::{    borrow::Cow,    fmt,    hash::Hash,    sync::atomic::{AtomicUsize, Ordering::SeqCst},}; /// A source of assets for this app to use.pub trait AssetSource: 'static + Send + Sync {    /// Load the given asset from the source path.    fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>>;     /// List the assets at the given path.    fn list(&self, path: &str) -> Result<Vec<SharedString>>;} impl AssetSource for () {    fn load(&self, _path: &str) -> Result<Option<Cow<'static, [u8]>>> {        Ok(None)    }     fn list(&self, _path: &str) -> Result<Vec<SharedString>> {        Ok(vec![])    }} /// A unique identifier for the image cache#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]pub struct ImageId(pub usize); #[derive(PartialEq, Eq, Hash, Clone)]pub(crate) struct RenderImageParams {    pub(crate) image_id: ImageId,    pub(crate) frame_index: usize,} /// A cached and processed image, in BGRA formatpub struct RenderImage {    /// The ID associated with this image    pub id: ImageId,    data: SmallVec<[Frame; 1]>,} impl PartialEq for RenderImage {    fn eq(&self, other: &Self) -> bool {        self.id == other.id    }} impl Eq for RenderImage {} impl RenderImage {    /// Create a new image from the given data.    pub fn new(data: impl Into<SmallVec<[Frame; 1]>>) -> Self {        static NEXT_ID: AtomicUsize = AtomicUsize::new(0);         Self {            id: ImageId(NEXT_ID.fetch_add(1, SeqCst)),            data: data.into(),        }    }     /// Convert this image into a byte slice.    pub fn as_bytes(&self, frame_index: usize) -> Option<&[u8]> {        self.data            .get(frame_index)            .map(|frame| frame.buffer().as_raw().as_slice())    }     /// Get the size of this image, in pixels.    pub fn size(&self, frame_index: usize) -> Size<DevicePixels> {        let (width, height) = self.data[frame_index].buffer().dimensions();        size(width.into(), height.into())    }     /// Get the delay of this frame from the previous    pub fn delay(&self, frame_index: usize) -> Delay {        self.data[frame_index].delay()    }     /// Get the number of frames for this image.    pub fn frame_count(&self) -> usize {        self.data.len()    }} impl fmt::Debug for RenderImage {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        f.debug_struct("ImageData")            .field("id", &self.id)            .field("size", &self.size(0))            .finish()    }}