Skip to content

Commit a3a0040

Browse files
committed
Document path, and Context::close_to due to use in example
1 parent a0b248d commit a3a0040

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

cairo/src/context.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,70 @@ impl Context {
10641064
unsafe { ffi::cairo_new_sub_path(self.0.as_ptr()) }
10651065
}
10661066

1067+
/// Adds a line segment from the current point to the beginning of the current sub-path (the
1068+
/// most recent point passed to [`Context::move_to`]) to the path, and closes this sub-path.
1069+
/// After this call, the current point will be at the **joined endpoint of the sub-path**.
1070+
///
1071+
/// The behavior of [`Context::close_path`] is distinct from simply calling
1072+
/// [`Context::line_to`] with the equivalent coordinate in the case of stroking. When a closed
1073+
/// sub-path is stroked, there are no caps on the ends of the sub-path. Instead, there is a
1074+
/// line join connecting the final and initial segments of the sub-path.
1075+
///
1076+
/// If there is no current point before the call to [`Context::close_path`], this function will
1077+
/// have no effect.
1078+
///
1079+
/// **Note**: Calls to [`Context::close_path`] now (as of `cairo 1.2.4`) place an explicit
1080+
/// [`MoveTo`] element into the path immediately after the [`ClosePath`] element. This can
1081+
/// simplify path processing in some cases. See below for an example of this case.
1082+
///
1083+
/// # Examples
1084+
///
1085+
/// ```
1086+
/// # fn main() -> Result<(), cairo::Error> {
1087+
/// use cairo::{Context, Format, ImageSurface};
1088+
///
1089+
/// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
1090+
/// let ctx = Context::new(&surface).unwrap();
1091+
///
1092+
/// // paint the background black
1093+
/// ctx.paint()?;
1094+
///
1095+
/// // draw a 5-pointed star with a white fill, in similar manner to how a human would
1096+
/// let angle = std::f64::consts::TAU / 2.5;
1097+
/// ctx.set_source_rgb(1.0, 1.0, 1.0);
1098+
/// for i in 0..5 {
1099+
/// let x = 50.0 + 40.0 * (i as f64 * angle).cos();
1100+
/// let y = 50.0 + 40.0 * (i as f64 * angle).sin();
1101+
/// if i == 0 {
1102+
/// ctx.move_to(x, y);
1103+
/// } else {
1104+
/// ctx.line_to(x, y);
1105+
/// }
1106+
/// }
1107+
/// ctx.close_path();
1108+
///
1109+
/// // print the path details before filling (will clear the context path)
1110+
/// let path = ctx.copy_path()?;
1111+
/// for element in path.iter() {
1112+
/// println!("{:?}", element);
1113+
/// }
1114+
///
1115+
/// ctx.fill()?;
1116+
///
1117+
/// // output:
1118+
/// // MoveTo((90.0, 50.0))
1119+
/// // LineTo((17.640625, 73.51171875))
1120+
/// // LineTo((62.359375, 11.95703125))
1121+
/// // LineTo((62.359375, 88.04296875))
1122+
/// // LineTo((17.640625, 26.48828125))
1123+
/// // ClosePath
1124+
/// // MoveTo((90.0, 50.0))
1125+
/// # Ok(())
1126+
/// # }
1127+
/// ```
1128+
///
1129+
/// [`MoveTo`]: crate::PathSegment::MoveTo
1130+
/// [`ClosePath`]: crate::PathSegment::ClosePath
10671131
#[doc(alias = "cairo_close_path")]
10681132
pub fn close_path(&self) {
10691133
unsafe { ffi::cairo_close_path(self.0.as_ptr()) }

cairo/src/paths.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,65 @@ use std::{iter::FusedIterator, ptr};
44

55
use 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")]
968
pub 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)]
55118
pub 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.
62139
pub struct PathSegments<'a> {
63140
data: &'a [ffi::cairo_path_data],
64141
i: usize,

0 commit comments

Comments
 (0)