Skip to content

Commit

Permalink
Update test image and add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
rfuest committed Feb 1, 2024
1 parent d02d60f commit 075a26f
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 34 deletions.
1 change: 1 addition & 0 deletions mipidsi/docs/test_image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 92 additions & 34 deletions mipidsi/src/test_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@ use embedded_graphics_core::{
///
/// The test image can be used to check if the display is working and to
/// identify the correct orientation and color settings.
///
/// # Expected output
///
#[doc = include_str!("../docs/test_image.svg")]
///
/// Note that the gray border around the image above is only added to make the
/// white border visible on the light rustdoc theme and will not be visible when
/// the test image is drawn.
///
/// - There should be a one pixel white border around the display.
/// Modify the [display size](crate::Builder::with_display_size) and [display
/// offset](crate::Builder::with_display_offset) settings, if at least one
/// edge of the white border isn't drawn or if there is a gap between the
/// white border and the edge of the display.
/// - A white triangle should be drawn in the top left corner and the RGB label text should not be mirrored.
/// Modify the [orientation](crate::Builder::with_orientation) setting to
/// rotate and mirror the display until the test image is displayed correctly.
/// Note that the white triangle might not be visible on displays with rounded
/// corners.
/// - The colored bars should match the labels.
/// Use the [color inversion](crate::Builder::with_invert_colors) and [color
/// order](crate::Builder::with_color_order) settings until the colored bars
/// and labels match.
#[derive(Default)]
pub struct TestImage<C: RgbColor> {
color_type: PhantomData<C>,
Expand All @@ -24,8 +47,9 @@ impl<C: RgbColor> TestImage<C> {
}
}

const CORNER_SIZE: u32 = 10;
const CORNER_STROKE_WIDTH: u32 = 1;
const BORDER_WIDTH: u32 = 1;
const BORDER_PADDING: u32 = 4;
const TOP_LEFT_MARKER_SIZE: u32 = 20;

impl<C: RgbColor> Drawable for TestImage<C> {
type Color = C;
Expand All @@ -35,44 +59,78 @@ impl<C: RgbColor> Drawable for TestImage<C> {
where
D: DrawTarget<Color = Self::Color>,
{
let bounding_box = target.bounding_box();
target.fill_solid(&bounding_box, RgbColor::GREEN)?;
Character::new(G, bounding_box.center()).draw(target)?;

let rect = bounding_box.resized_width(bounding_box.size.width / 3, AnchorX::Left);
target.fill_solid(&rect, RgbColor::RED)?;
Character::new(R, rect.center()).draw(target)?;

let rect = bounding_box.resized_width(bounding_box.size.width / 3, AnchorX::Right);
target.fill_solid(&rect, RgbColor::BLUE)?;
Character::new(B, rect.center()).draw(target)?;

for anchor in [
AnchorPoint::TopLeft,
AnchorPoint::TopRight,
AnchorPoint::BottomLeft,
AnchorPoint::BottomRight,
] {
target.fill_solid(
&bounding_box.resized(Size::new(CORNER_SIZE, CORNER_STROKE_WIDTH), anchor),
C::WHITE,
)?;
target.fill_solid(
&bounding_box.resized(Size::new(CORNER_STROKE_WIDTH, CORNER_SIZE), anchor),
C::WHITE,
)?;
}
draw_border(target, BORDER_WIDTH)?;

let top_left_marker = Rectangle::new(
Point::new_equal((CORNER_STROKE_WIDTH * 3) as i32),
Size::new_equal(CORNER_SIZE - 3 * CORNER_STROKE_WIDTH),
);
target.fill_solid(&top_left_marker, C::WHITE)?;
let color_bar_area = target
.bounding_box()
.offset(-i32::try_from(BORDER_WIDTH + BORDER_PADDING).unwrap());
draw_color_bars(target, &color_bar_area)?;

draw_top_left_marker(target, &color_bar_area, TOP_LEFT_MARKER_SIZE)?;

Ok(())
}
}

/// Draws a white border around the draw target.
fn draw_border<D>(target: &mut D, width: u32) -> Result<(), D::Error>
where
D: DrawTarget,
D::Color: RgbColor,
{
let bounding_box = target.bounding_box();
let inner_box = bounding_box.offset(-i32::try_from(width).unwrap());

target.fill_contiguous(
&bounding_box,
bounding_box.points().map(|p| {
if inner_box.contains(p) {
D::Color::BLACK
} else {
D::Color::WHITE
}
}),
)
}

/// Draws RGB color bars and labels.
fn draw_color_bars<D>(target: &mut D, area: &Rectangle) -> Result<(), D::Error>
where
D: DrawTarget,
D::Color: RgbColor,
{
target.fill_solid(area, RgbColor::GREEN)?;
Character::new(G, area.center()).draw(target)?;

let rect = area.resized_width(area.size.width / 3, AnchorX::Left);
target.fill_solid(&rect, RgbColor::RED)?;
Character::new(R, rect.center()).draw(target)?;

let rect = area.resized_width(area.size.width / 3, AnchorX::Right);
target.fill_solid(&rect, RgbColor::BLUE)?;
Character::new(B, rect.center()).draw(target)?;

Ok(())
}

// Draws a triangular marker in the top left corner.
fn draw_top_left_marker<D>(target: &mut D, area: &Rectangle, size: u32) -> Result<(), D::Error>
where
D: DrawTarget,
D::Color: RgbColor,
{
let mut rect = area.resized(Size::new(size, 1), AnchorPoint::TopLeft);

while rect.size.width > 0 {
target.fill_solid(&rect, D::Color::WHITE)?;

rect.top_left.y += 1;
rect.size.width -= 1;
}

Ok(())
}

const R: &[u8] = &[
0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 0, 0, 0, 0, 0, //
Expand Down

0 comments on commit 075a26f

Please sign in to comment.