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::{ffi, Path, PathForeachFlags, PathOperation};
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            let op = from_glib(op);
48            let pts = from_glib_borrow(pts);
49            let callback = user_data as *mut P;
50            (*callback)(&op, &pts, n_pts, weight).into_glib()
51        }
52        let func = Some(func_func::<P> as _);
53        let super_callback0: &mut P = &mut func_data;
54        unsafe {
55            from_glib(ffi::gsk_path_foreach(
56                self.to_glib_none().0,
57                flags.into_glib(),
58                func,
59                super_callback0 as *mut _ as *mut _,
60            ))
61        }
62    }
63
64    /// Finds intersections between two paths.
65    ///
66    /// This function finds intersections between @self and @path2,
67    /// and calls @func for each of them, in increasing order for @self.
68    ///
69    /// If @path2 is not provided or equal to @self, the function finds
70    /// non-trivial self-intersections of @self.
71    ///
72    /// When segments of the paths coincide, the callback is called once
73    /// for the start of the segment, with @GSK_PATH_INTERSECTION_START, and
74    /// once for the end of the segment, with @GSK_PATH_INTERSECTION_END.
75    /// Note that other intersections may occur between the start and end
76    /// of such a segment.
77    ///
78    /// If @func returns `FALSE`, the iteration is stopped.
79    /// ## `path2`
80    /// the second path
81    /// ## `func`
82    /// the function to call for intersections
83    ///
84    /// # Returns
85    ///
86    /// `FALSE` if @func returned FALSE`, `TRUE` otherwise.
87    #[cfg(feature = "v4_20")]
88    #[cfg_attr(docsrs, doc(cfg(feature = "v4_20")))]
89    #[doc(alias = "gsk_path_foreach_intersection")]
90    pub fn foreach_intersection<
91        P: FnMut(&Path, &PathPoint, &Path, &PathPoint, PathIntersection) -> bool,
92    >(
93        &self,
94        path2: Option<&Path>,
95        func: P,
96    ) -> bool {
97        let mut func_data: P = func;
98        unsafe extern "C" fn func_func<
99            P: FnMut(&Path, &PathPoint, &Path, &PathPoint, PathIntersection) -> bool,
100        >(
101            path1: *mut ffi::GskPath,
102            point1: *const ffi::GskPathPoint,
103            path2: *mut ffi::GskPath,
104            point2: *const ffi::GskPathPoint,
105            kind: ffi::GskPathIntersection,
106            user_data: glib::ffi::gpointer,
107        ) -> glib::ffi::gboolean {
108            let path1 = from_glib_borrow(path1);
109            let point1 = from_glib_borrow(point1);
110            let path2 = from_glib_borrow(path2);
111            let point2 = from_glib_borrow(point2);
112            let kind = from_glib(kind);
113            let callback = user_data as *mut P;
114            (*callback)(&path1, &point1, &path2, &point2, kind).into_glib()
115        }
116        let func = Some(func_func::<P> as _);
117        let super_callback0: &mut P = &mut func_data;
118        unsafe {
119            from_glib(ffi::gsk_path_foreach_intersection(
120                self.to_glib_none().0,
121                path2.to_glib_none().0,
122                func,
123                super_callback0 as *mut _ as *mut _,
124            ))
125        }
126    }
127}
128
129impl std::str::FromStr for Path {
130    type Err = glib::BoolError;
131    fn from_str(s: &str) -> Result<Self, Self::Err> {
132        assert_initialized_main_thread!();
133        Path::parse(s)
134    }
135}