1use std::{fs::File, path::PathBuf};
2
3use anyhow::{Context, Result};
4use cairo::ImageSurface;
5use derive_builder::Builder;
6
7use crate::{
8 get_table_from_config, parser, remove_float_from_config,
9 remove_string_from_config,
10};
11
12#[derive(Debug, Builder, Clone)]
14#[builder_struct_attr(allow(missing_docs))]
15#[builder_impl_attr(allow(missing_docs))]
16pub struct Image {
17 surface: ImageSurface,
18 #[builder(default)]
19 x: f64,
20 #[builder(default)]
21 y: f64,
22}
23
24impl Image {
25 pub fn new(path: PathBuf, x: f64, y: f64) -> Result<Self> {
27 let mut file = File::open(path)?;
28 Ok(Self {
29 surface: ImageSurface::create_from_png(&mut file)?,
30 x,
31 y,
32 })
33 }
34
35 pub fn parse(name: &str) -> Result<Self> {
42 let images_table = parser::IMAGES.get().unwrap();
43
44 let mut table = get_table_from_config(name, images_table)
45 .with_context(|| format!("No subtable found with name {name}"))?;
46
47 let mut builder = ImageBuilder::default();
48
49 let path = remove_string_from_config("path", &mut table)
50 .context("No path specified")?;
51 let mut file = File::open(path)?;
52
53 builder.surface(ImageSurface::create_from_png(&mut file)?);
54
55 if let Some(x) = remove_float_from_config("x", &mut table) {
56 builder.x(x);
57 }
58
59 if let Some(y) = remove_float_from_config("y", &mut table) {
60 builder.y(y);
61 }
62
63 Ok(builder.build()?)
64 }
65
66 pub fn draw(&self, cr: &cairo::Context) -> Result<()> {
69 cr.save()?;
70
71 cr.set_source_surface(self.surface.as_ref(), 0.0, 0.0)?;
72 cr.rectangle(
73 self.x,
74 self.y,
75 self.surface.width() as f64,
76 self.surface.height() as f64,
77 );
78
79 cr.fill()?;
80 cr.restore()?;
81
82 Ok(())
83 }
84}