use super::validation::{require_exact_payload, validate_new_texture_layout};
use super::{TextureData, TextureDataError, TextureFormat};
use crate::sys;
use std::ptr::NonNull;
pub struct OwnedTextureData {
raw: NonNull<sys::ImTextureData>,
}
impl OwnedTextureData {
pub(crate) fn empty() -> Self {
let raw = unsafe { sys::ImTextureData_ImTextureData() };
let raw = NonNull::new(raw).expect("ImTextureData_ImTextureData() returned null");
Self { raw }
}
pub fn from_pixels(
format: TextureFormat,
width: u32,
height: u32,
pixels: &[u8],
) -> Result<Self, TextureDataError> {
let layout = validate_new_texture_layout(format, width, height)?;
require_exact_payload(layout.byte_len, pixels.len())?;
let mut texture = Self::empty();
unsafe {
sys::ImTextureData_Create(
texture.raw.as_ptr(),
format.into(),
i32::try_from(width).expect("validated texture width must fit i32"),
i32::try_from(height).expect("validated texture height must fit i32"),
);
}
texture.replace_pixels(pixels)?;
Ok(texture)
}
pub fn into_raw(self) -> *mut sys::ImTextureData {
let raw = self.raw.as_ptr();
std::mem::forget(self);
raw
}
pub unsafe fn from_raw_owned(raw: *mut sys::ImTextureData) -> Self {
let raw = NonNull::new(raw).expect("raw ImTextureData pointer was null");
Self { raw }
}
}
impl Drop for OwnedTextureData {
fn drop(&mut self) {
unsafe { sys::ImTextureData_destroy(self.raw.as_ptr()) }
}
}
impl std::ops::Deref for OwnedTextureData {
type Target = TextureData;
fn deref(&self) -> &Self::Target {
unsafe { &*(self.raw.as_ptr() as *const TextureData) }
}
}
impl std::ops::DerefMut for OwnedTextureData {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self.raw.as_ptr() as *mut TextureData) }
}
}
impl AsRef<TextureData> for OwnedTextureData {
fn as_ref(&self) -> &TextureData {
self
}
}
impl AsMut<TextureData> for OwnedTextureData {
fn as_mut(&mut self) -> &mut TextureData {
self
}
}