img-gen-renderer 0.1.0

A library to render images from img-gen-spec
Documentation
use super::{ConcreteSize, Renderer};
use crate::{Corners, ImgGenRendererError, Layer, Result};
use image::RgbaImage;
use resvg::tiny_skia::PathBuilder;

impl Renderer<'_> {
    pub fn render_rectangle(
        &self,
        layer: &Layer,
        size: ConcreteSize,
        canvas: &mut RgbaImage,
    ) -> Result<()> {
        if let Some(l) = layer.rectangle.as_ref() {
            let border_width = l.border.as_ref().map_or(0, |b| b.width.get());
            let max_radius = (size.width.min(size.height) as f32 / 2.0).min(l.radius);
            let path = {
                let mut pb = PathBuilder::new();
                let inset = border_width as f32 / 2.0;
                if l.corners.contains(&Corners::TopLeft) && max_radius > 0.0 {
                    pb.move_to(inset, max_radius);
                    pb.quad_to(inset, inset, max_radius + inset, inset);
                } else {
                    pb.move_to(inset, inset);
                }
                if l.corners.contains(&Corners::TopRight) && max_radius > 0.0 {
                    pb.line_to(size.width as f32 - inset - max_radius, inset);
                    pb.quad_to(
                        size.width as f32 - inset,
                        inset,
                        size.width as f32 - inset,
                        max_radius,
                    );
                } else {
                    pb.line_to(size.width as f32 - inset, inset);
                }
                if l.corners.contains(&Corners::BottomRight) && max_radius > 0.0 {
                    pb.line_to(
                        size.width as f32 - inset,
                        size.height as f32 - max_radius - inset,
                    );
                    pb.quad_to(
                        size.width as f32 - inset,
                        size.height as f32 - inset,
                        size.width as f32 - inset - max_radius,
                        size.height as f32 - inset,
                    );
                } else {
                    pb.line_to(size.width as f32 - inset, size.height as f32 - inset);
                }
                if l.corners.contains(&Corners::BottomLeft) && max_radius > 0.0 {
                    pb.line_to(inset + max_radius, size.height as f32 - inset);
                    pb.quad_to(
                        inset,
                        size.height as f32 - inset,
                        inset,
                        size.height as f32 - inset - max_radius,
                    );
                } else {
                    pb.line_to(inset, size.height as f32 - inset);
                }
                pb.close();
                pb.finish()
                    .ok_or(ImgGenRendererError::InvalidPathBounds { shape: "rectangle" })?
            };
            Self::render_shape(path, &l.color, size, &layer.offset, &l.border, canvas)?;
        }
        Ok(())
    }
}