1use crate::{ffi, FillRule, PathPoint, Stroke};
6use glib::translate::*;
7
8glib::wrapper! {
9 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10 pub struct Path(Shared<ffi::GskPath>);
11
12 match fn {
13 ref => |ptr| ffi::gsk_path_ref(ptr),
14 unref => |ptr| ffi::gsk_path_unref(ptr),
15 type_ => || ffi::gsk_path_get_type(),
16 }
17}
18
19impl Path {
20 #[doc(alias = "gsk_path_get_bounds")]
21 #[doc(alias = "get_bounds")]
22 pub fn bounds(&self) -> Option<graphene::Rect> {
23 unsafe {
24 let mut bounds = graphene::Rect::uninitialized();
25 let ret = from_glib(ffi::gsk_path_get_bounds(
26 self.to_glib_none().0,
27 bounds.to_glib_none_mut().0,
28 ));
29 if ret {
30 Some(bounds)
31 } else {
32 None
33 }
34 }
35 }
36
37 #[doc(alias = "gsk_path_get_closest_point")]
38 #[doc(alias = "get_closest_point")]
39 pub fn closest_point(
40 &self,
41 point: &graphene::Point,
42 threshold: f32,
43 ) -> Option<(PathPoint, f32)> {
44 unsafe {
45 let mut result = PathPoint::uninitialized();
46 let mut distance = std::mem::MaybeUninit::uninit();
47 let ret = from_glib(ffi::gsk_path_get_closest_point(
48 self.to_glib_none().0,
49 point.to_glib_none().0,
50 threshold,
51 result.to_glib_none_mut().0,
52 distance.as_mut_ptr(),
53 ));
54 if ret {
55 Some((result, distance.assume_init()))
56 } else {
57 None
58 }
59 }
60 }
61
62 #[doc(alias = "gsk_path_get_end_point")]
63 #[doc(alias = "get_end_point")]
64 pub fn end_point(&self) -> Option<PathPoint> {
65 unsafe {
66 let mut result = PathPoint::uninitialized();
67 let ret = from_glib(ffi::gsk_path_get_end_point(
68 self.to_glib_none().0,
69 result.to_glib_none_mut().0,
70 ));
71 if ret {
72 Some(result)
73 } else {
74 None
75 }
76 }
77 }
78
79 #[doc(alias = "gsk_path_get_start_point")]
80 #[doc(alias = "get_start_point")]
81 pub fn start_point(&self) -> Option<PathPoint> {
82 unsafe {
83 let mut result = PathPoint::uninitialized();
84 let ret = from_glib(ffi::gsk_path_get_start_point(
85 self.to_glib_none().0,
86 result.to_glib_none_mut().0,
87 ));
88 if ret {
89 Some(result)
90 } else {
91 None
92 }
93 }
94 }
95
96 #[doc(alias = "gsk_path_get_stroke_bounds")]
97 #[doc(alias = "get_stroke_bounds")]
98 pub fn stroke_bounds(&self, stroke: &Stroke) -> Option<graphene::Rect> {
99 unsafe {
100 let mut bounds = graphene::Rect::uninitialized();
101 let ret = from_glib(ffi::gsk_path_get_stroke_bounds(
102 self.to_glib_none().0,
103 stroke.to_glib_none().0,
104 bounds.to_glib_none_mut().0,
105 ));
106 if ret {
107 Some(bounds)
108 } else {
109 None
110 }
111 }
112 }
113
114 #[doc(alias = "gsk_path_in_fill")]
115 pub fn in_fill(&self, point: &graphene::Point, fill_rule: FillRule) -> bool {
116 unsafe {
117 from_glib(ffi::gsk_path_in_fill(
118 self.to_glib_none().0,
119 point.to_glib_none().0,
120 fill_rule.into_glib(),
121 ))
122 }
123 }
124
125 #[doc(alias = "gsk_path_is_closed")]
126 pub fn is_closed(&self) -> bool {
127 unsafe { from_glib(ffi::gsk_path_is_closed(self.to_glib_none().0)) }
128 }
129
130 #[doc(alias = "gsk_path_is_empty")]
131 pub fn is_empty(&self) -> bool {
132 unsafe { from_glib(ffi::gsk_path_is_empty(self.to_glib_none().0)) }
133 }
134
135 #[doc(alias = "gsk_path_to_cairo")]
136 pub fn to_cairo(&self, cr: &cairo::Context) {
137 unsafe {
138 ffi::gsk_path_to_cairo(self.to_glib_none().0, mut_override(cr.to_glib_none().0));
139 }
140 }
141
142 #[doc(alias = "gsk_path_to_string")]
143 #[doc(alias = "to_string")]
144 pub fn to_str(&self) -> glib::GString {
145 unsafe { from_glib_full(ffi::gsk_path_to_string(self.to_glib_none().0)) }
146 }
147
148 #[doc(alias = "gsk_path_parse")]
149 pub fn parse(string: &str) -> Result<Path, glib::BoolError> {
150 assert_initialized_main_thread!();
151 unsafe {
152 Option::<_>::from_glib_full(ffi::gsk_path_parse(string.to_glib_none().0))
153 .ok_or_else(|| glib::bool_error!("Can't parse Path"))
154 }
155 }
156}
157
158impl std::fmt::Display for Path {
159 #[inline]
160 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
161 f.write_str(&self.to_str())
162 }
163}