diff --git a/cowgen/src/lib.rs b/cowgen/src/lib.rs index 6b12b65..1d000f6 100644 --- a/cowgen/src/lib.rs +++ b/cowgen/src/lib.rs @@ -1,28 +1,47 @@ use ril::prelude::*; use std::fs::File; -struct Template> { +pub struct Template> { elements: Vec>, dimensions: (u32, u32), base: Image, } impl> Template { - pub fn new(elements: Vec>) -> Self { - Self { + pub fn new(base: Vec, elements: Vec>) -> Result { + let base: Image = Image::from_bytes_inferred(base)?; + Ok(Self { + dimensions: base.dimensions(), elements, - } + base, + }) } - pub fn produce(self, image: File) -> Result { + pub fn produce(mut self) -> Vec { + let size = self.base.dimensions(); for element in self.elements { - - image.draw - } - } + 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::::new(); + self.base.encode(ImageFormat::Png, &mut buf).unwrap(); + + buf + } } -struct Element> { +pub struct Element> { position: (i32, i32), dimensions: (u32, u32), media: Media, @@ -39,16 +58,26 @@ impl> Element { } impl> Into for Element { - pub fn into(self) -> Image { + 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, Rgba::transparent()) - .with(TextSegment::new(text.font, text.text, Rgb::new(text.fill.0, text.fill.1, text.fill.2)) - .with_size(text.size)) - }, + 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), + ), } } } @@ -58,7 +87,7 @@ pub enum Media> { Image(Image), } -struct Text> { +pub struct Text> { text: T, font: File, size: f32, @@ -66,17 +95,15 @@ struct Text> { } impl> Text { - pub fn new(contents: T, font: File, size: f32, fill: (u8, u8, u8)) -> Self { + pub fn new(text: T, font: File, size: f32, fill: (u8, u8, u8)) -> Self { Self { - contents, + text, font, size, fill, } } -} - - +} #[cfg(test)] mod tests {