gsk4/
render_node.rs
1use glib::translate::*;
4
5use crate::{ffi, prelude::*, ParseLocation, RenderNode, RenderNodeType};
6
7impl RenderNode {
8 #[inline]
9 pub fn is<T: IsRenderNode>(&self) -> bool {
10 T::NODE_TYPE == self.node_type()
11 }
12
13 #[inline]
14 pub fn type_(&self) -> glib::Type {
15 unsafe {
16 let ptr = self.as_ptr();
17 from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
18 }
19 }
20
21 #[doc(alias = "gsk_render_node_deserialize")]
33 pub fn deserialize(bytes: &glib::Bytes) -> Option<Self> {
34 assert_initialized_main_thread!();
35 unsafe {
36 from_glib_full(ffi::gsk_render_node_deserialize(
37 bytes.to_glib_none().0,
38 None,
39 std::ptr::null_mut(),
40 ))
41 }
42 }
43
44 #[doc(alias = "gsk_render_node_deserialize")]
45 pub fn deserialize_with_error_func<P: FnMut(&ParseLocation, &ParseLocation, &glib::Error)>(
46 bytes: &glib::Bytes,
47 error_func: P,
48 ) -> Option<Self> {
49 assert_initialized_main_thread!();
50 let mut error_func_data: P = error_func;
51 unsafe extern "C" fn error_func_func<
52 P: FnMut(&ParseLocation, &ParseLocation, &glib::Error),
53 >(
54 start: *const ffi::GskParseLocation,
55 end: *const ffi::GskParseLocation,
56 error: *const glib::ffi::GError,
57 user_data: glib::ffi::gpointer,
58 ) {
59 let start = from_glib_borrow(start);
60 let end = from_glib_borrow(end);
61 let error = from_glib_borrow(error);
62 let callback = user_data as *mut P;
63 (*callback)(&start, &end, &error);
64 }
65 let error_func = Some(error_func_func::<P> as _);
66 let super_callback0: &mut P = &mut error_func_data;
67 unsafe {
68 from_glib_full(ffi::gsk_render_node_deserialize(
69 bytes.to_glib_none().0,
70 error_func,
71 super_callback0 as *mut _ as *mut _,
72 ))
73 }
74 }
75
76 #[inline]
77 pub fn downcast<T: IsRenderNode>(self) -> Result<T, Self> {
78 unsafe {
79 if self.is::<T>() {
80 Ok(from_glib_full(self.into_glib_ptr()))
81 } else {
82 Err(self)
83 }
84 }
85 }
86
87 #[inline]
88 pub fn downcast_ref<T: IsRenderNode>(&self) -> Option<&T> {
89 unsafe {
90 if self.is::<T>() {
91 Some(&*(self as *const RenderNode as *const T))
92 } else {
93 None
94 }
95 }
96 }
97}
98
99impl std::fmt::Debug for RenderNode {
100 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
101 f.debug_struct("RenderNode")
102 .field("bounds", &self.bounds())
103 .field("node_type", &self.node_type())
104 .finish()
105 }
106}
107
108pub unsafe trait IsRenderNode:
116 StaticType
117 + FromGlibPtrFull<*mut ffi::GskRenderNode>
118 + std::convert::AsRef<crate::RenderNode>
119 + 'static
120{
121 const NODE_TYPE: RenderNodeType;
122 fn upcast(self) -> RenderNode;
123 fn upcast_ref(&self) -> &RenderNode;
124}
125
126#[doc(hidden)]
127impl AsRef<RenderNode> for RenderNode {
128 #[inline]
129 fn as_ref(&self) -> &Self {
130 self
131 }
132}
133
134macro_rules! define_render_node {
135 ($rust_type:ident, $ffi_type:path, $node_type:path) => {
136 impl std::convert::AsRef<crate::RenderNode> for $rust_type {
137 #[inline]
138 fn as_ref(&self) -> &crate::RenderNode {
139 self
140 }
141 }
142
143 impl std::ops::Deref for $rust_type {
144 type Target = crate::RenderNode;
145
146 #[inline]
147 fn deref(&self) -> &Self::Target {
148 unsafe { &*(self as *const $rust_type as *const crate::RenderNode) }
149 }
150 }
151
152 unsafe impl crate::render_node::IsRenderNode for $rust_type {
153 const NODE_TYPE: RenderNodeType = $node_type;
154
155 #[inline]
156 fn upcast(self) -> crate::RenderNode {
157 unsafe {
158 glib::translate::from_glib_full(
159 glib::translate::IntoGlibPtr::<*mut $ffi_type>::into_glib_ptr(self)
160 as *mut crate::ffi::GskRenderNode,
161 )
162 }
163 }
164
165 #[inline]
166 fn upcast_ref(&self) -> &crate::RenderNode {
167 self
168 }
169 }
170
171 #[doc(hidden)]
172 impl glib::translate::FromGlibPtrFull<*mut crate::ffi::GskRenderNode> for $rust_type {
173 #[inline]
174 unsafe fn from_glib_full(ptr: *mut crate::ffi::GskRenderNode) -> Self {
175 glib::translate::from_glib_full(ptr as *mut $ffi_type)
176 }
177 }
178
179 #[cfg(feature = "v4_6")]
180 #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
181 impl glib::value::ValueType for $rust_type {
182 type Type = Self;
183 }
184
185 #[cfg(feature = "v4_6")]
186 #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
187 unsafe impl<'a> glib::value::FromValue<'a> for $rust_type {
188 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
189
190 #[inline]
191 unsafe fn from_value(value: &'a glib::Value) -> Self {
192 skip_assert_initialized!();
193 glib::translate::from_glib_full(crate::ffi::gsk_value_dup_render_node(
194 glib::translate::ToGlibPtr::to_glib_none(value).0,
195 ))
196 }
197 }
198
199 #[cfg(feature = "v4_6")]
200 #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
201 impl glib::value::ToValue for $rust_type {
202 #[inline]
203 fn to_value(&self) -> glib::Value {
204 let mut value = glib::Value::for_value_type::<Self>();
205 unsafe {
206 crate::ffi::gsk_value_set_render_node(
207 glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
208 self.as_ptr() as *mut _,
209 )
210 }
211 value
212 }
213
214 #[inline]
215 fn value_type(&self) -> glib::Type {
216 use glib::prelude::StaticType;
217 Self::static_type()
218 }
219 }
220
221 #[cfg(feature = "v4_6")]
222 #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
223 impl glib::value::ToValueOptional for $rust_type {
224 #[inline]
225 fn to_value_optional(s: Option<&Self>) -> glib::Value {
226 skip_assert_initialized!();
227 let mut value = glib::Value::for_value_type::<Self>();
228 unsafe {
229 crate::ffi::gsk_value_set_render_node(
230 glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
231 s.map(|s| s.as_ptr()).unwrap_or(std::ptr::null_mut()) as *mut _,
232 )
233 }
234 value
235 }
236 }
237 };
238}