plotters_gtk4/
snapshot.rs

1use std::convert::Infallible;
2
3use gtk::{pango, prelude::*};
4use plotters_backend::{
5    BackendColor, BackendCoord, BackendStyle, BackendTextStyle, DrawingBackend, DrawingErrorKind,
6};
7
8use crate::common;
9
10/// Backend that draws to a [`gtk::Snapshot`].
11#[derive(Debug)]
12pub struct SnapshotBackend<'a> {
13    snapshot: &'a gtk::Snapshot,
14    layout: pango::Layout,
15    size: (u32, u32),
16}
17
18impl<'a> SnapshotBackend<'a> {
19    /// Creates a new drawing backend backed with [`gtk::Snapshot`] with
20    /// the given width and height.
21    pub fn new(snapshot: &'a gtk::Snapshot, (w, h): (u32, u32)) -> Self {
22        let font_map = pangocairo::FontMap::default();
23        let context = font_map.create_context();
24        let layout = pango::Layout::new(&context);
25        Self {
26            snapshot,
27            layout,
28            size: (w, h),
29        }
30    }
31}
32
33impl<'a> DrawingBackend for SnapshotBackend<'a> {
34    type ErrorType = Infallible;
35
36    #[inline]
37    fn get_size(&self) -> (u32, u32) {
38        self.size
39    }
40
41    fn ensure_prepared(&mut self) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
42        Ok(())
43    }
44
45    fn present(&mut self) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
46        Ok(())
47    }
48
49    #[inline]
50    fn draw_pixel(
51        &mut self,
52        point: BackendCoord,
53        color: BackendColor,
54    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
55        common::draw_pixel(self.snapshot, point, color)
56    }
57
58    #[inline]
59    fn draw_line<S: BackendStyle>(
60        &mut self,
61        from: BackendCoord,
62        to: BackendCoord,
63        style: &S,
64    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
65        common::draw_line(self.snapshot, from, to, style)
66    }
67
68    #[inline]
69    fn draw_rect<S: BackendStyle>(
70        &mut self,
71        upper_left: BackendCoord,
72        bottom_right: BackendCoord,
73        style: &S,
74        fill: bool,
75    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
76        common::draw_rect(self.snapshot, upper_left, bottom_right, style, fill)
77    }
78
79    #[inline]
80    fn draw_path<S: BackendStyle, I: IntoIterator<Item = BackendCoord>>(
81        &mut self,
82        raw_path: I,
83        style: &S,
84    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
85        common::draw_path(self.snapshot, raw_path, style)
86    }
87
88    #[inline]
89    fn fill_polygon<S: BackendStyle, I: IntoIterator<Item = BackendCoord>>(
90        &mut self,
91        vert: I,
92        style: &S,
93    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
94        common::fill_polygon(self.snapshot, vert, style)
95    }
96
97    #[inline]
98    fn draw_circle<S: BackendStyle>(
99        &mut self,
100        center: BackendCoord,
101        radius: u32,
102        style: &S,
103        fill: bool,
104    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
105        common::draw_circle(self.snapshot, center, radius, style, fill)
106    }
107
108    #[inline]
109    fn estimate_text_size<TStyle: BackendTextStyle>(
110        &self,
111        text: &str,
112        style: &TStyle,
113    ) -> Result<(u32, u32), DrawingErrorKind<Self::ErrorType>> {
114        common::estimate_text_size(&self.layout, text, style)
115    }
116
117    #[inline]
118    fn draw_text<TStyle: BackendTextStyle>(
119        &mut self,
120        text: &str,
121        style: &TStyle,
122        pos: BackendCoord,
123    ) -> Result<(), DrawingErrorKind<Self::ErrorType>> {
124        common::draw_text(self.snapshot, &self.layout, text, style, pos)
125    }
126}