use crate::dmc; use anyhow::{anyhow, bail, Result}; /// The data necessary to represent a stich legend icon. pub struct Data { /// The character we want to draw. pub symbol: char, /// The DMC thread color we want to use. This will be `None` if /// the user has not entered in a valid DMC thread, and we'll draw /// a bland gray background in that case pub dmc: Option, } impl Data { pub fn draw_to_file>(&self, path: P) -> Result<()> { let f = std::fs::File::create(path)?; let surf = cairo::SvgSurface::for_stream(100.0, 100.0, f)?; self.render(&cairo::Context::new(&surf), 100.0, 100.0)?; if let Err(err) = surf.finish_output_stream() { bail!(err.error); }; Ok(()) } pub fn render(&self, ctx: &cairo::Context, w: f64, h: f64) -> Result<()> { let off_x = (w - 100.) / 2.0; let off_y = (h - 100.) / 2.0; let color = self.color(); ctx.set_source_rgb(color.0, color.1, color.2); ctx.paint(); ctx.set_source_rgb(0., 0., 0.); ctx.rectangle(off_x, off_y, 100., 100.); ctx.stroke(); ctx.move_to(off_x, off_y - 23.0); let layout = pangocairo::functions::create_layout(&ctx) .ok_or_else(|| anyhow!("Could not create layout"))?; layout.set_width(100 * 1024); layout.set_alignment(pango::Alignment::Center); let font = pango::FontDescription::from_string("Fira Sans 92"); layout.set_font_description(Some(&font)); layout.set_text(&self.symbol.to_string()); pangocairo::functions::show_layout(&ctx, &layout); Ok(()) } fn color(&self) -> (f64, f64, f64) { self.dmc .map(|dmc| dmc.color) .unwrap_or_else(|| (0.5, 0.5, 0.5)) } }