116 lines
2.7 KiB
Rust
116 lines
2.7 KiB
Rust
use ril::prelude::*;
|
|
use std::fs::File;
|
|
|
|
pub struct Template<T: AsRef<str>> {
|
|
elements: Vec<Element<T>>,
|
|
dimensions: (u32, u32),
|
|
base: Image,
|
|
}
|
|
|
|
impl<T: AsRef<str>> Template<T> {
|
|
pub fn new(base: Vec<u8>, elements: Vec<Element<T>>) -> Result<Self, ril::Error> {
|
|
let base: Image = Image::from_bytes_inferred(base)?;
|
|
Ok(Self {
|
|
dimensions: base.dimensions(),
|
|
elements,
|
|
base,
|
|
})
|
|
}
|
|
|
|
pub fn produce(mut self) -> Vec<u8> {
|
|
let size = self.base.dimensions();
|
|
for element in self.elements {
|
|
let mut pos = element.position;
|
|
let mut img: Image = element.into();
|
|
if pos.0 < 0 {
|
|
img.crop(-pos.0 as u32, 0, size.0, size.1);
|
|
pos.0 = 0;
|
|
}
|
|
if pos.1 < 0 {
|
|
img.crop(0, -pos.1 as u32, size.0, size.1);
|
|
pos.1 = 0;
|
|
}
|
|
|
|
self.base
|
|
.draw(&Paste::new(img).with_position(pos.0 as u32, pos.1 as u32));
|
|
}
|
|
let mut buf = Vec::<u8>::new();
|
|
self.base.encode(ImageFormat::Png, &mut buf).unwrap();
|
|
|
|
buf
|
|
}
|
|
}
|
|
|
|
pub struct Element<T: AsRef<str>> {
|
|
position: (i32, i32),
|
|
dimensions: (u32, u32),
|
|
media: Media<T>,
|
|
}
|
|
|
|
impl<T: AsRef<str>> Element<T> {
|
|
pub fn new(media: Media<T>, position: (i32, i32), dimensions: (u32, u32)) -> Self {
|
|
Self {
|
|
position,
|
|
dimensions,
|
|
media,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: AsRef<str>> Into<Image> for Element<T> {
|
|
fn into(self) -> Image {
|
|
match self.media {
|
|
Media::Image(image) => image.resized(
|
|
self.dimensions.0,
|
|
self.dimensions.1,
|
|
ResizeAlgorithm::Bicubic,
|
|
),
|
|
Media::Text(text) => Image::new(
|
|
self.dimensions.0,
|
|
self.dimensions.1,
|
|
Dynamic::Rgba(Rgba::transparent()),
|
|
)
|
|
.with(
|
|
&TextSegment::new(
|
|
&Font::from_reader(text.font, 12.0).unwrap(),
|
|
text.text,
|
|
Dynamic::Rgb(Rgb::new(text.fill.0, text.fill.1, text.fill.2)),
|
|
)
|
|
.with_size(text.size),
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum Media<T: AsRef<str>> {
|
|
Text(Text<T>),
|
|
Image(Image),
|
|
}
|
|
|
|
pub struct Text<T: AsRef<str>> {
|
|
text: T,
|
|
font: File,
|
|
size: f32,
|
|
fill: (u8, u8, u8),
|
|
}
|
|
|
|
impl<T: AsRef<str>> Text<T> {
|
|
pub fn new(text: T, font: File, size: f32, fill: (u8, u8, u8)) -> Self {
|
|
Self {
|
|
text,
|
|
font,
|
|
size,
|
|
fill,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#[test]
|
|
fn it_works() {
|
|
let result = 2 + 2;
|
|
assert_eq!(result, 4);
|
|
}
|
|
}
|