Extract method

This commit is contained in:
Gwilym Kuiper 2022-04-23 14:34:34 +01:00
parent fec4015978
commit 6485cc895a

View file

@ -91,11 +91,6 @@ pub struct TextRenderer<'a> {
impl<'a> Write for TextRenderer<'a> {
fn write_str(&mut self, text: &str) -> Result<(), Error> {
let vram_manager = &mut self.vram_manager;
let tiles = &mut self.tiles;
let foreground_colour = self.foreground_colour;
let background_colour = self.background_colour;
for c in text.chars() {
if c == '\n' {
self.current_y_pos += self.font.line_height;
@ -105,63 +100,7 @@ impl<'a> Write for TextRenderer<'a> {
let letter = self.font.letter(c);
let x_start = (self.current_x_pos + letter.xmin as i32).max(0);
let y_start =
self.current_y_pos + self.font.ascent - letter.height as i32 - letter.ymin as i32;
let x_tile_start = x_start / 8;
let y_tile_start = y_start / 8;
let letter_offset_x = x_start.rem_euclid(8);
let letter_offset_y = y_start.rem_euclid(8);
let x_tiles = div_ceil(letter.width as i32 + letter_offset_x, 8);
let y_tiles = div_ceil(letter.height as i32 + letter_offset_y, 8);
for letter_y_tile in 0..(y_tiles + 1) {
let letter_y_start = 0.max(letter_offset_y - 8 * letter_y_tile) + 8 * letter_y_tile;
let letter_y_end =
(letter_offset_y + letter.height as i32).min((letter_y_tile + 1) * 8);
let tile_y = y_tile_start + letter_y_tile;
for letter_x_tile in 0..(x_tiles + 1) {
let letter_x_start =
0.max(letter_offset_x - 8 * letter_x_tile) + 8 * letter_x_tile;
let letter_x_end =
(letter_offset_x + letter.width as i32).min((letter_x_tile + 1) * 8);
let tile_x = x_tile_start + letter_x_tile;
let mut masks = [0u32; 8];
let mut zero = true;
for letter_y in letter_y_start..letter_y_end {
let y = letter_y - letter_offset_y;
for letter_x in letter_x_start..letter_x_end {
let x = letter_x - letter_offset_x;
let px = letter.data[(x + y * letter.width as i32) as usize];
if px > 100 {
masks[(letter_y & 7) as usize] |=
(foreground_colour as u32) << ((letter_x & 7) * 4);
zero = false;
}
}
}
if !zero {
let tile = tiles.entry((tile_x, tile_y)).or_insert_with(|| {
vram_manager.new_dynamic_tile().fill_with(background_colour)
});
for (i, tile_data_line) in tile.tile_data.iter_mut().enumerate() {
*tile_data_line |= masks[i];
}
}
}
}
self.render_letter(letter);
self.current_x_pos += letter.advance_width as i32;
}
@ -175,6 +114,69 @@ fn div_ceil(quotient: i32, divisor: i32) -> i32 {
}
impl<'a> TextRenderer<'a> {
fn render_letter(&mut self, letter: &FontLetter) {
let vram_manager = &mut self.vram_manager;
let foreground_colour = self.foreground_colour;
let background_colour = self.background_colour;
let x_start = (self.current_x_pos + letter.xmin as i32).max(0);
let y_start =
self.current_y_pos + self.font.ascent - letter.height as i32 - letter.ymin as i32;
let x_tile_start = x_start / 8;
let y_tile_start = y_start / 8;
let letter_offset_x = x_start.rem_euclid(8);
let letter_offset_y = y_start.rem_euclid(8);
let x_tiles = div_ceil(letter.width as i32 + letter_offset_x, 8);
let y_tiles = div_ceil(letter.height as i32 + letter_offset_y, 8);
for letter_y_tile in 0..(y_tiles + 1) {
let letter_y_start = 0.max(letter_offset_y - 8 * letter_y_tile) + 8 * letter_y_tile;
let letter_y_end =
(letter_offset_y + letter.height as i32).min((letter_y_tile + 1) * 8);
let tile_y = y_tile_start + letter_y_tile;
for letter_x_tile in 0..(x_tiles + 1) {
let letter_x_start = 0.max(letter_offset_x - 8 * letter_x_tile) + 8 * letter_x_tile;
let letter_x_end =
(letter_offset_x + letter.width as i32).min((letter_x_tile + 1) * 8);
let tile_x = x_tile_start + letter_x_tile;
let mut masks = [0u32; 8];
let mut zero = true;
for letter_y in letter_y_start..letter_y_end {
let y = letter_y - letter_offset_y;
for letter_x in letter_x_start..letter_x_end {
let x = letter_x - letter_offset_x;
let px = letter.data[(x + y * letter.width as i32) as usize];
if px > 100 {
masks[(letter_y & 7) as usize] |=
(foreground_colour as u32) << ((letter_x & 7) * 4);
zero = false;
}
}
}
if !zero {
let tile = self.tiles.entry((tile_x, tile_y)).or_insert_with(|| {
vram_manager.new_dynamic_tile().fill_with(background_colour)
});
for (i, tile_data_line) in tile.tile_data.iter_mut().enumerate() {
*tile_data_line |= masks[i];
}
}
}
}
}
pub fn commit(mut self) {
let tiles = core::mem::take(&mut self.tiles);