Skip to main content

gsk4/auto/
render_replay.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{RenderNode, ffi};
6use glib::{prelude::*, translate::*};
7use std::boxed::Box as Box_;
8
9glib::wrapper! {
10    /// A facility to replay a [`RenderNode`][crate::RenderNode] and its children, potentially
11    /// modifying them.
12    ///
13    /// This is a utility tool to walk a rendernode tree. The most powerful way
14    /// is to provide a function via [`set_node_filter()`][Self::set_node_filter()]
15    /// to filter each individual node and then run
16    /// [`filter_node()`][Self::filter_node()] on the nodes you want to filter.
17    ///
18    /// If you want to just walk the node tree and extract information
19    /// without any modifications, you can also use [`RenderNode::children()`][crate::RenderNode::children()].
20    ///
21    /// Here is a little example application that redacts text in a node file:
22    ///
23    /// ```text
24    /// #include <gtk/gtk.h>
25    ///
26    /// static GskRenderNode *
27    /// redact_nodes (GskRenderReplay *replay,
28    ///               GskRenderNode   *node,
29    ///               gpointer         user_data)
30    /// {
31    ///   GskRenderNode *result;
32    ///
33    ///   if (gsk_render_node_get_node_type (node) == GSK_TEXT_NODE)
34    ///     {
35    ///       graphene_rect_t bounds;
36    ///       const GdkRGBA *color;
37    ///
38    ///       gsk_render_node_get_bounds (node, &bounds);
39    ///       color = gsk_text_node_get_color (node);
40    ///
41    ///       result = gsk_color_node_new (color, &bounds);
42    ///     }
43    ///   else
44    ///     {
45    ///       result = gsk_render_replay_default (replay, node);
46    ///     }
47    ///
48    ///   return result;
49    /// }
50    ///
51    /// int
52    /// main (int argc, char *argv[])
53    /// {
54    ///   GFile *file;
55    ///   GBytes *bytes;
56    ///   GskRenderNode *result, *node;
57    ///   GskRenderReplay *replay;
58    ///
59    ///   gtk_init ();
60    ///
61    ///   if (argc != 3)
62    ///     {
63    ///       g_print ("usage: %s INFILE OUTFILE\n", argv[0]);
64    ///       return 0;
65    ///     }
66    ///
67    ///   file = g_file_new_for_commandline_arg (argv[1]);
68    ///   bytes = g_file_load_bytes (file, NULL, NULL, NULL);
69    ///   g_object_unref (file);
70    ///   if (bytes == NULL)
71    ///     return 1;
72    ///
73    ///   node = gsk_render_node_deserialize (bytes, NULL, NULL);
74    ///   g_bytes_unref (bytes);
75    ///   if (node == NULL)
76    ///     return 1;
77    ///
78    ///   replay = gsk_render_replay_new ();
79    ///   gsk_render_replay_set_node_filter (replay, redact_nodes, NULL, NULL);
80    ///   result = gsk_render_replay_filter_node (replay, node);
81    ///   gsk_render_replay_free (replay);
82    ///
83    ///   if (!gsk_render_node_write_to_file (result, argv[2], NULL))
84    ///     return 1;
85    ///
86    ///   gsk_render_node_unref (result);
87    ///   gsk_render_node_unref (node);
88    ///
89    ///   return 0;
90    /// }
91    /// ```
92    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
93    pub struct RenderReplay(Boxed<ffi::GskRenderReplay>);
94
95    match fn {
96        copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::gsk_render_replay_get_type(), ptr as *mut _) as *mut ffi::GskRenderReplay,
97        free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::gsk_render_replay_get_type(), ptr as *mut _),
98        type_ => || ffi::gsk_render_replay_get_type(),
99    }
100}
101
102impl RenderReplay {
103    /// Creates a new replay object to replay nodes.
104    ///
105    /// # Returns
106    ///
107    /// A new replay object to replay nodes
108    #[doc(alias = "gsk_render_replay_new")]
109    pub fn new() -> RenderReplay {
110        assert_initialized_main_thread!();
111        unsafe { from_glib_full(ffi::gsk_render_replay_new()) }
112    }
113
114    /// Replays the node using the default method.
115    ///
116    /// The default method calls [`filter_node()`][Self::filter_node()]
117    /// on all its child nodes and the filter functions for all its
118    /// properties. If none of them are changed, it returns the passed
119    /// in node. Otherwise it constructs a new node with the changed
120    /// children and properties.
121    ///
122    /// It may not be possible to construct a new node when any of the
123    /// callbacks return NULL. In that case, this function will return
124    /// NULL, too.
125    /// ## `node`
126    /// the node to replay
127    ///
128    /// # Returns
129    ///
130    /// The replayed node
131    #[doc(alias = "gsk_render_replay_default")]
132    #[allow(clippy::should_implement_trait)]
133    pub fn default(&mut self, node: impl AsRef<RenderNode>) -> Option<RenderNode> {
134        unsafe {
135            from_glib_full(ffi::gsk_render_replay_default(
136                self.to_glib_none_mut().0,
137                node.as_ref().to_glib_none().0,
138            ))
139        }
140    }
141
142    /// Filters a font using the current filter function.
143    /// ## `font`
144    /// The font to filter
145    ///
146    /// # Returns
147    ///
148    /// the filtered font
149    #[doc(alias = "gsk_render_replay_filter_font")]
150    pub fn filter_font(&mut self, font: &impl IsA<pango::Font>) -> pango::Font {
151        unsafe {
152            from_glib_full(ffi::gsk_render_replay_filter_font(
153                self.to_glib_none_mut().0,
154                font.as_ref().to_glib_none().0,
155            ))
156        }
157    }
158
159    /// Replays a node using the replay's filter function.
160    ///
161    /// After the replay the node may be unchanged, or it may be
162    /// removed, which will result in [`None`] being returned.
163    ///
164    /// If no filter node is set, [`default()`][Self::default()] is
165    /// called instead.
166    /// ## `node`
167    /// the node to replay
168    ///
169    /// # Returns
170    ///
171    /// The replayed node
172    #[doc(alias = "gsk_render_replay_filter_node")]
173    pub fn filter_node(&mut self, node: impl AsRef<RenderNode>) -> Option<RenderNode> {
174        unsafe {
175            from_glib_full(ffi::gsk_render_replay_filter_node(
176                self.to_glib_none_mut().0,
177                node.as_ref().to_glib_none().0,
178            ))
179        }
180    }
181
182    /// Filters a texture using the current filter function.
183    /// ## `texture`
184    /// The texture to filter
185    ///
186    /// # Returns
187    ///
188    /// the filtered texture
189    #[doc(alias = "gsk_render_replay_filter_texture")]
190    pub fn filter_texture(&mut self, texture: &impl IsA<gdk::Texture>) -> gdk::Texture {
191        unsafe {
192            from_glib_full(ffi::gsk_render_replay_filter_texture(
193                self.to_glib_none_mut().0,
194                texture.as_ref().to_glib_none().0,
195            ))
196        }
197    }
198
199    /// Sets a filter function to be called by [`default()`][Self::default()]
200    /// for nodes that contain fonts.
201    ///
202    /// You can call `GskRenderReplay::filter_font()` to filter
203    /// a font yourself.
204    /// ## `filter`
205    ///
206    ///   the font filter function
207    #[doc(alias = "gsk_render_replay_set_font_filter")]
208    pub fn set_font_filter(
209        &mut self,
210        filter: Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
211    ) {
212        let filter_data: Box_<
213            Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
214        > = Box_::new(filter);
215        unsafe extern "C" fn filter_func(
216            replay: *mut ffi::GskRenderReplay,
217            font: *mut pango::ffi::PangoFont,
218            user_data: glib::ffi::gpointer,
219        ) -> *mut pango::ffi::PangoFont {
220            unsafe {
221                let replay = from_glib_borrow(replay);
222                let font = from_glib_borrow(font);
223                let callback = &*(user_data
224                    as *mut Option<
225                        Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>,
226                    >);
227                if let Some(ref callback) = *callback {
228                    callback(&replay, &font)
229                } else {
230                    panic!("cannot get closure...")
231                }
232                .to_glib_full()
233            }
234        }
235        let filter = if filter_data.is_some() {
236            Some(filter_func as _)
237        } else {
238            None
239        };
240        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
241            unsafe {
242                let _callback = Box_::from_raw(
243                    data as *mut Option<
244                        Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>,
245                    >,
246                );
247            }
248        }
249        let destroy_call3 = Some(user_destroy_func as _);
250        let super_callback0: Box_<
251            Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
252        > = filter_data;
253        unsafe {
254            ffi::gsk_render_replay_set_font_filter(
255                self.to_glib_none_mut().0,
256                filter,
257                Box_::into_raw(super_callback0) as *mut _,
258                destroy_call3,
259            );
260        }
261    }
262
263    /// Sets the function to use as a node filter.
264    ///
265    /// This is the most complex function to use for replaying nodes.
266    /// It can either:
267    ///
268    /// * keep the node and just return it unchanged
269    ///
270    /// * create a replacement node and return that
271    ///
272    /// * discard the node by returning `NULL`
273    ///
274    /// * call [`default()`][Self::default()] to have the default handler
275    ///   run for this node, which calls your function on its children
276    /// ## `filter`
277    ///
278    ///   the function to call to replay nodes
279    #[doc(alias = "gsk_render_replay_set_node_filter")]
280    pub fn set_node_filter(
281        &mut self,
282        filter: Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
283    ) {
284        let filter_data: Box_<
285            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
286        > = Box_::new(filter);
287        unsafe extern "C" fn filter_func(
288            replay: *mut ffi::GskRenderReplay,
289            node: *mut ffi::GskRenderNode,
290            user_data: glib::ffi::gpointer,
291        ) -> *mut ffi::GskRenderNode {
292            unsafe {
293                let replay = from_glib_borrow(replay);
294                let node = from_glib_borrow(node);
295                let callback = &*(user_data
296                    as *mut Option<
297                        Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
298                    >);
299                if let Some(ref callback) = *callback {
300                    callback(&replay, &node)
301                } else {
302                    panic!("cannot get closure...")
303                }
304                .to_glib_full()
305            }
306        }
307        let filter = if filter_data.is_some() {
308            Some(filter_func as _)
309        } else {
310            None
311        };
312        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
313            unsafe {
314                let _callback = Box_::from_raw(
315                    data as *mut Option<
316                        Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
317                    >,
318                );
319            }
320        }
321        let destroy_call3 = Some(user_destroy_func as _);
322        let super_callback0: Box_<
323            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
324        > = filter_data;
325        unsafe {
326            ffi::gsk_render_replay_set_node_filter(
327                self.to_glib_none_mut().0,
328                filter,
329                Box_::into_raw(super_callback0) as *mut _,
330                destroy_call3,
331            );
332        }
333    }
334
335    /// Sets a filter function to be called by [`default()`][Self::default()]
336    /// for nodes that contain textures.
337    ///
338    /// You can call `GskRenderReplay::filter_texture()` to filter
339    /// a texture yourself.
340    /// ## `filter`
341    ///
342    ///   the texture filter function
343    #[doc(alias = "gsk_render_replay_set_texture_filter")]
344    pub fn set_texture_filter(
345        &mut self,
346        filter: Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
347    ) {
348        let filter_data: Box_<
349            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
350        > = Box_::new(filter);
351        unsafe extern "C" fn filter_func(
352            replay: *mut ffi::GskRenderReplay,
353            texture: *mut gdk::ffi::GdkTexture,
354            user_data: glib::ffi::gpointer,
355        ) -> *mut gdk::ffi::GdkTexture {
356            unsafe {
357                let replay = from_glib_borrow(replay);
358                let texture = from_glib_borrow(texture);
359                let callback = &*(user_data
360                    as *mut Option<
361                        Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
362                    >);
363                if let Some(ref callback) = *callback {
364                    callback(&replay, &texture)
365                } else {
366                    panic!("cannot get closure...")
367                }
368                .to_glib_full()
369            }
370        }
371        let filter = if filter_data.is_some() {
372            Some(filter_func as _)
373        } else {
374            None
375        };
376        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
377            unsafe {
378                let _callback = Box_::from_raw(
379                    data as *mut Option<
380                        Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
381                    >,
382                );
383            }
384        }
385        let destroy_call3 = Some(user_destroy_func as _);
386        let super_callback0: Box_<
387            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
388        > = filter_data;
389        unsafe {
390            ffi::gsk_render_replay_set_texture_filter(
391                self.to_glib_none_mut().0,
392                filter,
393                Box_::into_raw(super_callback0) as *mut _,
394                destroy_call3,
395            );
396        }
397    }
398}
399
400#[cfg(feature = "v4_22")]
401#[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
402impl Default for RenderReplay {
403    fn default() -> Self {
404        Self::new()
405    }
406}