@@ -4,6 +4,65 @@ use std::{iter::FusedIterator, ptr};
44
55use crate :: { ffi, PathDataType } ;
66
7+ /// A path of segments, representing a series of moveto, lineto, curveto, and closepath operations
8+ /// that define a path to draw.
9+ ///
10+ /// A [`Path`] can be thought of as a list of commands that define how to draw a particular shape,
11+ /// akin to drawing a shape with pen and paper. Each command is represented by a [`PathSegment`],
12+ /// which define a specific operation to perform with the pen.
13+ ///
14+ /// Paths are created by calling [`Context::copy_path`] and [`Context::copy_path_flat`], which
15+ /// returns a copy of the current path that the context is using. This allows you to inspect the
16+ /// path that has been drawn so far.
17+ ///
18+ /// # Examples
19+ ///
20+ /// ```
21+ /// # fn main() -> Result<(), cairo::Error> {
22+ /// use cairo::{Context, Format, ImageSurface};
23+ ///
24+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
25+ /// let ctx = Context::new(&surface).unwrap();
26+ ///
27+ /// // paint the background black
28+ /// ctx.paint()?;
29+ ///
30+ /// // draw a 5-pointed star with a white fill, in similar manner to how a human would
31+ /// let angle = std::f64::consts::TAU / 2.5;
32+ /// ctx.set_source_rgb(1.0, 1.0, 1.0);
33+ /// for i in 0..5 {
34+ /// let x = 50.0 + 40.0 * (i as f64 * angle).cos();
35+ /// let y = 50.0 + 40.0 * (i as f64 * angle).sin();
36+ /// if i == 0 {
37+ /// ctx.move_to(x, y);
38+ /// } else {
39+ /// ctx.line_to(x, y);
40+ /// }
41+ /// }
42+ /// ctx.close_path();
43+ ///
44+ /// // print the path details before filling (will clear the context path)
45+ /// let path = ctx.copy_path()?;
46+ /// for element in path.iter() {
47+ /// println!("{:?}", element);
48+ /// }
49+ ///
50+ /// ctx.fill()?;
51+ ///
52+ /// // output:
53+ /// // MoveTo((90.0, 50.0))
54+ /// // LineTo((17.640625, 73.51171875))
55+ /// // LineTo((62.359375, 11.95703125))
56+ /// // LineTo((62.359375, 88.04296875))
57+ /// // LineTo((17.640625, 26.48828125))
58+ /// // ClosePath
59+ /// // MoveTo((90.0, 50.0))
60+ /// # Ok(())
61+ /// # }
62+ /// ```
63+ ///
64+ /// [`Context::copy_path`]: crate::Context::copy_path
65+ /// [`Context::copy_path_flat`]: crate::Context::copy_path_flat
766#[ derive( Debug ) ]
867#[ doc( alias = "cairo_path_t" ) ]
968pub struct Path ( ptr:: NonNull < ffi:: cairo_path_t > ) ;
@@ -20,6 +79,7 @@ impl Path {
2079 Path ( ptr:: NonNull :: new_unchecked ( pointer) )
2180 }
2281
82+ /// Returns an iterator over the segments of the path.
2383 pub fn iter ( & self ) -> PathSegments {
2484 use std:: slice;
2585
@@ -51,14 +111,31 @@ impl Drop for Path {
51111 }
52112}
53113
114+ /// A segment of a path, representing a single moveto, lineto, curveto, or closepath operation.
115+ ///
116+ /// See the documentation for [`Path`] for more information.
54117#[ derive( Debug , Clone , Copy , PartialEq ) ]
55118pub enum PathSegment {
119+ /// Lift up the "pen" and move it to the given point, starting a new subpath.
56120 MoveTo ( ( f64 , f64 ) ) ,
121+
122+ /// Draw a straight line from the current point to the given point.
57123 LineTo ( ( f64 , f64 ) ) ,
124+
125+ /// Draw a cubic Bezier curve from the current point to the given point, using the two control
126+ /// points to define the curve.
127+ ///
128+ /// The first and second points are the control points, and the third point is the end point.
58129 CurveTo ( ( f64 , f64 ) , ( f64 , f64 ) , ( f64 , f64 ) ) ,
130+
131+ /// Draw a straight line from the current point to the starting point of the subpath, closing
132+ /// it.
59133 ClosePath ,
60134}
61135
136+ /// An iterator over the segments of a [`Path`].
137+ ///
138+ /// This struct is created by the [`Path::iter`] method.
62139pub struct PathSegments < ' a > {
63140 data : & ' a [ ffi:: cairo_path_data ] ,
64141 i : usize ,
0 commit comments