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}