97 lines
2.9 KiB
Rust
97 lines
2.9 KiB
Rust
use image::{RgbaImage, imageops};
|
|
use rand::{Rng, seq::SliceRandom};
|
|
use showbits_assets::{EGG_BAD_COVERS, EGG_BAD_PATTERNS, EGG_COVERS, EGG_PATTERNS};
|
|
use showbits_common::{
|
|
Node, Tree, WidgetExt,
|
|
color::{self, WHITE},
|
|
widgets::{Image, Text},
|
|
};
|
|
use taffy::{AlignItems, Display, FlexDirection, style_helpers::percent};
|
|
|
|
use crate::printer::Printer;
|
|
|
|
use super::{Context, Drawing};
|
|
|
|
pub struct EggDrawing;
|
|
|
|
fn load_image(bytes: &[u8]) -> RgbaImage {
|
|
image::load_from_memory(bytes)
|
|
.expect("malformed image data")
|
|
.into_rgba8()
|
|
}
|
|
|
|
impl Drawing for EggDrawing {
|
|
fn draw(&self, printer: &mut Printer, ctx: &mut Context) -> anyhow::Result<()> {
|
|
let mut rng = rand::thread_rng();
|
|
|
|
// Choose which set of egg images to use
|
|
let bad_egg = rng.gen_range(0..8) == 0;
|
|
let (covers, patterns) = if bad_egg {
|
|
(EGG_BAD_COVERS, EGG_BAD_PATTERNS)
|
|
} else {
|
|
(EGG_COVERS, EGG_PATTERNS)
|
|
};
|
|
|
|
// Load images from memory
|
|
let covers = covers.iter().map(|img| load_image(img)).collect::<Vec<_>>();
|
|
let patterns = patterns
|
|
.iter()
|
|
.map(|img| load_image(img))
|
|
.collect::<Vec<_>>();
|
|
|
|
// Choose a random cover
|
|
let cover = covers.choose(&mut rng).expect("too few covers");
|
|
|
|
// Prepare image of appropriate size
|
|
let mut image =
|
|
RgbaImage::from_pixel(cover.width(), cover.height(), color::to_image_color(WHITE));
|
|
|
|
// Draw patterns onto egg
|
|
let mut last_idx = None;
|
|
let mut y = rng.gen_range(-100_i64..0);
|
|
while y < image.height().into() {
|
|
let idx = loop {
|
|
let idx = rng.gen_range(0..patterns.len());
|
|
if Some(idx) != last_idx {
|
|
break idx;
|
|
}
|
|
};
|
|
|
|
let paint = &patterns[idx];
|
|
imageops::overlay(&mut image, paint, 0, y);
|
|
y += <_ as Into<i64>>::into(paint.height());
|
|
last_idx = Some(idx);
|
|
}
|
|
|
|
// Finally, draw the cover
|
|
imageops::overlay(&mut image, cover, 0, 0);
|
|
|
|
let mut tree = Tree::<Context>::new(WHITE);
|
|
|
|
let image = Image::new(image)
|
|
.with_grow(false)
|
|
.with_shrink(false)
|
|
.node()
|
|
.register(&mut tree)?;
|
|
|
|
let text = Text::new()
|
|
.with_metrics(Text::default_metrics().scale(2.0))
|
|
.and_plain("Frohe Ostern!")
|
|
.widget(&mut ctx.font_stuff)
|
|
.node()
|
|
.register(&mut tree)?;
|
|
|
|
let root = Node::empty()
|
|
.with_size_width(percent(1.0))
|
|
.with_display(Display::Flex)
|
|
.with_flex_direction(FlexDirection::Column)
|
|
.with_align_items(Some(AlignItems::Center))
|
|
.and_child(image)
|
|
.and_child(text)
|
|
.register(&mut tree)?;
|
|
|
|
printer.print_tree(&mut tree, ctx, root)?;
|
|
printer.feed()?;
|
|
Ok(())
|
|
}
|
|
}
|