1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use rich_sdl2_rust::{
surface::{RawSurface, Surface},
Result, Sdl, SdlError,
};
use static_assertions::assert_not_impl_all;
use std::{
ffi::{CStr, CString},
marker::PhantomData,
os::raw::c_char,
ptr::NonNull,
};
use crate::{bind, Img};
pub struct ImgSurface<'img> {
surface: NonNull<RawSurface>,
_phantom: PhantomData<&'img ()>,
}
assert_not_impl_all!(ImgSurface: Send, Sync);
impl<'img> ImgSurface<'img> {
pub fn new(_img: &'img Img, file_name: &str, file_type: Option<&str>) -> Result<Self> {
let file_name_cstr = CString::new(file_name).expect("file_name mus not be empty");
let mode = CStr::from_bytes_with_nul(b"rb\0").unwrap();
let fp = unsafe { bind::SDL_RWFromFile(file_name_cstr.as_ptr(), mode.as_ptr()) };
let file_type_cstr = file_type
.map(|file_type| CString::new(file_type).expect("file_name must not be empty"));
let ptr = unsafe {
bind::IMG_LoadTyped_RW(
fp,
1,
file_type_cstr.map_or(std::ptr::null(), |cstr| cstr.as_ptr()),
)
};
if ptr.is_null() {
Err(SdlError::Others { msg: Sdl::error() })
} else {
Ok(Self {
surface: NonNull::new(ptr.cast()).unwrap(),
_phantom: PhantomData,
})
}
}
pub fn from_xpm(_img: &'img Img, xpm: &[&str]) -> Result<Self> {
let xpm: Vec<_> = xpm
.iter()
.map(|&s| CString::new(s).expect("xpm fragment must not be empty"))
.collect();
let xpm_ptr: Vec<_> = xpm.iter().map(|s| s.as_ptr() as *mut c_char).collect();
let ptr = unsafe { bind::IMG_ReadXPMFromArray(xpm_ptr.as_ptr() as *mut _) };
if ptr.is_null() {
Err(SdlError::Others { msg: Sdl::error() })
} else {
Ok(Self {
surface: NonNull::new(ptr.cast()).unwrap(),
_phantom: PhantomData,
})
}
}
}
impl Surface for ImgSurface<'_> {
fn as_ptr(&self) -> NonNull<RawSurface> {
self.surface
}
}
impl Drop for ImgSurface<'_> {
fn drop(&mut self) {
unsafe { bind::SDL_FreeSurface(self.surface.as_ptr().cast()) }
}
}