1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- 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<dmc::DMC>,
- }
- impl Data {
- pub fn draw_to_file<P: AsRef<std::path::Path>>(&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))
- }
- }
|