beryllium 0.13.3

Opinionated wrapper for `fermium`.
Documentation
use crate::{
  error::{get_error, SdlError},
  init::SdlInit,
  Sdl,
};
use alloc::sync::Arc;
use core::ptr::NonNull;
use fermium::prelude::*;
use pixel_formats::r8g8b8a8_Srgb;

#[repr(C)]
pub struct Surface {
  pub(crate) surf: NonNull<SDL_Surface>,
  pub(crate) parent: Arc<SdlInit>,
}
impl Drop for Surface {
  #[inline]
  fn drop(&mut self) {
    unsafe { SDL_FreeSurface(self.surf.as_ptr()) };
  }
}
impl Sdl {
  #[inline]
  pub fn create_surface_from(
    &self, pixels: &[r8g8b8a8_Srgb], width: i32, height: i32,
  ) -> Result<Surface, SdlError> {
    if width <= 0
      || height <= 0
      || width.checked_mul(height).unwrap_or_default() as usize != pixels.len()
    {
      return Err(SdlError::new("illegal input dimensions"));
    }
    let depth = 32;
    let pitch = width * 4;
    const R_MASK: u32 = unsafe { core::mem::transmute(r8g8b8a8_Srgb { r: 255, g: 0, b: 0, a: 0 }) };
    const G_MASK: u32 = unsafe { core::mem::transmute(r8g8b8a8_Srgb { g: 255, r: 0, b: 0, a: 0 }) };
    const B_MASK: u32 = unsafe { core::mem::transmute(r8g8b8a8_Srgb { b: 255, g: 0, r: 0, a: 0 }) };
    const A_MASK: u32 = unsafe { core::mem::transmute(r8g8b8a8_Srgb { a: 255, g: 0, b: 0, r: 0 }) };
    let p = unsafe {
      SDL_CreateRGBSurfaceFrom(
        pixels.as_ptr() as *mut c_void,
        width,
        height,
        depth,
        pitch,
        R_MASK,
        G_MASK,
        B_MASK,
        A_MASK,
      )
    };
    match NonNull::new(p) {
      Some(surf) => Ok(Surface { surf, parent: self.init.clone() }),
      None => Err(get_error()),
    }
  }
}