playdate_graphics/
text.rs

1//! Playdate text API
2
3use core::ffi::{c_int, c_char};
4
5use alloc::ffi::NulError;
6use alloc::boxed::Box;
7use fs::Path;
8use sys::ffi::{CString, CStr, LCDFont, LCDFontGlyph, LCDFontPage, LCDBitmap};
9use sys::traits::AsRaw;
10
11pub use sys::ffi::PDStringEncoding as StringEncoding;
12pub use sys::ffi::PDTextWrappingMode as TextWrappingMode;
13pub use sys::ffi::PDTextAlignment as TextAlignment;
14
15use crate::Graphics;
16use crate::bitmap::BitmapRef;
17use crate::error::{Error, ApiError};
18
19
20/// Draws the given `text` using the provided coords `x`, `y`.
21///
22/// Encoding is always `StringEncoding::UTF8`.
23/// If another encoding is desired, use [`draw_text_cstr`] instead.
24///
25/// If no `font` has been set with [`set_font`],
26/// the default system font `Asheville Sans 14 Light` is used.
27///
28/// This function is shorthand for [`Graphics::draw_text`],
29/// using default ZST end-point.
30///
31/// Equivalent to [`sys::ffi::playdate_graphics::drawText`].
32#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
33#[inline(always)]
34pub fn draw_text<S: AsRef<str>>(text: S, x: c_int, y: c_int) -> Result<c_int, NulError> {
35	Graphics::Default().draw_text(text, x, y)
36}
37
38/// Draws the given `text` using the provided options.
39///
40/// If no `font` has been set with [`set_font`],
41/// the default system font `Asheville Sans 14 Light` is used.
42///
43/// Same as [`draw_text`] but takes a [`sys::ffi::CStr`],
44/// but little bit more efficient.
45///
46/// This function is shorthand for [`Graphics::draw_text_cstr`],
47/// using default ZST end-point.
48///
49/// Equivalent to [`sys::ffi::playdate_graphics::drawText`].
50#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
51#[inline(always)]
52pub fn draw_text_cstr(text: &CStr, encoding: StringEncoding, x: c_int, y: c_int) -> c_int {
53	Graphics::Default().draw_text_cstr(text, encoding, x, y)
54}
55
56/// Draws the `text` in the given rectangle using the provided options.
57///
58/// If no `font` has been set with [`set_font`],
59/// the default system font `Asheville Sans 14 Light`` is used.
60///
61/// This function is shorthand for [`Graphics::draw_text_in_rect`],
62/// using default ZST end-point.
63///
64/// Equivalent to [`sys::ffi::playdate_graphics::drawTextInRect`].
65#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
66#[inline(always)]
67pub fn draw_text_in_rect<S: AsRef<str>>(text: S,
68                                        x: c_int,
69                                        y: c_int,
70                                        width: c_int,
71                                        height: c_int,
72                                        wrap: TextWrappingMode,
73                                        align: TextAlignment)
74                                        -> Result<(), NulError> {
75	Graphics::Default().draw_text_in_rect(text, x, y, width, height, wrap, align)
76}
77
78/// Returns the width of the given `text` in the given `font`.
79///
80/// This function is shorthand for [`Graphics::get_text_width`],
81/// using default ZST end-point.
82///
83/// Equivalent to [`sys::ffi::playdate_graphics::getTextWidth`].
84#[doc(alias = "sys::ffi::playdate_graphics::getTextWidth")]
85#[inline(always)]
86pub fn get_text_width<S: AsRef<str>>(text: S, font: Option<&Font>, tracking: c_int) -> Result<c_int, NulError> {
87	Graphics::Default().get_text_width(text, font, tracking)
88}
89
90/// Returns the width of the given `text` in the given `font`.
91///
92/// Same as [`get_text_width`] but takes a [`sys::ffi::CStr`],
93/// but little bit more efficient.
94///
95/// This function is shorthand for [`Graphics::get_text_width_cstr`],
96/// using default ZST end-point.
97///
98/// Equivalent to [`sys::ffi::playdate_graphics::getTextWidth`].
99#[doc(alias = "sys::ffi::playdate_graphics::getTextWidth")]
100#[inline(always)]
101pub fn get_text_width_cstr(text: &CStr, encoding: StringEncoding, font: Option<&Font>, tracking: c_int) -> c_int {
102	Graphics::Default().get_text_width_cstr(text, encoding, font, tracking)
103}
104
105
106/// Returns the height of the given `font`.
107///
108/// This function is shorthand for [`Graphics::get_font_height`],
109/// using default ZST end-point.
110///
111/// Equivalent to [`sys::ffi::playdate_graphics::getFontHeight`].
112#[doc(alias = "sys::ffi::playdate_graphics::getFontHeight")]
113#[inline(always)]
114pub fn get_font_height(font: &Font) -> u8 { Graphics::Default().get_font_height(font) }
115
116/// Sets the `font` to use in subsequent [`draw_text`] calls.
117///
118/// This function is shorthand for [`Graphics::set_font`],
119/// using default ZST end-point.
120///
121/// Equivalent to [`sys::ffi::playdate_graphics::setFont`].
122#[doc(alias = "sys::ffi::playdate_graphics::setFont")]
123#[inline(always)]
124pub fn set_font(font: &Font) { Graphics::Default().set_font(font) }
125
126/// Returns the kerning adjustment between characters `glyph_code` and `next_code` as specified by the font
127///
128/// This function is shorthand for [`Graphics::get_glyph_kerning`],
129/// using default ZST end-point.
130///
131/// Equivalent to [`sys::ffi::playdate_graphics::getGlyphKerning`].
132#[doc(alias = "sys::ffi::playdate_graphics::getGlyphKerning")]
133#[inline(always)]
134pub fn get_glyph_kerning(glyph: &Glyph, glyph_code: u32, next_code: u32) -> c_int {
135	Graphics::Default().get_glyph_kerning(glyph, glyph_code, next_code)
136}
137
138/// Returns an [`Glyph`] object for character `c` in [`FontPage`] page,
139///
140/// To also get the glyph’s bitmap and `advance` value
141/// use [`get_page_glyph_with_bitmap`] instead.
142///
143/// This function is shorthand for [`Graphics::get_page_glyph`],
144/// using default ZST end-point.
145///
146/// Equivalent to [`sys::ffi::playdate_graphics::getPageGlyph`].
147#[doc(alias = "sys::ffi::playdate_graphics::getPageGlyph")]
148#[inline(always)]
149pub fn get_page_glyph(page: &FontPage, c: u32) -> Result<Glyph, Error> {
150	Graphics::Default().get_page_glyph(page, c)
151}
152
153/// Returns an [`Glyph`] object for character `c` in [`FontPage`] page,
154/// and optionally returns the glyph’s bitmap and `advance` value.
155///
156/// If bitmap is not needed, use [`get_page_glyph`] instead.
157///
158/// This function is shorthand for [`Graphics::get_page_glyph_with_bitmap`],
159/// using default ZST end-point.
160///
161/// Equivalent to [`sys::ffi::playdate_graphics::getPageGlyph`].
162#[doc(alias = "sys::ffi::playdate_graphics::getPageGlyph")]
163#[inline(always)]
164pub fn get_page_glyph_with_bitmap<'p>(page: &'p FontPage,
165                                      c: u32,
166                                      advance: &mut c_int)
167                                      -> Result<(Glyph, BitmapRef<'p>), Error> {
168	Graphics::Default().get_page_glyph_with_bitmap(page, c, advance)
169}
170
171
172/// Returns an [`FontPage`] object for the given character code `c`.
173///
174/// Each [`FontPage`] contains information for 256 characters;
175/// specifically, if `(c1 & ~0xff) == (c2 & ~0xff)`,
176/// then `c1` and `c2` belong to the same page and the same [`FontPage`]
177/// can be used to fetch the character data for both instead of searching for the page twice.
178///
179/// This function is shorthand for [`Graphics::get_font_page`],
180/// using default ZST end-point.
181///
182/// Equivalent to [`sys::ffi::playdate_graphics::getFontPage`].
183#[doc(alias = "sys::ffi::playdate_graphics::getFontPage")]
184#[inline(always)]
185pub fn get_font_page(font: &Font, c: u32) -> Result<FontPage, Error> {
186	Graphics::Default().get_font_page(font, c)
187}
188
189
190/// Returns the [`Font`] object for the font file at `path`.
191///
192/// This function is shorthand for [`Graphics::load_font`],
193/// using default ZST end-point.
194///
195/// Equivalent to [`sys::ffi::playdate_graphics::loadFont`].
196#[doc(alias = "sys::ffi::playdate_graphics::loadFont")]
197#[inline(always)]
198pub fn load_font<P: AsRef<Path>>(path: P) -> Result<Font, ApiError> { Graphics::Default().load_font(path) }
199
200
201/// ⚠️ Caution: This function is not tested.
202///
203/// Returns an [`Font`] object wrapping the LCDFontData data
204/// comprising the contents (minus 16-byte header) of an uncompressed pft file.
205///
206/// The `wide` corresponds to the flag in the header indicating
207/// whether the font contains glyphs at codepoints above `U+1FFFF`.
208///
209/// This function is shorthand for [`Graphics::make_font_from_bytes`],
210/// using default ZST end-point.
211///
212/// Equivalent to [`sys::ffi::playdate_graphics::makeFontFromData`].
213#[doc(alias = "sys::ffi::playdate_graphics::makeFontFromData")]
214#[inline(always)]
215pub fn make_font_from_bytes(data: &[u8], wide: c_int) -> Result<Font, Error> {
216	Graphics::Default().make_font_from_bytes(data, wide)
217}
218
219
220/// Sets the leading adjustment (added to the leading specified in the font) to use when drawing text.
221///
222/// This function is shorthand for [`Graphics::set_text_leading`],
223/// using default ZST end-point.
224///
225/// Equivalent to [`sys::ffi::playdate_graphics::setTextLeading`].
226#[doc(alias = "sys::ffi::playdate_graphics::setTextLeading")]
227#[inline(always)]
228pub fn set_text_leading(line_height_adjustment: c_int) {
229	Graphics::Default().set_text_leading(line_height_adjustment)
230}
231
232/// Sets the tracking to use when drawing text.
233///
234/// This function is shorthand for [`Graphics::set_text_tracking`],
235/// using default ZST end-point.
236///
237/// Equivalent to [`sys::ffi::playdate_graphics::setTextTracking`].
238#[doc(alias = "sys::ffi::playdate_graphics::setTextTracking")]
239#[inline(always)]
240pub fn set_text_tracking(tracking: c_int) { Graphics::Default().set_text_tracking(tracking) }
241
242
243/// Gets the tracking used when drawing text.
244///
245/// This function is shorthand for [`Graphics::set_text_tracking`],
246/// using default ZST end-point.
247///
248/// Equivalent to [`sys::ffi::playdate_graphics::getTextTracking`].
249#[doc(alias = "sys::ffi::playdate_graphics::getTextTracking")]
250#[inline(always)]
251pub fn get_text_tracking() -> c_int { Graphics::Default().get_text_tracking() }
252
253
254impl<Api: crate::api::Api> Graphics<Api> {
255	/// Draws the given `text` using the provided coords `x`, `y`.
256	///
257	/// Encoding is always `StringEncoding::UTF8`.
258	/// If another encoding is desired, use [`draw_text_cstr`] instead.
259	///
260	/// If no `font` has been set with [`set_font`],
261	/// the default system font `Asheville Sans 14 Light` is used.
262	///
263	/// Equivalent to [`sys::ffi::playdate_graphics::drawText`].
264	#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
265	pub fn draw_text<S: AsRef<str>>(&self, text: S, x: c_int, y: c_int) -> Result<c_int, NulError> {
266		let s = CString::new(text.as_ref())?;
267		let f = self.0.draw_text();
268		let res = unsafe { f(s.as_ptr().cast(), text.as_ref().len(), StringEncoding::UTF8, x, y) };
269		Ok(res)
270	}
271
272	/// Draws the given `text` using the provided options.
273	///
274	/// If no `font` has been set with [`set_font`],
275	/// the default system font `Asheville Sans 14 Light` is used.
276	///
277	/// Same as [`draw_text`] but takes a [`sys::ffi::CStr`],
278	/// but little bit more efficient.
279	///
280	/// Equivalent to [`sys::ffi::playdate_graphics::drawText`].
281	#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
282	pub fn draw_text_cstr(&self, text: &CStr, encoding: StringEncoding, x: c_int, y: c_int) -> c_int {
283		let f = self.0.draw_text();
284		let len = text.to_bytes().len();
285		unsafe { f(text.as_ptr().cast(), len, encoding, x, y) }
286	}
287
288	/// Draws the `text` in the given rectangle using the provided options.
289	///
290	/// If no `font` has been set with [`set_font`],
291	/// the default system font `Asheville Sans 14 Light`` is used.
292	///
293	/// Equivalent to [`sys::ffi::playdate_graphics::drawTextInRect`].
294	#[doc(alias = "sys::ffi::playdate_graphics::drawTextInRect")]
295	pub fn draw_text_in_rect<S: AsRef<str>>(&self,
296	                                        text: S,
297	                                        x: c_int,
298	                                        y: c_int,
299	                                        width: c_int,
300	                                        height: c_int,
301	                                        wrap: TextWrappingMode,
302	                                        align: TextAlignment)
303	                                        -> Result<(), NulError> {
304		let s = CString::new(text.as_ref())?;
305		let f = self.0.draw_text_in_rect();
306		let res = unsafe {
307			f(
308			  s.as_ptr().cast(),
309			  text.as_ref().len(),
310			  StringEncoding::UTF8,
311			  x,
312			  y,
313			  width,
314			  height,
315			  wrap,
316			  align,
317			)
318		};
319		Ok(res)
320	}
321
322	/// Returns the width of the given `text` in the given `font`.
323	///
324	/// Equivalent to [`sys::ffi::playdate_graphics::getTextWidth`].
325	#[doc(alias = "sys::ffi::playdate_graphics::getTextWidth")]
326	pub fn get_text_width<S: AsRef<str>>(&self,
327	                                     text: S,
328	                                     font: Option<&Font>,
329	                                     tracking: c_int)
330	                                     -> Result<c_int, NulError> {
331		let s = CString::new(text.as_ref())?;
332		let f = self.0.get_text_width();
333		let font = font.map(|font| unsafe { font.as_raw() })
334		               .unwrap_or(core::ptr::null_mut());
335		let res = unsafe {
336			f(
337			  font,
338			  s.as_ptr().cast(),
339			  text.as_ref().len(),
340			  StringEncoding::UTF8,
341			  tracking,
342			)
343		};
344		Ok(res)
345	}
346
347	/// Returns the width of the given `text` in the given `font`.
348	///
349	/// Same as [`get_text_width`] but takes a [`sys::ffi::CStr`],
350	/// but little bit more efficient.
351	///
352	/// Equivalent to [`sys::ffi::playdate_graphics::getTextWidth`].
353	#[doc(alias = "sys::ffi::playdate_graphics::getTextWidth")]
354	pub fn get_text_width_cstr(&self,
355	                           text: &CStr,
356	                           encoding: StringEncoding,
357	                           font: Option<&Font>,
358	                           tracking: c_int)
359	                           -> c_int {
360		let f = self.0.get_text_width();
361		let len = text.to_bytes().len();
362		let font = font.map(|font| unsafe { font.as_raw() })
363		               .unwrap_or(core::ptr::null_mut());
364		unsafe { f(font, text.as_ptr().cast(), len, encoding, tracking) }
365	}
366
367
368	/// Returns the height of the given `font`.
369	///
370	/// Equivalent to [`sys::ffi::playdate_graphics::getFontHeight`].
371	#[doc(alias = "sys::ffi::playdate_graphics::getFontHeight")]
372	pub fn get_font_height(&self, font: &Font) -> u8 {
373		let f = self.0.get_font_height();
374		unsafe { f(font.as_raw()) }
375	}
376
377	/// Sets the `font` to use in subsequent [`draw_text`] calls.
378	///
379	/// Equivalent to [`sys::ffi::playdate_graphics::setFont`].
380	#[doc(alias = "sys::ffi::playdate_graphics::setFont")]
381	pub fn set_font(&self, font: &Font) {
382		let f = self.0.set_font();
383		unsafe { f(font.as_raw()) }
384	}
385
386	/// Returns the kerning adjustment between characters `glyph_code` and `next_code` as specified by the font
387	///
388	/// Equivalent to [`sys::ffi::playdate_graphics::getGlyphKerning`].
389	#[doc(alias = "sys::ffi::playdate_graphics::getGlyphKerning")]
390	pub fn get_glyph_kerning(&self, glyph: &Glyph, glyph_code: u32, next_code: u32) -> c_int {
391		let f = self.0.get_glyph_kerning();
392		unsafe { f(glyph.as_raw(), glyph_code, next_code) }
393	}
394
395	/// Returns an [`Glyph`] object for character `c` in [`FontPage`] page,
396	///
397	/// To also get the glyph’s bitmap and `advance` value
398	/// use [`get_page_glyph_with_bitmap`] instead.
399	///
400	/// Equivalent to [`sys::ffi::playdate_graphics::getPageGlyph`].
401	#[doc(alias = "sys::ffi::playdate_graphics::getPageGlyph")]
402	pub fn get_page_glyph(&self, page: &FontPage, c: u32) -> Result<Glyph, Error> {
403		let f = self.0.get_page_glyph();
404		let ptr = unsafe { f(page.as_raw(), c, core::ptr::null_mut(), core::ptr::null_mut()) };
405
406		if ptr.is_null() {
407			Err(Error::Font)
408		} else {
409			Ok(Glyph(ptr))
410		}
411	}
412
413	/// Returns an [`Glyph`] object for character `c` in [`FontPage`] page,
414	/// and optionally returns the glyph’s bitmap and `advance` value.
415	///
416	/// If bitmap is not needed, use [`get_page_glyph`] instead.
417	///
418	/// Equivalent to [`sys::ffi::playdate_graphics::getPageGlyph`].
419	#[doc(alias = "sys::ffi::playdate_graphics::getPageGlyph")]
420	pub fn get_page_glyph_with_bitmap<'p>(&self,
421	                                      page: &'p FontPage,
422	                                      c: u32,
423	                                      advance: &mut c_int)
424	                                      -> Result<(Glyph, BitmapRef<'p>), Error> {
425		let bitmap = Box::new(core::ptr::null_mut() as *mut LCDBitmap);
426		let out_bitmap = Box::into_raw(bitmap);
427
428		let f = self.0.get_page_glyph();
429		let ptr = unsafe { f(page.as_raw(), c, out_bitmap, advance) };
430
431		if ptr.is_null() {
432			Err(Error::Font)
433		} else {
434			let bitmap = unsafe { Box::from_raw(out_bitmap) };
435			if bitmap.is_null() {
436				Err(Error::Font)
437			} else {
438				Ok((Glyph(ptr), BitmapRef::from(*bitmap)))
439			}
440		}
441	}
442
443
444	/// Returns an [`FontPage`] object for the given character code `c`.
445	///
446	/// Each [`FontPage`] contains information for 256 characters;
447	/// specifically, if `(c1 & ~0xff) == (c2 & ~0xff)`,
448	/// then `c1` and `c2` belong to the same page and the same [`FontPage`]
449	/// can be used to fetch the character data for both instead of searching for the page twice.
450	///
451	/// Equivalent to [`sys::ffi::playdate_graphics::getFontPage`].
452	#[doc(alias = "sys::ffi::playdate_graphics::getFontPage")]
453	pub fn get_font_page(&self, font: &Font, c: u32) -> Result<FontPage, Error> {
454		let f = self.0.get_font_page();
455		let ptr = unsafe { f(font.as_raw(), c) };
456
457		if ptr.is_null() {
458			Err(Error::Font)
459		} else {
460			Ok(FontPage(ptr))
461		}
462	}
463
464
465	/// Returns the [`Font`] object for the font file at `path`.
466	///
467	/// Equivalent to [`sys::ffi::playdate_graphics::loadFont`].
468	#[doc(alias = "sys::ffi::playdate_graphics::loadFont")]
469	pub fn load_font<P: AsRef<Path>>(&self, path: P) -> Result<Font, ApiError> {
470		let mut err = Box::new(core::ptr::null() as *const c_char);
471		let out_err = Box::into_raw(err);
472
473		let path = CString::new(path.as_ref())?;
474
475		let f = self.0.load_font();
476		let ptr = unsafe { f(path.as_ptr() as *mut c_char, out_err as _) };
477
478		if ptr.is_null() {
479			err = unsafe { Box::from_raw(out_err) };
480			if let Some(err) = fs::error::Error::from_ptr(*err) {
481				Err(Error::Fs(err).into())
482			} else {
483				Err(Error::Alloc.into())
484			}
485		} else {
486			Ok(Font(ptr))
487		}
488	}
489
490
491	/// ⚠️ Caution: This function is not tested.
492	///
493	/// Returns an [`Font`] object wrapping the LCDFontData data
494	/// comprising the contents (minus 16-byte header) of an uncompressed pft file.
495	///
496	/// The `wide` corresponds to the flag in the header indicating
497	/// whether the font contains glyphs at codepoints above `U+1FFFF`.
498	///
499	/// Equivalent to [`sys::ffi::playdate_graphics::makeFontFromData`].
500	#[doc(alias = "sys::ffi::playdate_graphics::makeFontFromData")]
501	pub fn make_font_from_bytes(&self, data: &[u8], wide: c_int) -> Result<Font, Error> {
502		let f = self.0.make_font_from_data();
503		let ptr = unsafe { f(data.as_ptr() as _, wide) };
504
505		if ptr.is_null() {
506			Err(Error::Alloc)
507		} else {
508			Ok(Font(ptr))
509		}
510	}
511
512
513	/// Sets the leading adjustment (added to the leading specified in the font) to use when drawing text.
514	///
515	/// Equivalent to [`sys::ffi::playdate_graphics::setTextLeading`].
516	#[doc(alias = "sys::ffi::playdate_graphics::setTextLeading")]
517	pub fn set_text_leading(&self, line_height_adjustment: c_int) {
518		let f = self.0.set_text_leading();
519		unsafe { f(line_height_adjustment) }
520	}
521
522	/// Sets the tracking to use when drawing text.
523	///
524	/// Equivalent to [`sys::ffi::playdate_graphics::setTextTracking`].
525	#[doc(alias = "sys::ffi::playdate_graphics::setTextTracking")]
526	pub fn set_text_tracking(&self, tracking: c_int) {
527		let f = self.0.set_text_tracking();
528		unsafe { f(tracking) }
529	}
530
531	/// Sets the tracking to use when drawing text.
532	///
533	/// Equivalent to [`sys::ffi::playdate_graphics::getTextTracking`].
534	#[doc(alias = "sys::ffi::playdate_graphics::getTextTracking")]
535	pub fn get_text_tracking(&self) -> c_int {
536		let f = self.0.get_text_tracking();
537		unsafe { f() }
538	}
539}
540
541
542/// Playdate Font representation.
543///
544/// See [official docs][] for more information.
545///
546/// [official docs]: https://sdk.play.date/Inside%20Playdate.html#C-graphics.font
547pub struct Font(*mut LCDFont);
548
549impl AsRaw for Font {
550	type Type = LCDFont;
551	unsafe fn as_raw(&self) -> *mut Self::Type { self.0 }
552}
553
554/// Playdate Glyph representation.
555pub struct Glyph(*mut LCDFontGlyph);
556
557impl AsRaw for Glyph {
558	type Type = LCDFontGlyph;
559	unsafe fn as_raw(&self) -> *mut Self::Type { self.0 }
560}
561
562/// Playdate FontPage representation.
563pub struct FontPage(*mut LCDFontPage);
564
565impl AsRaw for FontPage {
566	type Type = LCDFontPage;
567	unsafe fn as_raw(&self) -> *mut Self::Type { self.0 }
568}
569
570
571pub trait StringEncodingExt {
572	#![allow(non_upper_case_globals)]
573	const ASCII: StringEncoding = StringEncoding::kASCIIEncoding;
574	const UTF8: StringEncoding = StringEncoding::kUTF8Encoding;
575	const LE16Bit: StringEncoding = StringEncoding::k16BitLEEncoding;
576}
577impl StringEncodingExt for StringEncoding {}
578
579pub trait TextWrappingModeExt {
580	#![allow(non_upper_case_globals)]
581	const Clip: TextWrappingMode = TextWrappingMode::kWrapClip;
582	const Character: TextWrappingMode = TextWrappingMode::kWrapCharacter;
583	const Word: TextWrappingMode = TextWrappingMode::kWrapWord;
584}
585impl TextWrappingModeExt for TextWrappingMode {}
586
587pub trait TextAlignmentExt {
588	#![allow(non_upper_case_globals)]
589	const Left: TextAlignment = TextAlignment::kAlignTextLeft;
590	const Center: TextAlignment = TextAlignment::kAlignTextCenter;
591	const Right: TextAlignment = TextAlignment::kAlignTextRight;
592}
593impl TextAlignmentExt for TextAlignment {}
594
595
596pub mod api {
597	use core::ffi::c_char;
598	use core::ffi::c_int;
599	use core::ffi::c_void;
600
601	use sys::ffi::LCDBitmap;
602	use sys::ffi::LCDFont;
603	use sys::ffi::LCDFontData;
604	use sys::ffi::LCDFontGlyph;
605	use sys::ffi::LCDFontPage;
606	use sys::ffi::PDStringEncoding;
607	use sys::ffi::PDTextWrappingMode;
608	use sys::ffi::PDTextAlignment;
609
610
611	/// Default graphics text api end-point, ZST.
612	///
613	/// All calls approximately costs ~3 derefs.
614	pub type Default = crate::api::Default;
615
616	/// Cached graphics text api end-point.
617	///
618	/// Stores one reference, so size on stack is eq `usize`.
619	///
620	/// All calls approximately costs ~1 deref.
621	pub type Cache = crate::api::Cache;
622
623
624	/// End-point with methods about ops with text.
625	pub trait Api {
626		/// Equivalent to [`sys::ffi::playdate_graphics::drawText`]
627		#[doc(alias = "sys::ffi::playdate_graphics::drawText")]
628		#[inline(always)]
629		fn draw_text(
630			&self)
631			-> unsafe extern "C" fn(text: *const c_void,
632			                        len: usize,
633			                        encoding: PDStringEncoding,
634			                        x: c_int,
635			                        y: c_int) -> c_int {
636			*sys::api!(graphics.drawText)
637		}
638
639		/// Equivalent to [`sys::ffi::playdate_graphics::drawTextInRect`]
640		#[doc(alias = "sys::ffi::playdate_graphics::drawTextInRect")]
641		#[inline(always)]
642		fn draw_text_in_rect(
643			&self)
644			-> unsafe extern "C" fn(text: *const c_void,
645			                        len: usize,
646			                        encoding: PDStringEncoding,
647			                        x: c_int,
648			                        y: c_int,
649			                        width: c_int,
650			                        height: c_int,
651			                        wrap: PDTextWrappingMode,
652			                        align: PDTextAlignment) {
653			*sys::api!(graphics.drawTextInRect)
654		}
655
656		/// Equivalent to [`sys::ffi::playdate_graphics::getTextWidth`]
657		#[doc(alias = "sys::ffi::playdate_graphics::getTextWidth")]
658		#[inline(always)]
659		fn get_text_width(
660			&self)
661			-> unsafe extern "C" fn(font: *mut LCDFont,
662			                        text: *const c_void,
663			                        len: usize,
664			                        encoding: PDStringEncoding,
665			                        tracking: c_int) -> c_int {
666			*sys::api!(graphics.getTextWidth)
667		}
668
669		/// Equivalent to [`sys::ffi::playdate_graphics::getFontHeight`]
670		#[doc(alias = "sys::ffi::playdate_graphics::getFontHeight")]
671		#[inline(always)]
672		fn get_font_height(&self) -> unsafe extern "C" fn(font: *mut LCDFont) -> u8 {
673			*sys::api!(graphics.getFontHeight)
674		}
675
676		/// Equivalent to [`sys::ffi::playdate_graphics::setFont`]
677		#[doc(alias = "sys::ffi::playdate_graphics::setFont")]
678		#[inline(always)]
679		fn set_font(&self) -> unsafe extern "C" fn(font: *mut LCDFont) { *sys::api!(graphics.setFont) }
680
681		/// Equivalent to [`sys::ffi::playdate_graphics::setTextTracking`]
682		#[doc(alias = "sys::ffi::playdate_graphics::setTextTracking")]
683		#[inline(always)]
684		fn set_text_tracking(&self) -> unsafe extern "C" fn(tracking: c_int) {
685			*sys::api!(graphics.setTextTracking)
686		}
687
688		/// Equivalent to [`sys::ffi::playdate_graphics::getTextTracking`]
689		#[doc(alias = "sys::ffi::playdate_graphics::getTextTracking")]
690		#[inline(always)]
691		fn get_text_tracking(&self) -> unsafe extern "C" fn() -> c_int { *sys::api!(graphics.getTextTracking) }
692
693		/// Equivalent to [`sys::ffi::playdate_graphics::getGlyphKerning`]
694		#[doc(alias = "sys::ffi::playdate_graphics::getGlyphKerning")]
695		#[inline(always)]
696		fn get_glyph_kerning(
697			&self)
698			-> unsafe extern "C" fn(glyph: *mut LCDFontGlyph, glyphcode: u32, nextcode: u32) -> c_int {
699			*sys::api!(graphics.getGlyphKerning)
700		}
701
702		/// Equivalent to [`sys::ffi::playdate_graphics::loadFont`]
703		#[doc(alias = "sys::ffi::playdate_graphics::loadFont")]
704		#[inline(always)]
705		fn load_font(&self)
706		             -> unsafe extern "C" fn(path: *const c_char, outErr: *mut *const c_char) -> *mut LCDFont {
707			*sys::api!(graphics.loadFont)
708		}
709
710		/// Equivalent to [`sys::ffi::playdate_graphics::getFontPage`]
711		#[doc(alias = "sys::ffi::playdate_graphics::getFontPage")]
712		#[inline(always)]
713		fn get_font_page(&self) -> unsafe extern "C" fn(font: *mut LCDFont, c: u32) -> *mut LCDFontPage {
714			*sys::api!(graphics.getFontPage)
715		}
716
717		/// Equivalent to [`sys::ffi::playdate_graphics::getPageGlyph`]
718		#[doc(alias = "sys::ffi::playdate_graphics::getPageGlyph")]
719		#[inline(always)]
720		fn get_page_glyph(
721			&self)
722			-> unsafe extern "C" fn(page: *mut LCDFontPage,
723			                        c: u32,
724			                        bitmap: *mut *mut LCDBitmap,
725			                        advance: *mut c_int) -> *mut LCDFontGlyph {
726			*sys::api!(graphics.getPageGlyph)
727		}
728
729		/// Equivalent to [`sys::ffi::playdate_graphics::makeFontFromData`]
730		#[doc(alias = "sys::ffi::playdate_graphics::makeFontFromData")]
731		#[inline(always)]
732		fn make_font_from_data(&self) -> unsafe extern "C" fn(data: *mut LCDFontData, wide: c_int) -> *mut LCDFont {
733			*sys::api!(graphics.makeFontFromData)
734		}
735
736		/// Equivalent to [`sys::ffi::playdate_graphics::setTextLeading`]
737		#[doc(alias = "sys::ffi::playdate_graphics::setTextLeading")]
738		#[inline(always)]
739		fn set_text_leading(&self) -> unsafe extern "C" fn(lineHeightAdjustment: c_int) {
740			*sys::api!(graphics.setTextLeading)
741		}
742	}
743}