use super::ffi;
use std::{fmt::Debug, hash::Hash, mem::MaybeUninit, ops::Deref};
pub struct ClipperImage(pub(crate) ffi::ClipperImage);
impl ClipperImage {
#[inline(always)]
pub fn width(&self) -> u32 {
self.0.width
}
#[inline(always)]
pub fn height(&self) -> u32 {
self.0.height
}
pub(crate) fn size(&self) -> usize {
(self.0.width * self.0.height * 4) as usize
}
pub fn rgba(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.0.rgba, self.size()) }
}
}
impl From<ClipperImage> for Vec<u8> {
fn from(img: ClipperImage) -> Self {
img.as_ref().to_vec()
}
}
impl From<ClipperImage> for Box<[u8]> {
fn from(img: ClipperImage) -> Self {
img.as_ref().into()
}
}
impl AsRef<[u8]> for ClipperImage {
fn as_ref(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.0.rgba, self.size()) }
}
}
impl Deref for ClipperImage {
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl Debug for ClipperImage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ClipperImage")
.field("width", &self.width())
.field("height", &self.height())
.field("rgba", &self.as_ref())
.finish()
}
}
impl Drop for ClipperImage {
fn drop(&mut self) {
unsafe {
ffi::clipper_free_tagged_data(ffi::TaggedClipperData {
tag: ffi::ClipperTag::Image,
data: MaybeUninit::new(ffi::ClipperData { image: self.0 }),
})
}
}
}
impl Eq for ClipperImage {}
impl PartialEq for ClipperImage {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.as_ref() == other.as_ref()
}
}
impl PartialEq<[u8]> for ClipperImage {
fn eq(&self, other: &[u8]) -> bool {
self.as_ref() == other
}
}
impl PartialEq<ClipperImage> for [u8] {
fn eq(&self, other: &ClipperImage) -> bool {
self == other.as_ref()
}
}
impl PartialEq<Vec<u8>> for ClipperImage {
fn eq(&self, other: &Vec<u8>) -> bool {
self.as_ref() == other.as_slice()
}
}
impl PartialEq<ClipperImage> for Vec<u8> {
fn eq(&self, other: &ClipperImage) -> bool {
self.as_slice() == other.as_ref()
}
}
impl Ord for ClipperImage {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_ref().cmp(other.as_ref())
}
}
impl PartialOrd for ClipperImage {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl PartialOrd<[u8]> for ClipperImage {
fn partial_cmp(&self, other: &[u8]) -> Option<std::cmp::Ordering> {
Some(self.as_ref().cmp(other))
}
}
impl PartialOrd<ClipperImage> for [u8] {
fn partial_cmp(&self, other: &ClipperImage) -> Option<std::cmp::Ordering> {
Some(self.cmp(other.as_ref()))
}
}
impl PartialOrd<Vec<u8>> for ClipperImage {
fn partial_cmp(&self, other: &Vec<u8>) -> Option<std::cmp::Ordering> {
Some(self.as_ref().cmp(other.as_slice()))
}
}
impl PartialOrd<ClipperImage> for Vec<u8> {
fn partial_cmp(&self, other: &ClipperImage) -> Option<std::cmp::Ordering> {
Some(self.as_slice().cmp(other.as_ref()))
}
}
impl Hash for ClipperImage {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_ref().hash(state)
}
}