playdate_graphics/lib.rs
1//! Playdate graphics API
2#![cfg_attr(not(test), no_std)]
3
4extern crate sys;
5extern crate alloc;
6pub extern crate color;
7
8pub mod error;
9pub mod text;
10pub mod bitmap {
11 mod bitmap;
12 pub mod api;
13 pub mod table;
14 pub use bitmap::*;
15}
16pub mod video;
17pub mod api;
18
19use core::ffi::c_float;
20use core::ffi::c_int;
21use error::ApiError;
22
23pub use sys::ffi::LCDBitmapFlip as BitmapFlip;
24pub use sys::ffi::LCDBitmapDrawMode as BitmapDrawMode;
25pub use sys::ffi::LCDLineCapStyle as LineCapStyle;
26
27use sys::ffi::LCDColor;
28use sys::ffi::LCD_ROWS;
29use sys::ffi::LCD_ROWSIZE;
30use sys::ffi::LCDPolygonFillRule;
31use sys::ffi::LCDSolidColor;
32
33pub use bitmap::debug_bitmap;
34pub use bitmap::display_buffer_bitmap;
35pub use bitmap::copy_frame_buffer_bitmap;
36pub use bitmap::set_stencil;
37pub use bitmap::set_stencil_tiled;
38pub use bitmap::set_draw_mode;
39pub use bitmap::push_context;
40pub use bitmap::pop_context;
41
42
43unsafe fn as_slice_mut(buf: *mut u8) -> Result<&'static mut [u8], ApiError> {
44 if !buf.is_null() {
45 Ok(core::slice::from_raw_parts_mut(
46 buf,
47 (LCD_ROWSIZE * LCD_ROWS) as usize,
48 ))
49 } else {
50 Err(sys::error::NullPtrError.into())
51 }
52}
53
54
55/// Returns the current display frame buffer.
56/// Rows are 32-bit aligned, so the row stride is 52 bytes, with the extra 2 bytes per row ignored.
57/// Bytes are MSB-ordered; i.e., the pixel in column 0 is the 0x80 bit of the first byte of the row.
58///
59/// This function is shorthand for [`Graphics::get_frame`],
60/// using default ZST end-point.
61///
62/// Equivalent to [`sys::ffi::playdate_graphics::getFrame`].
63#[doc(alias = "sys::ffi::playdate_graphics::getFrame")]
64#[inline(always)]
65pub fn get_frame() -> Result<&'static mut [u8], ApiError> { Graphics::Default().get_frame() }
66
67
68/// Returns the raw bits in the display buffer,
69/// __the last completed frame__.
70///
71/// This function is shorthand for [`Graphics::get_display_frame`],
72/// using default ZST end-point.
73///
74/// Equivalent to [`sys::ffi::playdate_graphics::getDisplayFrame`].
75#[doc(alias = "sys::ffi::playdate_graphics::getDisplayFrame")]
76#[inline(always)]
77pub fn get_display_frame() -> Result<&'static mut [u8], ApiError> { Graphics::Default().get_display_frame() }
78
79/// After updating pixels in the buffer returned by [`get_frame`],
80/// you must tell the graphics system which rows were updated.
81///
82/// This function marks a contiguous range of rows as updated
83/// (e.g., `markUpdatedRows(0, LCD_ROWS-1)` tells the system to update the entire display).
84///
85/// Both `start` and `end` are __included__ in the range.
86///
87/// This function is shorthand for [`Graphics::mark_updated_rows`],
88/// using default ZST end-point.
89///
90/// Equivalent to [`sys::ffi::playdate_graphics::markUpdatedRows`].
91#[doc(alias = "sys::ffi::playdate_graphics::markUpdatedRows")]
92#[inline(always)]
93pub fn mark_updated_rows(start: c_int, end: c_int) { Graphics::Default().mark_updated_rows(start, end) }
94
95/// Manually flushes the current frame buffer out to the display.
96/// This function is automatically called after each pass through the run loop,
97/// so there shouldn’t be any need to call it yourself.
98///
99/// This function is shorthand for [`Graphics::display`],
100/// using default ZST end-point.
101///
102/// Equivalent to [`sys::ffi::playdate_graphics::display`].
103#[doc(alias = "sys::ffi::playdate_graphics::display")]
104#[inline(always)]
105pub fn display() { Graphics::Default().display() }
106
107/// Clears the entire display, filling it with `color`.
108///
109/// This function is shorthand for [`Graphics::always`],
110/// using default ZST end-point.
111///
112/// Equivalent to [`sys::ffi::playdate_graphics::clear`].
113#[doc(alias = "sys::ffi::playdate_graphics::clear")]
114#[inline(always)]
115pub fn clear(color: color::Color) { clear_raw(color.into()) }
116
117
118/// Clears the entire display, filling it with `color`.
119///
120/// Same as [`clear`], but without conversion `Color` -> `LCDColor`.
121/// That conversion is really cheap,
122/// so this function is useful if you're working with `LCDColor` directly.
123///
124/// This function is shorthand for [`Graphics::clear_raw`],
125/// using default ZST end-point.
126///
127/// Equivalent to [`sys::ffi::playdate_graphics::clear`].
128#[doc(alias = "sys::ffi::playdate_graphics::clear")]
129#[inline(always)]
130pub fn clear_raw(color: LCDColor) { Graphics::Default().clear_raw(color) }
131
132/// Sets the current clip rect in __screen__ coordinates.
133///
134/// This function is shorthand for [`Graphics::set_screen_clip_rect`],
135/// using default ZST end-point.
136///
137/// Equivalent to [`sys::ffi::playdate_graphics::setScreenClipRect`].
138#[doc(alias = "sys::ffi::playdate_graphics::setScreenClipRect")]
139#[inline(always)]
140pub fn set_screen_clip_rect(x: c_int, y: c_int, width: c_int, height: c_int) {
141 Graphics::Default().set_screen_clip_rect(x, y, width, height)
142}
143
144/// Offsets the origin point for all drawing calls to `x, y` (can be negative).
145///
146/// This is useful, for example, for centering a "camera"
147/// on a sprite that is moving around a world larger than the screen.
148///
149/// This function is shorthand for [`Graphics::set_draw_offset`],
150/// using default ZST end-point.
151///
152/// Equivalent to [`sys::ffi::playdate_graphics::setDrawOffset`].
153#[doc(alias = "sys::ffi::playdate_graphics::setDrawOffset")]
154#[inline(always)]
155pub fn set_draw_offset(dx: c_int, dy: c_int) { Graphics::Default().set_draw_offset(dx, dy) }
156
157/// Sets the current clip rect, using __world__ coordinates that is,
158/// the given rectangle will be translated by the current drawing offset.
159///
160/// The clip rect is cleared at the beginning of each update.
161///
162/// This function is shorthand for [`Graphics::set_clip_rect`],
163/// using default ZST end-point.
164///
165/// Equivalent to [`sys::ffi::playdate_graphics::setClipRect`].
166#[doc(alias = "sys::ffi::playdate_graphics::setClipRect")]
167#[inline(always)]
168pub fn set_clip_rect(x: c_int, y: c_int, width: c_int, height: c_int) {
169 Graphics::Default().set_clip_rect(x, y, width, height)
170}
171
172/// Clears the current clip rect.
173///
174/// This function is shorthand for [`Graphics::clear_clip_rect`],
175/// using default ZST end-point.
176///
177/// Equivalent to [`sys::ffi::playdate_graphics::clearClipRect`].
178#[doc(alias = "sys::ffi::playdate_graphics::clearClipRect")]
179#[inline(always)]
180pub fn clear_clip_rect() { Graphics::Default().clear_clip_rect() }
181
182/// Sets the background color shown when the display is offset
183/// or for clearing dirty areas in the sprite system.
184///
185/// This function is shorthand for [`Graphics::set_background_color`],
186/// using default ZST end-point.
187///
188/// Equivalent to [`sys::ffi::playdate_graphics::setBackgroundColor`].
189#[doc(alias = "sys::ffi::playdate_graphics::setBackgroundColor")]
190#[inline(always)]
191pub fn set_background_color(color: LCDSolidColor) { Graphics::Default().set_background_color(color) }
192
193
194//
195// Geometry
196//
197
198/// Fills the polygon with vertices at the given coordinates
199/// (an array of `2 * num_points` ints containing alternating x and y values)
200/// using the given `color` and fill, or winding, `rule`.
201///
202/// See [wikipedia](https://en.wikipedia.org/wiki/Nonzero-rule) for an explanation of the winding rule.
203///
204/// This function is shorthand for [`Graphics::fill_polygon`],
205/// using default ZST end-point.
206///
207/// Equivalent to [`sys::ffi::playdate_graphics::fillPolygon`].
208#[doc(alias = "sys::ffi::playdate_graphics::fillPolygon")]
209#[inline(always)]
210pub fn fill_polygon(num_points: c_int, coords: &mut [c_int], color: LCDColor, rule: LCDPolygonFillRule) {
211 Graphics::Default().fill_polygon(num_points, coords, color, rule)
212}
213
214/// Draws a line from `x1, y1` to `x2, y2` with a stroke width of `width`.
215///
216/// This function is shorthand for [`Graphics::draw_line`],
217/// using default ZST end-point.
218///
219/// Equivalent to [`sys::ffi::playdate_graphics::drawLine`].
220#[doc(alias = "sys::ffi::playdate_graphics::drawLine")]
221#[inline(always)]
222pub fn draw_line(x1: c_int, y1: c_int, x2: c_int, y2: c_int, width: c_int, color: LCDColor) {
223 Graphics::Default().draw_line(x1, y1, x2, y2, width, color)
224}
225
226/// Draws a filled triangle with points at `x1, y1`, `x2, y2`, and `x3, y3`.
227///
228/// This function is shorthand for [`Graphics::fill_triangle`],
229/// using default ZST end-point.
230///
231/// Equivalent to [`sys::ffi::playdate_graphics::fillTriangle`].
232#[doc(alias = "sys::ffi::playdate_graphics::fillTriangle")]
233#[inline(always)]
234pub fn fill_triangle(x1: c_int, y1: c_int, x2: c_int, y2: c_int, x3: c_int, y3: c_int, color: LCDColor) {
235 Graphics::Default().fill_triangle(x1, y1, x2, y2, x3, y3, color);
236}
237
238/// Draws a `width` by `height` rect at `x, y`.
239///
240/// This function is shorthand for [`Graphics::draw_rect`],
241/// using default ZST end-point.
242///
243/// Equivalent to [`sys::ffi::playdate_graphics::drawRect`].
244#[doc(alias = "sys::ffi::playdate_graphics::drawRect")]
245#[inline(always)]
246pub fn draw_rect(x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) {
247 Graphics::Default().draw_rect(x, y, width, height, color)
248}
249
250/// Draws a filled `width` by `height` rect at `x, y`.
251///
252/// This function is shorthand for [`Graphics::fill_rect`],
253/// using default ZST end-point.
254///
255/// Equivalent to [`sys::ffi::playdate_graphics::fillRect`].
256#[doc(alias = "sys::ffi::playdate_graphics::fillRect")]
257#[inline(always)]
258pub fn fill_rect(x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) {
259 Graphics::Default().fill_rect(x, y, width, height, color)
260}
261
262/// Draw an ellipse stroked inside the rect.
263///
264/// Draws an ellipse inside the rectangle `x, y, width, height` of width `line_width`
265/// (inset from the rectangle bounds).
266///
267/// If `start_angle != end_angle`, this draws an arc between the given angles.
268///
269/// Angles are given in degrees, clockwise from due north.
270///
271/// This function is shorthand for [`Graphics::draw_ellipse`],
272/// using default ZST end-point.
273///
274/// Equivalent to [`sys::ffi::playdate_graphics::drawEllipse`].
275#[doc(alias = "sys::ffi::playdate_graphics::drawEllipse")]
276#[inline(always)]
277pub fn draw_ellipse(x: c_int,
278 y: c_int,
279 width: c_int,
280 height: c_int,
281 line_width: c_int,
282 start_angle: c_float,
283 end_angle: c_float,
284 color: LCDColor) {
285 Graphics::Default().draw_ellipse(x, y, width, height, line_width, start_angle, end_angle, color)
286}
287
288/// Fills an ellipse inside the rectangle `x, y, width, height`.
289///
290/// If `start_angle != end_angle`, this draws a wedge/Pacman between the given angles.
291///
292/// Angles are given in degrees, clockwise from due north.
293///
294/// This function is shorthand for [`Graphics::fill_ellipse`],
295/// using default ZST end-point.
296///
297/// Equivalent to [`sys::ffi::playdate_graphics::fillEllipse`].
298#[doc(alias = "sys::ffi::playdate_graphics::fillEllipse")]
299#[inline(always)]
300pub fn fill_ellipse(x: c_int,
301 y: c_int,
302 width: c_int,
303 height: c_int,
304 start_angle: c_float,
305 end_angle: c_float,
306 color: LCDColor) {
307 Graphics::Default().fill_ellipse(x, y, width, height, start_angle, end_angle, color)
308}
309
310
311/// Sets the end cap style used in the line drawing functions.
312///
313/// This function is shorthand for [`Graphics::set_line_cap_style`],
314/// using default ZST end-point.
315///
316/// Equivalent to [`sys::ffi::playdate_graphics::setLineCapStyle`].
317#[doc(alias = "sys::ffi::playdate_graphics::setLineCapStyle")]
318#[inline(always)]
319pub fn set_line_cap_style(end_cap_style: LineCapStyle) { Graphics::Default().set_line_cap_style(end_cap_style) }
320
321
322#[derive(Debug, Clone, Copy)]
323pub struct Graphics<Api = api::Default>(Api);
324
325impl Graphics<api::Default> {
326 /// Creates default [`Graphics`] without type parameter requirement.
327 ///
328 /// Uses ZST [`api::Default`].
329 #[allow(non_snake_case)]
330 pub fn Default() -> Self { Self(Default::default()) }
331}
332
333impl Graphics<api::Cache> {
334 /// Creates [`Graphics`] without type parameter requirement.
335 ///
336 /// Uses [`api::Cache`].
337 #[allow(non_snake_case)]
338 pub fn Cached() -> Self { Self(Default::default()) }
339}
340
341impl<Api: Default + api::Api> Default for Graphics<Api> {
342 fn default() -> Self { Self(Default::default()) }
343}
344
345impl<Api: Default + api::Api> Graphics<Api> {
346 pub fn new() -> Self { Self(Default::default()) }
347}
348
349impl<Api: api::Api> Graphics<Api> {
350 pub fn new_with(api: Api) -> Self { Self(api) }
351}
352
353impl<Api: api::Api> Graphics<Api> {
354 /// Sets the pixel at `(x,y)` in the current drawing context (by default the screen) to the given `color`.
355 /// Be aware that setting a pixel at a time is not very efficient:
356 /// In our testing, more than around 20,000 calls in a tight loop will drop the frame rate below 30 fps.
357 ///
358 /// Equivalent to [`sys::ffi::playdate_graphics::setPixel`]
359 #[doc(alias = "sys::ffi::playdate_graphics::setPixel")]
360 #[inline(always)]
361 pub fn set_pixel(&self, x: c_int, y: c_int, color: color::Color) { self.set_pixel_raw(x, y, color.into()) }
362
363 /// Same as [`set_pixel`][Graphics::set_pixel], but without conversion [`Color`][color::Color] -> [`LCDColor`].
364 ///
365 /// Equivalent to [`sys::ffi::playdate_graphics::setPixel`]
366 #[doc(alias = "sys::ffi::playdate_graphics::setPixel")]
367 #[inline(always)]
368 pub fn set_pixel_raw(&self, x: c_int, y: c_int, color: LCDColor) {
369 let f = self.0.set_pixel();
370 unsafe { f(x, y, color) }
371 }
372
373
374 /// Returns the current display frame buffer.
375 /// Rows are 32-bit aligned, so the row stride is 52 bytes, with the extra 2 bytes per row ignored.
376 /// Bytes are MSB-ordered; i.e., the pixel in column 0 is the 0x80 bit of the first byte of the row.
377 ///
378 /// Equivalent to [`sys::ffi::playdate_graphics::getFrame`].
379 #[doc(alias = "sys::ffi::playdate_graphics::getFrame")]
380 pub fn get_frame(&self) -> Result<&'static mut [u8], ApiError> {
381 let f = self.0.get_frame();
382 unsafe { as_slice_mut(f()) }
383 }
384
385
386 /// Returns the raw bits in the display buffer,
387 /// __the last completed frame__.
388 ///
389 /// Equivalent to [`sys::ffi::playdate_graphics::getDisplayFrame`].
390 #[doc(alias = "sys::ffi::playdate_graphics::getDisplayFrame")]
391 pub fn get_display_frame(&self) -> Result<&'static mut [u8], ApiError> {
392 let f = self.0.get_display_frame();
393 unsafe { as_slice_mut(f()) }
394 }
395
396 /// After updating pixels in the buffer returned by [`get_frame`],
397 /// you must tell the graphics system which rows were updated.
398 ///
399 /// This function marks a contiguous range of rows as updated
400 /// (e.g., `markUpdatedRows(0, LCD_ROWS-1)` tells the system to update the entire display).
401 ///
402 /// Both `start` and `end` are __included__ in the range.
403 ///
404 /// Equivalent to [`sys::ffi::playdate_graphics::markUpdatedRows`].
405 #[doc(alias = "sys::ffi::playdate_graphics::markUpdatedRows")]
406 pub fn mark_updated_rows(&self, start: c_int, end: c_int) {
407 let f = self.0.mark_updated_rows();
408 unsafe { f(start, end) }
409 }
410
411 /// Manually flushes the current frame buffer out to the display.
412 /// This function is automatically called after each pass through the run loop,
413 /// so there shouldn’t be any need to call it yourself.
414 ///
415 /// Equivalent to [`sys::ffi::playdate_graphics::display`].
416 #[doc(alias = "sys::ffi::playdate_graphics::display")]
417 pub fn display(&self) {
418 let f = self.0.display();
419 unsafe { f() }
420 }
421
422 /// Clears the entire display, filling it with `color`.
423 ///
424 /// Equivalent to [`sys::ffi::playdate_graphics::clear`].
425 #[doc(alias = "sys::ffi::playdate_graphics::clear")]
426 #[inline(always)]
427 pub fn clear(&self, color: color::Color) { clear_raw(color.into()) }
428
429
430 /// Clears the entire display, filling it with `color`.
431 ///
432 /// Same as [`clear`], but without conversion `Color` -> `LCDColor`.
433 /// That conversion is really cheap,
434 /// so this function is useful if you're working with `LCDColor` directly.
435 ///
436 /// Equivalent to [`sys::ffi::playdate_graphics::clear`].
437 #[doc(alias = "sys::ffi::playdate_graphics::clear")]
438 pub fn clear_raw(&self, color: LCDColor) {
439 let f = self.0.clear();
440 unsafe { f(color) }
441 }
442
443 /// Sets the current clip rect in __screen__ coordinates.
444 ///
445 /// Equivalent to [`sys::ffi::playdate_graphics::setScreenClipRect`].
446 #[doc(alias = "sys::ffi::playdate_graphics::setScreenClipRect")]
447 pub fn set_screen_clip_rect(&self, x: c_int, y: c_int, width: c_int, height: c_int) {
448 let f = self.0.set_screen_clip_rect();
449 unsafe { f(x, y, width, height) }
450 }
451
452 /// Offsets the origin point for all drawing calls to `x, y` (can be negative).
453 ///
454 /// This is useful, for example, for centering a "camera"
455 /// on a sprite that is moving around a world larger than the screen.
456 ///
457 /// Equivalent to [`sys::ffi::playdate_graphics::setDrawOffset`].
458 #[doc(alias = "sys::ffi::playdate_graphics::setDrawOffset")]
459 pub fn set_draw_offset(&self, dx: c_int, dy: c_int) {
460 let f = self.0.set_draw_offset();
461 unsafe { f(dx, dy) }
462 }
463
464 /// Sets the current clip rect, using __world__ coordinates that is,
465 /// the given rectangle will be translated by the current drawing offset.
466 ///
467 /// The clip rect is cleared at the beginning of each update.
468 ///
469 /// Equivalent to [`sys::ffi::playdate_graphics::setClipRect`].
470 #[doc(alias = "sys::ffi::playdate_graphics::setClipRect")]
471 pub fn set_clip_rect(&self, x: c_int, y: c_int, width: c_int, height: c_int) {
472 let f = self.0.set_clip_rect();
473 unsafe { f(x, y, width, height) }
474 }
475
476 /// Clears the current clip rect.
477 ///
478 /// Equivalent to [`sys::ffi::playdate_graphics::clearClipRect`].
479 #[doc(alias = "sys::ffi::playdate_graphics::clearClipRect")]
480 pub fn clear_clip_rect(&self) {
481 let f = self.0.clear_clip_rect();
482 unsafe { f() }
483 }
484
485 /// Sets the background color shown when the display is offset
486 /// or for clearing dirty areas in the sprite system.
487 ///
488 /// Equivalent to [`sys::ffi::playdate_graphics::setBackgroundColor`].
489 #[doc(alias = "sys::ffi::playdate_graphics::setBackgroundColor")]
490 pub fn set_background_color(&self, color: LCDSolidColor) {
491 let f = self.0.set_background_color();
492 unsafe { f(color) }
493 }
494
495
496 //
497 // Geometry
498 //
499
500 /// Fills the polygon with vertices at the given coordinates
501 /// (an array of `2 * num_points` ints containing alternating x and y values)
502 /// using the given `color` and fill, or winding, `rule`.
503 ///
504 /// See [wikipedia](https://en.wikipedia.org/wiki/Nonzero-rule) for an explanation of the winding rule.
505 ///
506 /// Equivalent to [`sys::ffi::playdate_graphics::fillPolygon`].
507 #[doc(alias = "sys::ffi::playdate_graphics::fillPolygon")]
508 pub fn fill_polygon(&self,
509 num_points: c_int,
510 coords: &mut [c_int],
511 color: LCDColor,
512 rule: LCDPolygonFillRule) {
513 let f = self.0.fill_polygon();
514 unsafe { f(num_points, coords.as_mut_ptr(), color, rule) }
515 }
516
517 /// Draws a line from `x1, y1` to `x2, y2` with a stroke width of `width`.
518 ///
519 /// Equivalent to [`sys::ffi::playdate_graphics::drawLine`].
520 #[doc(alias = "sys::ffi::playdate_graphics::drawLine")]
521 pub fn draw_line(&self, x1: c_int, y1: c_int, x2: c_int, y2: c_int, width: c_int, color: LCDColor) {
522 let f = self.0.draw_line();
523 unsafe { f(x1, y1, x2, y2, width, color) }
524 }
525
526 /// Draws a filled triangle with points at `x1, y1`, `x2, y2`, and `x3, y3`.
527 ///
528 /// Equivalent to [`sys::ffi::playdate_graphics::fillTriangle`].
529 #[doc(alias = "sys::ffi::playdate_graphics::fillTriangle")]
530 pub fn fill_triangle(&self,
531 x1: c_int,
532 y1: c_int,
533 x2: c_int,
534 y2: c_int,
535 x3: c_int,
536 y3: c_int,
537 color: LCDColor) {
538 let f = self.0.fill_triangle();
539 unsafe { f(x1, y1, x2, y2, x3, y3, color) }
540 }
541
542 /// Draws a `width` by `height` rect at `x, y`.
543 ///
544 /// Equivalent to [`sys::ffi::playdate_graphics::drawRect`].
545 #[doc(alias = "sys::ffi::playdate_graphics::drawRect")]
546 pub fn draw_rect(&self, x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) {
547 let f = self.0.draw_rect();
548 unsafe { f(x, y, width, height, color) }
549 }
550
551 /// Draws a filled `width` by `height` rect at `x, y`.
552 ///
553 /// Equivalent to [`sys::ffi::playdate_graphics::fillRect`].
554 #[doc(alias = "sys::ffi::playdate_graphics::fillRect")]
555 pub fn fill_rect(&self, x: c_int, y: c_int, width: c_int, height: c_int, color: LCDColor) {
556 let f = self.0.fill_rect();
557 unsafe { f(x, y, width, height, color) }
558 }
559
560 /// Draw an ellipse stroked inside the rect.
561 ///
562 /// Draws an ellipse inside the rectangle `x, y, width, height` of width `line_width`
563 /// (inset from the rectangle bounds).
564 ///
565 /// If `start_angle != end_angle`, this draws an arc between the given angles.
566 ///
567 /// Angles are given in degrees, clockwise from due north.
568 ///
569 /// Equivalent to [`sys::ffi::playdate_graphics::drawEllipse`].
570 #[doc(alias = "sys::ffi::playdate_graphics::drawEllipse")]
571 pub fn draw_ellipse(&self,
572 x: c_int,
573 y: c_int,
574 width: c_int,
575 height: c_int,
576 line_width: c_int,
577 start_angle: c_float,
578 end_angle: c_float,
579 color: LCDColor) {
580 let f = self.0.draw_ellipse();
581 unsafe { f(x, y, width, height, line_width, start_angle, end_angle, color) }
582 }
583
584 /// Fills an ellipse inside the rectangle `x, y, width, height`.
585 ///
586 /// If `start_angle != end_angle`, this draws a wedge/Pacman between the given angles.
587 ///
588 /// Angles are given in degrees, clockwise from due north.
589 ///
590 /// Equivalent to [`sys::ffi::playdate_graphics::fillEllipse`].
591 #[doc(alias = "sys::ffi::playdate_graphics::fillEllipse")]
592 pub fn fill_ellipse(&self,
593 x: c_int,
594 y: c_int,
595 width: c_int,
596 height: c_int,
597 start_angle: c_float,
598 end_angle: c_float,
599 color: LCDColor) {
600 let f = self.0.fill_ellipse();
601 unsafe { f(x, y, width, height, start_angle, end_angle, color) }
602 }
603
604
605 /// Sets the end cap style used in the line drawing functions.
606 ///
607 /// Equivalent to [`sys::ffi::playdate_graphics::setLineCapStyle`].
608 #[doc(alias = "sys::ffi::playdate_graphics::setLineCapStyle")]
609 pub fn set_line_cap_style(&self, end_cap_style: LineCapStyle) {
610 let f = self.0.set_line_cap_style();
611 unsafe { f(end_cap_style) }
612 }
613}
614
615
616pub trait BitmapFlipExt {
617 #![allow(non_upper_case_globals)]
618 const Unflipped: BitmapFlip = BitmapFlip::kBitmapUnflipped;
619 const FlippedX: BitmapFlip = BitmapFlip::kBitmapFlippedX;
620 const FlippedY: BitmapFlip = BitmapFlip::kBitmapFlippedY;
621 const FlippedXY: BitmapFlip = BitmapFlip::kBitmapFlippedXY;
622}
623
624impl BitmapFlipExt for BitmapFlip {}
625
626
627pub trait BitmapDrawModeExt {
628 #![allow(non_upper_case_globals)]
629 const Copy: BitmapDrawMode = BitmapDrawMode::kDrawModeCopy;
630 const WhiteTransparent: BitmapDrawMode = BitmapDrawMode::kDrawModeWhiteTransparent;
631 const BlackTransparent: BitmapDrawMode = BitmapDrawMode::kDrawModeBlackTransparent;
632 const FillWhite: BitmapDrawMode = BitmapDrawMode::kDrawModeFillWhite;
633 const FillBlack: BitmapDrawMode = BitmapDrawMode::kDrawModeFillBlack;
634 const XOR: BitmapDrawMode = BitmapDrawMode::kDrawModeXOR;
635 const NXOR: BitmapDrawMode = BitmapDrawMode::kDrawModeNXOR;
636 const Inverted: BitmapDrawMode = BitmapDrawMode::kDrawModeInverted;
637}
638
639impl BitmapDrawModeExt for BitmapDrawMode {}
640
641
642pub trait LineCapStyleExt {
643 #![allow(non_upper_case_globals)]
644 const Butt: LineCapStyle = LineCapStyle::kLineCapStyleButt;
645 const Square: LineCapStyle = LineCapStyle::kLineCapStyleSquare;
646 const Round: LineCapStyle = LineCapStyle::kLineCapStyleRound;
647}
648impl LineCapStyleExt for LineCapStyle {}