mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Add test for font output
This commit is contained in:
parent
6485cc895a
commit
1b71ef6473
|
@ -51,7 +51,7 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream {
|
|||
let advance_width = letter_data.advance_width.ceil() as u8;
|
||||
|
||||
quote!(
|
||||
agb::display::FontLetter::new(
|
||||
display::FontLetter::new(
|
||||
#width,
|
||||
#height,
|
||||
#data_raw,
|
||||
|
@ -63,6 +63,6 @@ pub fn load_font(font_data: &[u8], pixels_per_em: f32) -> TokenStream {
|
|||
});
|
||||
|
||||
quote![
|
||||
agb::display::Font::new(&[#(#font),*], #line_height, #ascent)
|
||||
display::Font::new(&[#(#font),*], #line_height, #ascent)
|
||||
]
|
||||
}
|
||||
|
|
|
@ -311,6 +311,13 @@ fn palete_tile_data(
|
|||
(palette_data, tile_data, assignments)
|
||||
}
|
||||
|
||||
fn flatten_group(expr: &Expr) -> &Expr {
|
||||
match expr {
|
||||
Expr::Group(group) => &group.expr,
|
||||
_ => expr,
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn include_font(input: TokenStream) -> TokenStream {
|
||||
let parser = Punctuated::<Expr, syn::Token![,]>::parse_separated_nonempty;
|
||||
|
@ -324,7 +331,7 @@ pub fn include_font(input: TokenStream) -> TokenStream {
|
|||
panic!("Include_font requires 2 arguments, got {}", all_args.len());
|
||||
}
|
||||
|
||||
let filename = match &all_args[0] {
|
||||
let filename = match flatten_group(&all_args[0]) {
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(str_lit),
|
||||
..
|
||||
|
@ -332,7 +339,7 @@ pub fn include_font(input: TokenStream) -> TokenStream {
|
|||
_ => panic!("Expected literal string as first argument to include_font"),
|
||||
};
|
||||
|
||||
let font_size = match &all_args[1] {
|
||||
let font_size = match flatten_group(&all_args[1]) {
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Float(value),
|
||||
..
|
||||
|
|
BIN
agb/examples/font/font-test-output.png
Normal file
BIN
agb/examples/font/font-test-output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -201,3 +201,48 @@ impl<'a> Drop for TextRenderer<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
const FONT: Font = crate::include_font!("examples/font/yoster.ttf", 12);
|
||||
|
||||
#[test_case]
|
||||
fn font_display(gba: &mut crate::Gba) {
|
||||
let (gfx, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let mut bg = gfx.background(crate::display::Priority::P0);
|
||||
|
||||
vram.set_background_palette_raw(&[
|
||||
0x0000, 0x0ff0, 0x00ff, 0xf00f, 0xf0f0, 0x0f0f, 0xaaaa, 0x5555, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
]);
|
||||
|
||||
let background_tile = vram.new_dynamic_tile().fill_with(0);
|
||||
|
||||
for y in 0..20u16 {
|
||||
for x in 0..30u16 {
|
||||
bg.set_tile(
|
||||
&mut vram,
|
||||
(x, y).into(),
|
||||
&background_tile.tile_set(),
|
||||
TileSetting::from_raw(background_tile.tile_index()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
vram.remove_dynamic_tile(background_tile);
|
||||
|
||||
let mut writer = FONT.render_text((0u16, 3u16).into(), 1, 2, &mut bg, &mut vram);
|
||||
|
||||
writeln!(&mut writer, "Hello, World!").unwrap();
|
||||
writeln!(&mut writer, "This is a font rendering example").unwrap();
|
||||
|
||||
writer.commit();
|
||||
|
||||
bg.commit();
|
||||
bg.show();
|
||||
|
||||
crate::test_runner::assert_image_output("examples/font/font-test-output.png");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -961,6 +961,7 @@ mod tests {
|
|||
|
||||
let object = gba.display.object.get();
|
||||
|
||||
{
|
||||
let mut objects: Vec<_> = alloc::vec![
|
||||
object.object(object.sprite(BOSS.sprite(0))),
|
||||
object.object(object.sprite(EMU.sprite(0))),
|
||||
|
@ -980,4 +981,7 @@ mod tests {
|
|||
|
||||
object.commit();
|
||||
}
|
||||
|
||||
object.commit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,9 +112,19 @@
|
|||
/// ```
|
||||
pub use agb_image_converter::include_gfx;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use agb_image_converter::include_aseprite_inner;
|
||||
|
||||
pub use agb_image_converter::include_font;
|
||||
#[doc(hidden)]
|
||||
pub use agb_image_converter::include_font as include_font_inner;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! include_font {
|
||||
($font_path: literal, $font_size: literal) => {{
|
||||
use $crate::display;
|
||||
$crate::include_font_inner!($font_path, $font_size)
|
||||
}};
|
||||
}
|
||||
|
||||
/// This macro declares the entry point to your game written using `agb`.
|
||||
///
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
mod runner;
|
||||
use anyhow::{anyhow, Error};
|
||||
use image::io::Reader;
|
||||
use image::GenericImage;
|
||||
use io::Write;
|
||||
use regex::Regex;
|
||||
use runner::VideoBuffer;
|
||||
|
@ -135,15 +136,14 @@ fn rgba_to_gba_to_rgba(c: [u8; 4]) -> [u8; 4] {
|
|||
|
||||
fn check_image_match(image_path: &str, video_buffer: &VideoBuffer) -> Result<(), Error> {
|
||||
let expected_image = Reader::open(image_path)?.decode()?;
|
||||
let expected = expected_image
|
||||
.as_rgba8()
|
||||
.ok_or(anyhow!("cannot convert to rgba8"))?;
|
||||
let expected = expected_image.to_rgba8();
|
||||
|
||||
let (buf_dim_x, buf_dim_y) = video_buffer.get_size();
|
||||
let (exp_dim_x, exp_dim_y) = expected.dimensions();
|
||||
if (buf_dim_x != exp_dim_x) || (buf_dim_y != exp_dim_y) {
|
||||
return Err(anyhow!("image sizes do not match"));
|
||||
}
|
||||
|
||||
for y in 0..buf_dim_y {
|
||||
for x in 0..buf_dim_x {
|
||||
let video_pixel = video_buffer.get_pixel(x, y);
|
||||
|
@ -151,10 +151,37 @@ fn check_image_match(image_path: &str, video_buffer: &VideoBuffer) -> Result<(),
|
|||
let video_pixel = gba_colour_to_rgba(video_pixel);
|
||||
let image_pixel = rgba_to_gba_to_rgba(image_pixel.0);
|
||||
if image_pixel != video_pixel {
|
||||
return Err(anyhow!("images do not match"));
|
||||
let output_file = write_video_buffer(video_buffer);
|
||||
|
||||
return Err(anyhow!(
|
||||
"images do not match, actual output written to {}",
|
||||
output_file
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_video_buffer(video_buffer: &VideoBuffer) -> String {
|
||||
let (width, height) = video_buffer.get_size();
|
||||
let mut output_image = image::DynamicImage::new_rgba8(width, height);
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
let pixel = video_buffer.get_pixel(x, y);
|
||||
let pixel_as_rgba = gba_colour_to_rgba(pixel);
|
||||
|
||||
output_image.put_pixel(x, y, pixel_as_rgba.into())
|
||||
}
|
||||
}
|
||||
|
||||
let output_folder = std::env::temp_dir();
|
||||
let output_file = "mgba-test-runner-output.png"; // TODO make this random
|
||||
|
||||
let output_file = output_folder.join(output_file);
|
||||
let _ = output_image.save_with_format(&output_file, image::ImageFormat::Png);
|
||||
|
||||
output_file.to_string_lossy().into_owned()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue