Skip to main content

gsk4/
path.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{Path, PathForeachFlags, PathOperation, ffi};
6#[cfg(feature = "v4_20")]
7use crate::{PathIntersection, PathPoint};
8
9impl Path {
10    /// Calls @func for every operation of the path.
11    ///
12    /// Note that this may only approximate @self, because paths can contain
13    /// optimizations for various specialized contours, and depending on the
14    /// @flags, the path may be decomposed into simpler curves than the ones
15    /// that it contained originally.
16    ///
17    /// This function serves two purposes:
18    ///
19    /// - When the @flags allow everything, it provides access to the raw,
20    ///   unmodified data of the path.
21    /// - When the @flags disallow certain operations, it provides
22    ///   an approximation of the path using just the allowed operations.
23    /// ## `flags`
24    /// flags to pass to the foreach function
25    /// ## `func`
26    /// the function to call for operations
27    ///
28    /// # Returns
29    ///
30    /// false if @func returned false, true otherwise.
31    #[doc(alias = "gsk_path_foreach")]
32    pub fn foreach<P: FnMut(&PathOperation, &graphene::Point, usize, f32) -> glib::ControlFlow>(
33        &self,
34        flags: PathForeachFlags,
35        func: P,
36    ) -> glib::ControlFlow {
37        let mut func_data: P = func;
38        unsafe extern "C" fn func_func<
39            P: FnMut(&PathOperation, &graphene::Point, usize, f32) -> glib::ControlFlow,
40        >(
41            op: ffi::GskPathOperation,
42            pts: *const graphene::ffi::graphene_point_t,
43            n_pts: libc::size_t,
44            weight: libc::c_float,
45            user_data: glib::ffi::gpointer,
46        ) -> glib::ffi::gboolean {
47            unsafe {
48                let op = from_glib(op);
49                let pts = from_glib_borrow(pts);
50                let callback = user_data as *mut P;
51                (*callback)(&op, &pts, n_pts, weight).into_glib()
52            }
53        }
54        let func = Some(func_func::<P> as _);
55        let super_callback0: &mut P = &mut func_data;
56        unsafe {
57            from_glib(ffi::gsk_path_foreach(
58                self.to_glib_none().0,
59                flags.into_glib(),
60                func,
61                super_callback0 as *mut _ as *mut _,
62            ))
63        }
64    }
65
66    /// Finds intersections between two paths.
67    ///
68    /// This function finds intersections between @self and @path2,
69    /// and calls @func for each of them, in increasing order for @self.
70    ///
71    /// If @path2 is not provided or equal to @self, the function finds
72    /// non-trivial self-intersections of @self.
73    ///
74    /// When segments of the paths coincide, the callback is called once
75    /// for the start of the segment, with @GSK_PATH_INTERSECTION_START, and
76    /// once for the end of the segment, with @GSK_PATH_INTERSECTION_END.
77    /// Note that other intersections may occur between the start and end
78    /// of such a segment.
79    ///
80    /// If @func returns `FALSE`, the iteration is stopped.
81    /// ## `path2`
82    /// the second path
83    /// ## `func`
84    /// the function to call for intersections
85    ///
86    /// # Returns
87    ///
88    /// `FALSE` if @func returned FALSE`, `TRUE` otherwise.
89    #[cfg(feature = "v4_20")]
90    #[cfg_attr(docsrs, doc(cfg(feature = "v4_20")))]
91    #[doc(alias = "gsk_path_foreach_intersection")]
92    pub fn foreach_intersection<
93        P: FnMut(&Path, &PathPoint, &Path, &PathPoint, PathIntersection) -> bool,
94    >(
95        &self,
96        path2: Option<&Path>,
97        func: P,
98    ) -> bool {
99        let mut func_data: P = func;
100        unsafe extern "C" fn func_func<
101            P: FnMut(&Path, &PathPoint, &Path, &PathPoint, PathIntersection) -> bool,
102        >(
103            path1: *mut ffi::GskPath,
104            point1: *const ffi::GskPathPoint,
105            path2: *mut ffi::GskPath,
106            point2: *const ffi::GskPathPoint,
107            kind: ffi::GskPathIntersection,
108            user_data: glib::ffi::gpointer,
109        ) -> glib::ffi::gboolean {
110            unsafe {
111                let path1 = from_glib_borrow(path1);
112                let point1 = from_glib_borrow(point1);
113                let path2 = from_glib_borrow(path2);
114                let point2 = from_glib_borrow(point2);
115                let kind = from_glib(kind);
116                let callback = user_data as *mut P;
117                (*callback)(&path1, &point1, &path2, &point2, kind).into_glib()
118            }
119        }
120        let func = Some(func_func::<P> as _);
121        let super_callback0: &mut P = &mut func_data;
122        unsafe {
123            from_glib(ffi::gsk_path_foreach_intersection(
124                self.to_glib_none().0,
125                path2.to_glib_none().0,
126                func,
127                super_callback0 as *mut _ as *mut _,
128            ))
129        }
130    }
131}
132
133impl std::str::FromStr for Path {
134    type Err = glib::BoolError;
135    fn from_str(s: &str) -> Result<Self, Self::Err> {
136        assert_initialized_main_thread!();
137        Path::parse(s)
138    }
139}