use super::{Blob, Extend};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum ImageFormat {
Rgba8 = 0,
Bgra8 = 1,
}
impl ImageFormat {
#[must_use]
pub fn size_in_bytes(self, width: u32, height: u32) -> Option<usize> {
match self {
Self::Rgba8 | Self::Bgra8 => 4_usize
.checked_mul(width as usize)
.and_then(|x| x.checked_mul(height as usize)),
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u8)]
pub enum ImageAlphaType {
Alpha = 0,
AlphaPremultiplied = 1,
}
#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u8)]
pub enum ImageQuality {
Low = 0,
#[default]
Medium = 1,
High = 2,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImageData {
pub data: Blob<u8>,
pub format: ImageFormat,
pub alpha_type: ImageAlphaType,
pub width: u32,
pub height: u32,
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImageSampler {
pub x_extend: Extend,
pub y_extend: Extend,
pub quality: ImageQuality,
pub alpha: f32,
}
impl Default for ImageSampler {
fn default() -> Self {
Self {
x_extend: Extend::Pad,
y_extend: Extend::Pad,
quality: ImageQuality::Medium,
alpha: 1., }
}
}
impl ImageSampler {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_extend(mut self, mode: Extend) -> Self {
self.x_extend = mode;
self.y_extend = mode;
self
}
#[must_use]
pub fn with_x_extend(mut self, mode: Extend) -> Self {
self.x_extend = mode;
self
}
#[must_use]
pub fn with_y_extend(mut self, mode: Extend) -> Self {
self.y_extend = mode;
self
}
#[must_use]
pub fn with_quality(mut self, quality: ImageQuality) -> Self {
self.quality = quality;
self
}
#[must_use]
#[track_caller]
pub fn with_alpha(mut self, alpha: f32) -> Self {
debug_assert!(
alpha.is_finite() && alpha >= 0.0,
"A non-finite or negative alpha ({alpha}) is meaningless."
);
self.alpha = alpha;
self
}
#[must_use]
#[track_caller]
pub fn multiply_alpha(mut self, alpha: f32) -> Self {
debug_assert!(
alpha.is_finite() && alpha >= 0.0,
"A non-finite or negative alpha ({alpha}) is meaningless."
);
self.alpha *= alpha;
self
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImageBrush<D = ImageData> {
pub image: D,
pub sampler: ImageSampler,
}
impl<D> ImageBrush<D> {
#[must_use]
pub fn with_extend(mut self, mode: Extend) -> Self {
self.sampler.x_extend = mode;
self.sampler.y_extend = mode;
self
}
#[must_use]
pub fn with_x_extend(mut self, mode: Extend) -> Self {
self.sampler.x_extend = mode;
self
}
#[must_use]
pub fn with_y_extend(mut self, mode: Extend) -> Self {
self.sampler.y_extend = mode;
self
}
#[must_use]
pub fn with_quality(mut self, quality: ImageQuality) -> Self {
self.sampler.quality = quality;
self
}
#[must_use]
#[track_caller]
pub fn with_alpha(mut self, alpha: f32) -> Self {
debug_assert!(
alpha.is_finite() && alpha >= 0.0,
"A non-finite or negative alpha ({alpha}) is meaningless."
);
self.sampler.alpha = alpha;
self
}
#[must_use]
#[track_caller]
pub fn multiply_alpha(mut self, alpha: f32) -> Self {
debug_assert!(
alpha.is_finite() && alpha >= 0.0,
"A non-finite or negative alpha ({alpha}) is meaningless."
);
self.sampler.alpha *= alpha;
self
}
}
impl ImageBrush {
#[must_use]
pub fn new(image: ImageData) -> Self {
Self {
image,
sampler: ImageSampler::default(),
}
}
#[must_use]
pub fn as_ref(&'_ self) -> ImageBrushRef<'_> {
ImageBrush {
image: &self.image,
sampler: self.sampler,
}
}
}
impl From<ImageData> for ImageBrush {
fn from(image: ImageData) -> Self {
Self::new(image)
}
}
pub type ImageBrushRef<'a> = ImageBrush<&'a ImageData>;
impl ImageBrushRef<'_> {
#[must_use]
pub fn to_owned(&self) -> ImageBrush {
ImageBrush {
image: (*self.image).clone(),
sampler: self.sampler,
}
}
}
impl<'a> From<&'a ImageBrush> for ImageBrushRef<'a> {
fn from(value: &'a ImageBrush) -> Self {
value.as_ref()
}
}
impl<'a> From<&'a ImageData> for ImageBrushRef<'a> {
fn from(image: &'a ImageData) -> Self {
Self {
image,
sampler: ImageSampler::default(),
}
}
}