@@ -59,6 +59,27 @@ impl fmt::Display for RectangleList {
5959 }
6060}
6161
62+ /// A drawing context, used to draw on [`Surface`]s.
63+ ///
64+ /// [`Context`] is the main entry point for all drawing operations. To acquire a [`Context`], you
65+ /// can create any kind of [`Surface`] (such as [`ImageSurface`] or [`PdfSurface`]), and call
66+ /// [`Context::new`] with the target surface:
67+ ///
68+ /// ```
69+ /// use cairo::{Context, Format, ImageSurface};
70+ ///
71+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
72+ /// let ctx = Context::new(&surface).unwrap();
73+ ///
74+ /// // paint the background black
75+ /// ctx.set_source_rgb(0.0, 0.0, 0.0);
76+ /// ctx.paint();
77+ ///
78+ /// // etc.
79+ /// ```
80+ ///
81+ /// [`ImageSurface`]: crate::ImageSurface
82+ /// [`PdfSurface`]: crate::PdfSurface
6283#[ derive( Debug ) ]
6384#[ repr( transparent) ]
6485pub struct Context ( ptr:: NonNull < cairo_t > ) ;
@@ -163,74 +184,270 @@ impl Context {
163184 self . 0 . as_ptr ( )
164185 }
165186
187+ /// Checks whether an error has previously occurred for this context.
188+ ///
189+ /// Refer to [`Error`] for an exhaustive list of error codes.
166190 #[ doc( alias = "cairo_status" ) ]
167191 #[ inline]
168192 pub fn status ( & self ) -> Result < ( ) , Error > {
169193 let status = unsafe { ffi:: cairo_status ( self . 0 . as_ptr ( ) ) } ;
170194 status_to_result ( status)
171195 }
172196
197+ /// Creates a new [`Context`] with default graphics state parameters, for drawing to a target
198+ /// [`Surface`].
173199 pub fn new ( target : impl AsRef < Surface > ) -> Result < Context , Error > {
174200 let ctx = unsafe { Self :: from_raw_full ( ffi:: cairo_create ( target. as_ref ( ) . to_raw_none ( ) ) ) } ;
175201 ctx. status ( ) . map ( |_| ctx)
176202 }
177203
204+ /// Makes a copy of the current state of the [`Context`], saving it in an internal stack of
205+ /// saved states for the [`Context`]. When [`Context::restore`] is called, this context will be
206+ /// restored to the saved state.
207+ ///
208+ /// Multiple calls to [`Context::save`] and [`Context::restore`] can be nested; each call to
209+ /// [`Context::restore`] restores the state from the matching paired [`Context::save`].
210+ ///
211+ /// # Examples
212+ ///
213+ /// ```
214+ /// # fn main() -> Result<(), cairo::Error> {
215+ /// use cairo::{Context, Format, ImageSurface};
216+ ///
217+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
218+ /// let ctx = Context::new(&surface).unwrap();
219+ ///
220+ /// // set source to red
221+ /// ctx.set_source_rgb(1.0, 0.0, 0.0);
222+ ///
223+ /// // this block scope is not necessary, but can help with visualizing what happens
224+ /// {
225+ /// // save current state
226+ /// ctx.save()?;
227+ ///
228+ /// // set source to white
229+ /// ctx.set_source_rgb(1.0, 1.0, 1.0);
230+ ///
231+ /// // shift origin in canvas space, to (50, 50)
232+ /// ctx.translate(50.0, 50.0);
233+ ///
234+ /// // draw a white square with its upper-left corner at (0, 0) in canvas space
235+ /// // (i.e. at (50, 50) in device space)
236+ /// ctx.rectangle(0.0, 0.0, 20.0, 20.0);
237+ /// ctx.fill()?;
238+ ///
239+ /// // restore state, origin back at (0, 0) in canvas space
240+ /// ctx.restore()?;
241+ /// }
242+ ///
243+ /// // draw a red square at (0, 0) in canvas and device space
244+ /// ctx.rectangle(0.0, 0.0, 20.0, 20.0);
245+ /// ctx.fill()?;
246+ /// # Ok(())
247+ /// # }
248+ /// ```
178249 #[ doc( alias = "cairo_save" ) ]
179250 pub fn save ( & self ) -> Result < ( ) , Error > {
180251 unsafe { ffi:: cairo_save ( self . 0 . as_ptr ( ) ) }
181252 self . status ( )
182253 }
183254
255+ /// Restores the [`Context`] to the state saved by a preceding call to [`Context::save`],
256+ /// removing that state from the stack of saved states.
257+ ///
258+ /// See [`Context::save`] for example usage.
184259 #[ doc( alias = "cairo_restore" ) ]
185260 pub fn restore ( & self ) -> Result < ( ) , Error > {
186261 unsafe { ffi:: cairo_restore ( self . 0 . as_ptr ( ) ) }
187262 self . status ( )
188263 }
189264
265+ /// Returns the target [`Surface`] for this [`Context`].
190266 #[ doc( alias = "get_target" ) ]
191267 #[ doc( alias = "cairo_get_target" ) ]
192268 pub fn target ( & self ) -> Surface {
193269 unsafe { Surface :: from_raw_none ( ffi:: cairo_get_target ( self . 0 . as_ptr ( ) ) ) }
194270 }
195271
272+ /// Temporarily redirects drawing to an intermediate surface, known as a group, with a default
273+ /// content type of [`Content::ColorAlpha`]. The redirection lasts until the group is completed
274+ /// by a call to [`Context::pop_group`] / [`Context::pop_group_to_source`].
275+ ///
276+ /// This can be convenient for performing intermediate compositing. A common use of a group is
277+ /// to render objects as opaque within the group (so that they occlude each other), and then
278+ /// blend the result with translucence onto the destination.
279+ ///
280+ /// Groups can be nested arbitrarily deep by making balanced calls to [`Context::push_group`] /
281+ /// [`Context::pop_group`]. Each call pushes / pops the new target group onto / from a stack.
282+ ///
283+ /// This function calls [`Context::save`] so that any changes to the graphics state will not be
284+ /// visible outside the group. ([`Context::pop_group`] functions call [`Context::restore`])
285+ ///
286+ /// # Examples
287+ ///
288+ /// TODO: make a nice example here
196289 #[ doc( alias = "cairo_push_group" ) ]
197290 pub fn push_group ( & self ) {
198291 unsafe { ffi:: cairo_push_group ( self . 0 . as_ptr ( ) ) }
199292 }
200293
294+ /// Temporarily redirects drawing to an intermediate surface, known as a group, with the given
295+ /// content type. The redirection lasts until the group is completed by a call to
296+ /// [`Context::pop_group`] / [`Context::pop_group_to_source`].
297+ ///
298+ /// See [`Context::push_group`] for more details.
201299 #[ doc( alias = "cairo_push_group_with_content" ) ]
202300 pub fn push_group_with_content ( & self , content : Content ) {
203301 unsafe { ffi:: cairo_push_group_with_content ( self . 0 . as_ptr ( ) , content. into ( ) ) }
204302 }
205303
304+ /// Terminates the redirection begun by a call to [`Context::push_group`] or
305+ /// [`Context::push_group_with_content`] and returns a new [`Pattern`] containing the results
306+ /// of all drawing operations performed on the group.
307+ ///
308+ /// This function calls [`Context::restore`] so that any changes to the graphics state will not
309+ /// be visible outside the group.
310+ ///
311+ /// # Examples
312+ ///
313+ /// TODO: make a nice example here
206314 #[ doc( alias = "cairo_pop_group" ) ]
207315 pub fn pop_group ( & self ) -> Result < Pattern , Error > {
208316 let pattern = unsafe { Pattern :: from_raw_full ( ffi:: cairo_pop_group ( self . 0 . as_ptr ( ) ) ) } ;
209317 self . status ( ) . map ( |_| pattern)
210318 }
211319
320+ /// Terminates the redirection begun by a call to [`Context::push_group`] or
321+ /// [`Context::push_group_with_content`]. The results of the drawing operations are then used
322+ /// as the source pattern for this [`Context`].
323+ ///
324+ /// This function calls [`Context::restore`] so that any changes to the graphics state will not
325+ /// be visible outside the group.
326+ ///
327+ /// # Examples
328+ ///
329+ /// TODO: make a nice example here
212330 #[ doc( alias = "cairo_pop_group_to_source" ) ]
213331 pub fn pop_group_to_source ( & self ) -> Result < ( ) , Error > {
214332 unsafe { ffi:: cairo_pop_group_to_source ( self . 0 . as_ptr ( ) ) } ;
215333 self . status ( )
216334 }
217335
336+ /// Gets the current destination surface for the [`Context`].
337+ ///
338+ /// This is either the original target surface as passed to [`Context::new`], or the target
339+ /// surface for the current group as started by the most recent call to [`Context::push_group`]
340+ /// / [`Context::push_group_with_content`].
218341 #[ doc( alias = "get_group_target" ) ]
219342 #[ doc( alias = "cairo_get_group_target" ) ]
220343 pub fn group_target ( & self ) -> Surface {
221344 unsafe { Surface :: from_raw_none ( ffi:: cairo_get_group_target ( self . 0 . as_ptr ( ) ) ) }
222345 }
223346
347+ /// Sets this [`Context`]'s source pattern to an opaque color. This opaque color will be used
348+ /// for any subsequent drawing operation.
349+ ///
350+ /// The color components are floating point numbers in the range `0.0..=1.0`. If the given
351+ /// values are outside that range, they will be clamped.
352+ ///
353+ /// The default source pattern is an opaque black `(0.0, 0.0, 0.0)`.
354+ ///
355+ /// # Examples
356+ ///
357+ /// ```
358+ /// # fn main() -> Result<(), cairo::Error> {
359+ /// use cairo::{Context, Format, ImageSurface};
360+ ///
361+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
362+ /// let ctx = Context::new(&surface).unwrap();
363+ ///
364+ /// // paint the background black
365+ /// ctx.paint()?;
366+ ///
367+ /// // draw a red circle centered at (50, 50)
368+ /// ctx.set_source_rgb(1.0, 0.0, 0.0);
369+ /// ctx.arc(50.0, 50.0, 20.0, 0.0, std::f64::consts::TAU);
370+ /// ctx.fill()?;
371+ /// # Ok(())
372+ /// # }
373+ /// ```
224374 #[ doc( alias = "cairo_set_source_rgb" ) ]
225375 pub fn set_source_rgb ( & self , red : f64 , green : f64 , blue : f64 ) {
226376 unsafe { ffi:: cairo_set_source_rgb ( self . 0 . as_ptr ( ) , red, green, blue) }
227377 }
228378
379+ /// Sets this [`Context`]'s source pattern to a translucent color. This translucent color will
380+ /// be used for any subsequent drawing operation.
381+ ///
382+ /// The color and alpha components are floating point numbers in the range `0.0..=1.0`. If the
383+ /// given values are outside that range, they will be clamped.
384+ ///
385+ /// The default source pattern is an opaque black `(0.0, 0.0, 0.0, 1.0)`.
386+ ///
387+ /// # Examples
388+ ///
389+ /// ```
390+ /// # fn main() -> Result<(), cairo::Error> {
391+ /// use cairo::{Context, Format, ImageSurface};
392+ ///
393+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
394+ /// let ctx = Context::new(&surface).unwrap();
395+ ///
396+ /// // paint the background black
397+ /// ctx.paint()?;
398+ ///
399+ /// // draw a red circle centered at (50, 50)
400+ /// ctx.set_source_rgb(1.0, 0.0, 0.0);
401+ /// ctx.arc(50.0, 50.0, 20.0, 0.0, std::f64::consts::TAU);
402+ /// ctx.fill()?;
403+ ///
404+ /// // draw a translucent blue square on top of the circle
405+ /// ctx.set_source_rgba(0.0, 0.0, 1.0, 0.5);
406+ /// ctx.rectangle(30.0, 30.0, 40.0, 40.0);
407+ /// ctx.fill()?;
408+ /// # Ok(())
409+ /// # }
410+ /// ```
229411 #[ doc( alias = "cairo_set_source_rgba" ) ]
230412 pub fn set_source_rgba ( & self , red : f64 , green : f64 , blue : f64 , alpha : f64 ) {
231413 unsafe { ffi:: cairo_set_source_rgba ( self . 0 . as_ptr ( ) , red, green, blue, alpha) }
232414 }
233415
416+ /// Sets this [`Context`]'s source pattern. This source pattern will be used for any subsequent
417+ /// drawing operation.
418+ ///
419+ /// **Note**: The pattern's transformation matrix will be locked to the user space when
420+ /// [`Context::set_source`] is called. Any subsequent modification of the current transformation
421+ /// matrix **will not** affect the source pattern.
422+ ///
423+ /// The default source pattern is an opaque black `(0.0, 0.0, 0.0, 1.0)`.
424+ ///
425+ /// # Examples
426+ ///
427+ /// ```
428+ /// # fn main() -> Result<(), cairo::Error> {
429+ /// use cairo::{Context, Format, ImageSurface, RadialGradient};
430+ ///
431+ /// let surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap();
432+ /// let ctx = Context::new(&surface).unwrap();
433+ ///
434+ /// // creates a radial gradient from red to blue
435+ ///
436+ /// // gradient will begin at (50, 50) with radius 0
437+ /// // ends at (50, 50) with radius 50
438+ /// let pattern = RadialGradient::new(50.0, 50.0, 0.0, 50.0, 50.0, 50.0);
439+ ///
440+ /// // first color stop: at offset=0, draw with red=(1, 0, 0)
441+ /// pattern.add_color_stop_rgb(0.0, 1.0, 0.0, 0.0);
442+ ///
443+ /// // second color stop: at offset=1, draw with blue=(0, 0, 1)
444+ /// pattern.add_color_stop_rgb(1.0, 0.0, 0.0, 1.0);
445+ ///
446+ /// // paints the canvas with the gradient
447+ /// ctx.set_source(&pattern)?;
448+ /// ctx.paint()?;
449+ /// # Ok(())
450+ /// # }
234451 #[ doc( alias = "cairo_set_source" ) ]
235452 pub fn set_source ( & self , source : impl AsRef < Pattern > ) -> Result < ( ) , Error > {
236453 let source = source. as_ref ( ) ;
@@ -509,6 +726,7 @@ impl Context {
509726 self . status ( )
510727 }
511728
729+ /// Paints the current source color everywhere within the current clip region.
512730 #[ doc( alias = "cairo_paint" ) ]
513731 pub fn paint ( & self ) -> Result < ( ) , Error > {
514732 unsafe { ffi:: cairo_paint ( self . 0 . as_ptr ( ) ) } ;
0 commit comments