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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
//! A system for including, rendering, and displaying dynamic text.
//!
//! The agb text rendering system has support for:
//! * Unicode
//! * Variable sized letters
//! * Kerning
//! * Left, right, centre, and justified alignments
//! * Left to right text only
//!
//! It is designed such that there are two phases to the rendering:
//! * the [`Layout`] system which decides where groups of letters should be
//! rendered.
//! * the [`ObjectTextRenderer`] and [`RegularBackgroundTextRenderer`] which
//! take those groups of letters and display them to their relevant targets.
//!
//! These two phases interact through the [`LetterGroup`] that the [`Layout`]
//! generates.
//!
//! # Layout
//!
//! An iterator over the [`LetterGroup`]s. These allow for chunks of text to be
//! displayed in a single draw call and also enables the designer to track what
//! text is being manipulated should you want to perform any effects. For
//! example, you could play certain sounds after encountering text containing
//! certain characters.
//!
//! ```rust
//! # #![no_std]
//! # #![no_main]
//! use agb::display::font::{Layout, Font, LayoutSettings};
//!
//! static FONT: Font = agb::include_font!("examples/font/pixelated.ttf", 8);
//!
//! # #[agb::doctest]
//! # fn test(_: agb::Gba) {
//! let mut layout = Layout::new(
//! "Hello, world!",
//! &FONT,
//! &LayoutSettings::new()
//! .with_max_line_length(200)
//! .with_max_group_width(32),
//! );
//!
//! let n = layout.next().unwrap();
//! assert_eq!(n.text(), "Hello,");
//! assert_eq!(n.position(), (0, 0).into());
//!
//! let n = layout.next().unwrap();
//! assert_eq!(n.text(), "world!");
//!
//! assert!(layout.next().is_none());
//! # }
//! ```
//!
//! # Object based target
//!
//! The [`ObjectTextRenderer`] creates objects that can be stored and displayed
//! later. A simple renderer could look like
//!
//! ```rust
//! # #![no_std]
//! # #![no_main]
//! extern crate alloc;
//! use alloc::vec::Vec;
//! use agb::display::{
//! Palette16, Rgb15,
//! font::{AlignmentKind, Font, Layout, LayoutSettings, ObjectTextRenderer},
//! object::Size,
//! };
//!
//! static SIMPLE_PALETTE: &Palette16 = {
//! let mut palette = [Rgb15::BLACK; 16];
//! palette[1] = Rgb15::WHITE;
//! &Palette16::new(palette)
//! };
//! static FONT: Font = agb::include_font!("examples/font/pixelated.ttf", 8);
//! # #[agb::doctest]
//! # fn test(mut gba: agb::Gba) {
//! let mut text_elements = Vec::new();
//!
//! // the actual text rendering
//!
//! let layout = Layout::new("Hello, world!", &FONT, &LayoutSettings::new().with_max_line_length(200));
//! let text_renderer = ObjectTextRenderer::new(SIMPLE_PALETTE.into(), Size::S16x16);
//!
//! for letter_group in layout {
//! text_elements.push(text_renderer.show(&letter_group, (0, 0)));
//! }
//!
//! // display the objects in the usual means
//!
//! let mut gfx = gba.graphics.get();
//! let mut frame = gfx.frame();
//!
//! for obj in text_elements.iter() {
//! obj.show(&mut frame);
//! }
//! # }
//! ```
//!
//! # Background tile based renderer
//!
//! The [`RegularBackgroundTextRenderer`] uses backgrounds and tiles to display
//! text. A simple renderer could look like
//!
//! ```rust
//! # #![no_std]
//! # #![no_main]
//! use agb::display::{
//! Palette16, Rgb15, Priority,
//! font::{Font, Layout, LayoutSettings, RegularBackgroundTextRenderer},
//! tiled::{RegularBackground, VRAM_MANAGER, RegularBackgroundSize, TileFormat},
//! };
//!
//! static SIMPLE_PALETTE: &Palette16 = {
//! let mut palette = [Rgb15::BLACK; 16];
//! palette[1] = Rgb15::WHITE;
//! &Palette16::new(palette)
//! };
//! static FONT: Font = agb::include_font!("examples/font/pixelated.ttf", 8);
//!
//! # #[agb::doctest]
//! # fn test(mut gba: agb::Gba) {
//! VRAM_MANAGER.set_background_palette(0, SIMPLE_PALETTE);
//! let mut bg = RegularBackground::new(
//! Priority::P0,
//! RegularBackgroundSize::Background32x32,
//! TileFormat::FourBpp,
//! );
//!
//! // the actual text rendering
//!
//! let layout = Layout::new("Hello, world!", &FONT, &LayoutSettings::new().with_max_line_length(200));
//! let mut text_renderer = RegularBackgroundTextRenderer::new((0, 0), 0);
//!
//! for letter_group in layout {
//! text_renderer.show(&mut bg, &letter_group);
//! }
//!
//! // display the background in the usual means
//!
//! let mut gfx = gba.graphics.get();
//! let mut frame = gfx.frame();
//!
//! bg.show(&mut frame);
//! # }
//! ```
pub use AlignmentKind;
pub use ;
pub use ObjectTextRenderer;
pub use RegularBackgroundTextRenderer;
pub use ;
/// A single letter's data required to render it.
/// A font that was imported using the [`include_font`] macro.
/// This can be used by creating a [`Layout`] that uses this font.