1use core::ffi::c_char;
4use core::ffi::c_float;
5use core::ffi::c_int;
6use core::fmt::Write;
7use core::marker::PhantomData;
8use alloc::boxed::Box;
9
10use sys::error::NullPtrError;
11use sys::error::OkMutOrNullErr;
12use sys::error::OkOrNullFnErr;
13use sys::ffi::LCDPattern;
14use sys::ffi::LCDSolidColor;
15use sys::traits::AsRaw;
16use sys::ffi::CString;
17use sys::ffi::LCDColor;
18use sys::ffi::LCDRect;
19use sys::ffi::LCDBitmap;
20use fs::Path;
21
22use crate::Graphics;
23use crate::error::ApiError;
24use crate::error::Error;
25use super::api;
26
27pub use color::*;
28pub use sys::ffi::LCDBitmapFlip as BitmapFlip;
29pub use sys::ffi::LCDBitmapDrawMode as BitmapDrawMode;
30pub use crate::{BitmapFlipExt, BitmapDrawModeExt};
31
32
33pub trait AnyBitmap: AsRaw<Type = LCDBitmap> + BitmapApi {}
34impl<T: AnyBitmap> AnyBitmap for &'_ T {}
35impl AnyBitmap for BitmapRef<'_> {}
36impl<Api: api::Api, const FOD: bool> AnyBitmap for Bitmap<Api, FOD> {}
37
38
39pub trait BitmapApi {
40 type Api: api::Api;
41 fn api(&self) -> Self::Api
42 where Self::Api: Copy;
43 fn api_ref(&self) -> &Self::Api;
44}
45
46impl BitmapApi for BitmapRef<'_> {
47 type Api = api::Default;
48
49 fn api(&self) -> Self::Api
50 where Self::Api: Copy {
51 api::Default::default()
52 }
53
54 fn api_ref(&self) -> &Self::Api { &self.1 }
55}
56
57impl<Api: api::Api, const FOD: bool> BitmapApi for Bitmap<Api, FOD> {
58 type Api = Api;
59 fn api(&self) -> Api
60 where Self::Api: Copy {
61 self.1
62 }
63
64 fn api_ref(&self) -> &Self::Api { &self.1 }
65}
66
67impl<T: BitmapApi> BitmapApi for &'_ T {
68 type Api = T::Api;
69
70 fn api(&self) -> Self::Api
71 where Self::Api: Copy {
72 (*self).api()
73 }
74
75 fn api_ref(&self) -> &Self::Api { (*self).api_ref() }
76}
77
78
79#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
80pub struct Bitmap<Api: api::Api = api::Default, const FREE_ON_DROP: bool = true>(pub(crate) *mut LCDBitmap,
81 pub(crate) Api);
82
83impl<Api: api::Api, const FOD: bool> AsRaw for Bitmap<Api, FOD> {
84 type Type = LCDBitmap;
85 unsafe fn as_raw(&self) -> *mut LCDBitmap { self.0 }
86}
87
88impl<Api: api::Api + Default, const FOD: bool> From<*mut LCDBitmap> for Bitmap<Api, FOD> {
89 fn from(ptr: *mut LCDBitmap) -> Self { Self(ptr, Api::default()) }
90}
91
92impl<Api: api::Api + Copy> Bitmap<Api, true> {
93 pub fn into_shared(mut self) -> Bitmap<Api, false> {
98 let res = Bitmap(self.0, self.1);
99 self.0 = core::ptr::null_mut();
100 res
101 }
102}
103
104
105#[repr(transparent)]
106pub struct BitmapRef<'owner>(*mut LCDBitmap, api::Default, PhantomData<&'owner ()>);
107
108impl AsRaw for BitmapRef<'_> {
109 type Type = LCDBitmap;
110 unsafe fn as_raw(&self) -> *mut LCDBitmap { self.0 }
111}
112
113impl From<*mut LCDBitmap> for BitmapRef<'_> {
114 fn from(ptr: *mut LCDBitmap) -> Self { Self(ptr, Default::default(), PhantomData) }
115}
116
117impl<'owner> BitmapRef<'owner> {
118 pub fn into_bitmap(self) -> Result<Bitmap<<Self as BitmapApi>::Api, false>, NullPtrError> {
119 let ptr = unsafe { self.as_raw() }.ok_or_null()?;
120 Ok(Bitmap(ptr, self.api()))
121 }
122
123 pub fn into_bitmap_with<Api: api::Api>(self, api: Api) -> Result<Bitmap<Api, false>, NullPtrError> {
124 let ptr = unsafe { self.as_raw() }.ok_or_null()?;
125 Ok(Bitmap(ptr, api))
126 }
127
128 pub fn null() -> Self { Self::from(core::ptr::null_mut()) }
129}
130
131
132impl<Api: api::Api> Bitmap<Api, true> {
133 #[doc(alias = "sys::ffi::playdate_graphics::newBitmap")]
137 pub fn new(width: c_int, height: c_int, bg: Color) -> Result<Self, Error>
138 where Api: Default {
139 let api = Api::default();
140 Self::new_with(api, width, height, bg)
141 }
142
143 #[doc(alias = "sys::ffi::playdate_graphics::newBitmap")]
148 pub fn new_with(api: Api, width: c_int, height: c_int, bg: Color) -> Result<Self, Error> {
149 let f = api.new_bitmap();
150 let ptr = unsafe { f(width, height, bg.into()) };
151 if ptr.is_null() {
152 Err(Error::Alloc)
153 } else {
154 Ok(Self(ptr, api))
155 }
156 }
157
158
159 #[doc(alias = "sys::ffi::playdate_graphics::loadBitmap")]
163 pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, ApiError>
164 where Api: Default {
165 let api = Api::default();
166 Self::load_with(api, path)
167 }
168
169 #[doc(alias = "sys::ffi::playdate_graphics::loadBitmap")]
174 pub fn load_with<P: AsRef<Path>>(api: Api, path: P) -> Result<Self, ApiError> {
175 let mut err = Box::new(core::ptr::null() as *const c_char);
176 let out_err = Box::into_raw(err);
177
178 let path = CString::new(path.as_ref())?;
179
180 let f = api.load_bitmap();
181 let ptr = unsafe { f(path.as_ptr() as *mut c_char, out_err as _) };
182 if ptr.is_null() {
183 err = unsafe { Box::from_raw(out_err) };
184 if let Some(err) = fs::error::Error::from_ptr(*err) {
185 Err(Error::Fs(err).into())
186 } else {
187 Err(Error::Alloc.into())
188 }
189 } else {
190 Ok(Self(ptr, api))
191 }
192 }
193}
194
195
196impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
197 #[doc(alias = "sys::ffi::playdate_graphics::loadIntoBitmap")]
201 pub fn load_into<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ApiError> {
202 let mut err = Box::new(core::ptr::null() as *const c_char);
203 let out_err = Box::into_raw(err);
204
205 let path = CString::new(path.as_ref())?;
206
207 let f = self.1.load_into_bitmap();
208 unsafe { f(path.as_ptr() as *mut c_char, self.0, out_err as _) };
209 err = unsafe { Box::from_raw(out_err) };
210 if let Some(err) = fs::error::Error::from_ptr(*err) {
211 Err(Error::Fs(err).into())
212 } else {
213 Ok(())
214 }
215 }
216}
217
218
219impl<Api: api::Api, const FOD: bool> Drop for Bitmap<Api, FOD> {
220 fn drop(&mut self) {
221 if FOD && !self.0.is_null() {
222 let f = self.1.free_bitmap();
223 unsafe { f(self.0) };
224 self.0 = core::ptr::null_mut();
225 }
226 }
227}
228
229impl<Api: api::Api + Clone> Clone for Bitmap<Api, true> {
230 #[doc(alias = "sys::ffi::playdate_graphics::copyBitmap")]
235 fn clone(&self) -> Self {
236 let f = self.1.copy_bitmap();
237 let ptr = unsafe { f(self.0) };
238 if ptr.is_null() {
239 panic!("{}: bitmap clone", Error::Alloc)
240 } else {
241 Self(ptr, self.1.clone())
242 }
243 }
244}
245
246
247impl<Api: api::Api, const FOD: bool> Bitmap<Api, FOD> {
248 #[doc(alias = "sys::ffi::playdate_graphics::clearBitmap")]
252 pub fn clear(&self, bg: Color) {
253 let f = self.1.clear_bitmap();
254 unsafe { f(self.0, bg.into()) };
255 }
256
257
258 #[doc(alias = "sys::ffi::playdate_graphics::getBitmapData")]
264 pub fn size(&self) -> (c_int, c_int) {
265 let mut width: c_int = 0;
266 let mut height: c_int = 0;
267 let mut row_bytes: c_int = 0;
268
269 let f = self.1.get_bitmap_data();
270 unsafe {
271 f(
272 self.0,
273 &mut width,
274 &mut height,
275 &mut row_bytes,
276 core::ptr::null_mut(),
277 core::ptr::null_mut(),
278 )
279 };
280
281 (width, height)
282 }
283
284 #[doc(alias = "sys::ffi::playdate_graphics::getBitmapData")]
288 pub fn bitmap_data<'bitmap>(&'bitmap mut self) -> BitmapData<'bitmap> {
289 let mut width: c_int = 0;
290 let mut height: c_int = 0;
291 let mut row_bytes: c_int = 0;
292
293
294 let mut boxed_data = Box::new(core::ptr::null_mut());
295 let data = Box::into_raw(boxed_data);
296 let mut boxed_mask = Box::new(core::ptr::null_mut());
297 let mask = Box::into_raw(boxed_mask);
298
299 let f = self.1.get_bitmap_data();
300 unsafe { f(self.0, &mut width, &mut height, &mut row_bytes, mask, data) };
301
302 let len = row_bytes * height;
303
304 boxed_data = unsafe { Box::from_raw(data) };
305 boxed_mask = unsafe { Box::from_raw(mask) };
306
307 let mask = {
309 if !boxed_mask.is_null() && !(*boxed_mask).is_null() {
310 let mask = unsafe { core::slice::from_raw_parts_mut::<u8>(*boxed_mask, len as usize) };
311 Some(mask)
312 } else {
313 None
314 }
315 };
316
317 let data = unsafe { core::slice::from_raw_parts_mut::<u8>(*boxed_data, len as usize) };
319
320 BitmapData { width,
321 height,
322 row_bytes,
323 mask,
324 data }
325 }
326
327
328 #[doc(alias = "sys::ffi::playdate_graphics::setBitmapMask")]
333 pub fn set_mask<Api2: api::Api, const FREE: bool>(&self, mask: &mut Bitmap<Api2, FREE>) -> Result<(), Error> {
334 let f = self.1.set_bitmap_mask();
336 let res = unsafe { f(self.0, mask.0) };
337 if res == 0 { Ok(()) } else { Err(Error::InvalidMask) }
338 }
339
340 #[doc(alias = "sys::ffi::playdate_graphics::getBitmapMask")]
347 #[inline(always)]
348 pub fn mask(&self) -> Option<Bitmap<Api, false>>
349 where Api: Clone {
350 self.mask_with(self.1.clone())
351 }
352
353 #[doc(alias = "sys::ffi::playdate_graphics::getBitmapMask")]
360 pub fn mask_with<NewApi: api::Api>(&self, api: NewApi) -> Option<Bitmap<NewApi, false>> {
362 let f = self.1.get_bitmap_mask();
363 let ptr = unsafe { f(self.0) };
364 if !ptr.is_null() {
365 Some(Bitmap(ptr, api))
366 } else {
367 None
368 }
369 }
370
371 #[doc(alias = "sys::ffi::playdate_graphics::rotatedBitmap")]
375 #[inline(always)]
376 pub fn rotated_clone(&self,
377 rotation: c_float,
378 x_scale: c_float,
379 y_scale: c_float)
380 -> Result<Bitmap<Api, true>, Error>
381 where Api: Clone
382 {
383 self.rotated_clone_with(self.1.clone(), rotation, x_scale, y_scale)
384 }
385
386 #[doc(alias = "sys::ffi::playdate_graphics::rotatedBitmap")]
390 pub fn rotated_clone_with<NewApi: api::Api>(&self,
391 api: NewApi,
392 rotation: c_float,
393 x_scale: c_float,
394 y_scale: c_float)
395 -> Result<Bitmap<NewApi, true>, Error>
396 where Api: Clone
397 {
398 let mut alloced_size: c_int = 0;
399 let alloced_size_ref = &mut alloced_size;
400 let f = self.1.rotated_bitmap();
401 let ptr = unsafe { f(self.0, rotation, x_scale, y_scale, alloced_size_ref) };
402
403 if alloced_size == 0 || ptr.is_null() {
404 Err(Error::Alloc)
405 } else {
406 Ok(Bitmap(ptr, api))
407 }
408 }
409
410
411 #[doc(alias = "sys::ffi::playdate_graphics::drawBitmap")]
416 #[inline(always)]
417 pub fn draw(&self, x: c_int, y: c_int, flip: BitmapFlip) {
418 let f = self.1.draw_bitmap();
419 unsafe { f(self.0, x, y, flip) }
420 }
421
422 #[doc(alias = "sys::ffi::playdate_graphics::tileBitmap")]
427 #[inline(always)]
428 pub fn draw_tiled(&self, x: c_int, y: c_int, width: c_int, height: c_int, flip: BitmapFlip) {
429 let f = self.1.tile_bitmap();
430 unsafe { f(self.0, x, y, width, height, flip) }
431 }
432
433 #[doc(alias = "sys::ffi::playdate_graphics::drawRotatedBitmap")]
442 #[inline(always)]
443 pub fn draw_rotated(&self,
444 x: c_int,
445 y: c_int,
446 degrees: c_float,
447 center_x: c_float,
448 center_y: c_float,
449 x_scale: c_float,
450 y_scale: c_float) {
451 let f = self.1.draw_rotated_bitmap();
452 unsafe { f(self.0, x, y, degrees, center_x, center_y, x_scale, y_scale) }
453 }
454
455 #[doc(alias = "sys::ffi::playdate_graphics::drawScaledBitmap")]
461 #[inline(always)]
462 pub fn draw_scaled(&self, x: c_int, y: c_int, x_scale: c_float, y_scale: c_float) {
463 let f = self.1.draw_scaled_bitmap();
464 unsafe { f(self.0, x, y, x_scale, y_scale) }
465 }
466
467
468 #[doc(alias = "sys::ffi::playdate_graphics::checkMaskCollision")]
475 #[inline(always)]
476 pub fn check_mask_collision<OApi: api::Api, const OFOD: bool>(&self,
477 x: c_int,
478 y: c_int,
479 flip: BitmapFlip,
480 other: Bitmap<OApi, OFOD>,
481 x_other: c_int,
482 y_other: c_int,
483 flip_other: BitmapFlip,
484 rect: LCDRect)
485 -> bool {
486 let f = self.1.check_mask_collision();
487 unsafe { f(self.0, x, y, flip, other.0, x_other, y_other, flip_other, rect) == 1 }
488 }
489
490
491 #[doc(alias = "sys::ffi::playdate_graphics::setColorToPattern")]
499 pub fn pattern_at(&self, x: c_int, y: c_int) -> LCDPattern {
500 let mut color = LCDColor::default();
501 let f = self.1.set_color_to_pattern();
502
503 unsafe {
504 f(core::ptr::addr_of_mut!(color), self.0, x, y);
505 *(color as *mut u8 as *mut LCDPattern)
506 }
507 }
508
509 #[doc(alias = "sys::ffi::playdate_graphics::setColorToPattern")]
518 pub fn set_color_to_pattern(&self, color: &mut LCDColor, x: c_int, y: c_int) {
519 let f = self.1.set_color_to_pattern();
520 unsafe { f(color as _, self.0, x, y) }
521 }
522
523 #[doc(alias = "sys::ffi::playdate_graphics::getBitmapPixel")]
531 #[inline(always)]
532 pub fn pixel_at(&self, x: c_int, y: c_int) -> LCDSolidColor {
533 let f = self.1.get_pixel();
534 unsafe { f(self.0, x, y) }
535 }
536}
537
538
539pub struct BitmapData<'bitmap> {
544 pub width: c_int,
545 pub height: c_int,
546 pub row_bytes: c_int,
547 mask: Option<&'bitmap mut [u8]>,
548 data: &'bitmap mut [u8],
549}
550
551impl<'bitmap> BitmapData<'bitmap> {
552 pub const fn width(&self) -> c_int { self.width }
553 pub const fn height(&self) -> c_int { self.height }
554 pub const fn row_bytes(&self) -> c_int { self.row_bytes }
555 pub fn mask(&self) -> Option<&[u8]> { self.mask.as_deref() }
556 pub fn mask_mut(&mut self) -> Option<&mut [u8]> { self.mask.as_deref_mut() }
557 pub const fn data(&self) -> &[u8] { self.data }
558 pub fn data_mut(&mut self) -> &mut [u8] { self.data }
559}
560
561impl core::fmt::Display for BitmapData<'_> {
562 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
563 write!(f, "BitmapData({}, {}", self.width(), self.height())?;
564 if self.mask.is_some() {
565 write!(f, ", masked)")
566 } else {
567 write!(f, ")")
568 }
569 }
570}
571
572impl core::fmt::Debug for BitmapData<'_> {
573 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
574 let alternate = f.alternate();
575 if alternate {
576 let fmt_bd = |f: &mut core::fmt::Formatter<'_>, data: &[u8], row_len: c_int| {
577 for (i, b) in data.iter().enumerate() {
578 if i % row_len as usize == 0 {
579 f.write_char('\n')?;
580 f.write_char('\t')?;
581 }
582 f.write_fmt(format_args!("{b:08b} "))?;
583 }
584 Ok(())
585 };
586
587 write!(f, "BitmapData({}, {}", self.width(), self.height())?;
588 if self.mask.is_some() {
589 write!(f, ", masked")?;
590 }
591 write!(f, ", data:")?;
592 fmt_bd(f, self.data, self.row_bytes)?;
593 write!(f, ")")
594 } else {
595 let mut res = f.debug_struct("BitmapData");
596 res.field("width", &self.width)
597 .field("height", &self.height)
598 .field("row_bytes", &self.row_bytes);
599 res.field("data", &self.data).field("mask", &self.mask).finish()
600 }
601 }
602}
603
604
605#[doc(alias = "sys::ffi::playdate_graphics::getDebugBitmap")]
619#[inline(always)]
620pub fn debug_bitmap() -> Result<Bitmap<api::Default, false>, ApiError> { Graphics::Default().debug_bitmap() }
621
622#[doc(alias = "sys::ffi::playdate_graphics::getDisplayBufferBitmap")]
631#[inline(always)]
632pub fn display_buffer_bitmap() -> Result<Bitmap<api::Default, false>, Error> {
633 Graphics::Default().display_buffer_bitmap()
634}
635
636#[doc(alias = "sys::ffi::playdate_graphics::copyFrameBufferBitmap")]
645#[inline(always)]
646pub fn copy_frame_buffer_bitmap() -> Result<Bitmap<api::Default, true>, Error> {
647 Graphics::Default().frame_buffer_bitmap()
648}
649
650
651#[doc(alias = "sys::ffi::playdate_graphics::setStencilImage")]
662#[inline(always)]
663pub fn set_stencil_tiled(image: &impl AnyBitmap, tile: bool) {
664 Graphics::Default().set_stencil_tiled(image, tile)
665}
666
667#[doc(alias = "sys::ffi::playdate_graphics::setStencil")]
677#[inline(always)]
678pub fn set_stencil(image: &impl AnyBitmap) { Graphics::Default().set_stencil(image) }
679
680#[doc(alias = "sys::ffi::playdate_graphics::setDrawMode")]
689#[inline(always)]
690pub fn set_draw_mode(mode: BitmapDrawMode) -> BitmapDrawMode { Graphics::Default().set_draw_mode(mode) }
691
692#[doc(alias = "sys::ffi::playdate_graphics::pushContext")]
703#[inline(always)]
704pub fn push_context(target: &impl AnyBitmap) { Graphics::Default().push_context(target) }
705
706#[doc(alias = "sys::ffi::playdate_graphics::pushContext")]
713#[inline(always)]
714pub fn push_framebuffer_to_context() { Graphics::Default().push_framebuffer_to_context() }
715
716#[doc(alias = "sys::ffi::playdate_graphics::popContext")]
724#[inline(always)]
725pub fn pop_context() { Graphics::Default().pop_context() }
726
727
728impl<Api: crate::api::Api> Graphics<Api> {
729 #[doc(alias = "sys::ffi::playdate_graphics::getDebugBitmap")]
736 pub fn debug_bitmap(&self) -> Result<Bitmap<api::Default, false>, ApiError> {
737 let f = self.0.get_debug_bitmap().ok_or_null()?;
738 let ptr = unsafe { f() };
739 if ptr.is_null() {
740 Err(Error::Alloc.into())
741 } else {
742 Ok(Bitmap(ptr, Default::default()))
743 }
744 }
745
746 #[doc(alias = "sys::ffi::playdate_graphics::getDisplayBufferBitmap")]
752 pub fn display_buffer_bitmap(&self) -> Result<Bitmap<api::Default, false>, Error> {
753 let f = self.0.get_display_buffer_bitmap();
754 let ptr = unsafe { f() };
755 if ptr.is_null() {
756 Err(Error::Alloc)
757 } else {
758 Ok(Bitmap(ptr, Default::default()))
759 }
760 }
761
762 #[doc(alias = "sys::ffi::playdate_graphics::copyFrameBufferBitmap")]
768 pub fn frame_buffer_bitmap(&self) -> Result<Bitmap<api::Default, true>, Error> {
769 let f = self.0.copy_frame_buffer_bitmap();
770 let ptr = unsafe { f() };
771 if ptr.is_null() {
772 Err(Error::Alloc)
773 } else {
774 Ok(Bitmap(ptr, Default::default()))
775 }
776 }
777
778
779 #[doc(alias = "sys::ffi::playdate_graphics::setStencilImage")]
787 pub fn set_stencil_tiled(&self, image: &impl AnyBitmap, tile: bool) {
788 let f = self.0.set_stencil_image();
789 unsafe { f(image.as_raw(), tile as _) };
790 }
791
792 #[doc(alias = "sys::ffi::playdate_graphics::setStencil")]
799 pub fn set_stencil(&self, image: &impl AnyBitmap) {
800 let f = self.0.set_stencil();
801 unsafe { f(image.as_raw()) };
802 }
803
804 #[doc(alias = "sys::ffi::playdate_graphics::setDrawMode")]
812 pub fn set_draw_mode(&self, mode: BitmapDrawMode) -> BitmapDrawMode {
813 let f = self.0.set_draw_mode();
814 unsafe { f(mode) }
815 }
816
817 #[doc(alias = "sys::ffi::playdate_graphics::pushContext")]
825 pub fn push_context(&self, target: &impl AnyBitmap) {
826 let f = self.0.push_context();
827 unsafe { f(target.as_raw()) };
828 }
829
830 #[doc(alias = "sys::ffi::playdate_graphics::pushContext")]
834 pub fn push_framebuffer_to_context(&self) {
835 let f = self.0.push_context();
836 unsafe { f(core::ptr::null_mut()) };
837 }
838
839 #[doc(alias = "sys::ffi::playdate_graphics::popContext")]
844 pub fn pop_context(&self) {
845 let f = self.0.pop_context();
846 unsafe { f() };
847 }
848}
849
850
851impl<Api: crate::api::Api> Graphics<Api> {
852 #[doc(alias = "sys::ffi::playdate_graphics::drawBitmap")]
857 #[inline(always)]
858 pub fn draw(&self, bitmap: &impl AnyBitmap, x: c_int, y: c_int, flip: BitmapFlip) {
859 let f = self.0.draw_bitmap();
860 unsafe { f(bitmap.as_raw(), x, y, flip) }
861 }
862
863 #[doc(alias = "sys::ffi::playdate_graphics::tileBitmap")]
868 #[inline(always)]
869 pub fn draw_tiled(&self,
870 bitmap: &impl AnyBitmap,
871 x: c_int,
872 y: c_int,
873 width: c_int,
874 height: c_int,
875 flip: BitmapFlip) {
876 let f = self.0.tile_bitmap();
877 unsafe { f(bitmap.as_raw(), x, y, width, height, flip) }
878 }
879
880 #[doc(alias = "sys::ffi::playdate_graphics::drawRotatedBitmap")]
889 #[inline(always)]
890 pub fn draw_rotated(&self,
891 bitmap: &impl AnyBitmap,
892 x: c_int,
893 y: c_int,
894 degrees: c_float,
895 center_x: c_float,
896 center_y: c_float,
897 x_scale: c_float,
898 y_scale: c_float) {
899 let f = self.0.draw_rotated_bitmap();
900 unsafe {
901 f(
902 bitmap.as_raw(),
903 x,
904 y,
905 degrees,
906 center_x,
907 center_y,
908 x_scale,
909 y_scale,
910 )
911 }
912 }
913
914 #[doc(alias = "sys::ffi::playdate_graphics::drawScaledBitmap")]
920 #[inline(always)]
921 pub fn draw_scaled(&self, bitmap: &impl AnyBitmap, x: c_int, y: c_int, x_scale: c_float, y_scale: c_float) {
922 let f = self.0.draw_scaled_bitmap();
923 unsafe { f(bitmap.as_raw(), x, y, x_scale, y_scale) }
924 }
925}