[cairo-commit] [cairo-www] src/cookbook src/cookbook.mdwn
Bryce Harrington
bryce at freedesktop.org
Fri Jan 15 19:00:34 PST 2016
src/cookbook.mdwn | 1
src/cookbook/outside_clipping.mdwn | 89 +++++++++++++++++++++++++
src/cookbook/outside_clipping/outside_clip.png |binary
3 files changed, 90 insertions(+)
New commits:
commit f4534a34ca5665ef991af253bc62089835708aad
Author: Lawrence D'Oliveiro <ldo at geek-central.gen.nz>
Date: Sat Jan 16 14:36:06 2016 +1300
PATCH cairo-www: add outside-clipping cookbook example
Thought it might be useful to demonstrate this technique.
>From 6ffa8c1dd0979bc75b93af20534822a370283d88 Mon Sep 17 00:00:00 2001
From: Lawrence D'Oliveiro <ldo at geek-central.gen.nz>
Date: Sat, 16 Jan 2016 01:33:13 +0000
Subject: [PATCH] add outside-clipping cookbook example
diff --git a/src/cookbook.mdwn b/src/cookbook.mdwn
index 9e5471b..f9cb78e 100644
--- a/src/cookbook.mdwn
+++ b/src/cookbook.mdwn
@@ -6,6 +6,7 @@
* [[Rounded_rectangles|roundedrectangles]]
* [[Ellipses With Uniform Stroke Width|ellipses]]
* [[A_description_of_compositing_operators_in_Cairo|operators]]
+ * [[Clipping Outside A Region|outside_clipping]]
+ Matrix Transformations
* [[Basic_matrix_transformation_reminder|matrix_transform]]
diff --git a/src/cookbook/outside_clipping.mdwn b/src/cookbook/outside_clipping.mdwn
new file mode 100644
index 0000000..6220b18
--- /dev/null
+++ b/src/cookbook/outside_clipping.mdwn
@@ -0,0 +1,89 @@
+[[!meta title="Clipping Outside A Region"]]
+
+Cairo lets you clip drawing to arbitrary regions defined by paths. The basic technique
+is:
+
+ * construct your path
+ * use [`cairo_clip()`](http://cairographics.org/manual/cairo-cairo-t.html#cairo-clip)
+ to intersect the clip region with the interior of your path.
+
+Note that the intersection is with the *interior* of your path—that is, the area
+that would be filled if you did a `cairo_fill()` operation on your path. But supposing
+you have a path, and you want drawing to be clipped to the *exterior* of that path?
+
+The way to reverse the definitions of “interior” and “exterior” is simple: simply add
+another subpath to your path, surrounding the entire drawing area. If you use
+`CAIRO_FILL_RULE_WINDING` for your fill rule (the default), then make sure the enclosing
+subpath is defined in the opposite direction to the inner one. Now the interior of
+the path becomes the area between the subpaths, rather than inside the inner subpath.
+
+Alternatively, you can use `CAIRO_FILL_RULE_EVEN_ODD` for your fill rule, then the
+subpath directions don’t matter.
+
+ const int img_size = 300;
+ cairo_surface_t * const pix = cairo_image_surface_create
+ (
+ /*format =*/ CAIRO_FORMAT_RGB24,
+ /*width =*/ img_size,
+ /*height =*/ img_size
+ );
+ cairo_t * const cr = cairo_create(pix);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ /* use overwriting operator to make clear that overwriting is blocked by clipping */
+ cairo_set_source_rgb(cr, 1, 1, 1); /* background */
+ cairo_paint(cr);
+ for (bool outside = false;;)
+ {
+ /* Do two drawing passes, once clipped inside the region, then clipped outside. */
+ /* Because of the clipping, the second pass does not overwrite the first. */
+ cairo_reset_clip(cr);
+ cairo_new_path(cr);
+ cairo_arc /* example inner region--note subpath is defined clockwise */
+ (
+ /*cr =*/ cr,
+ /*xc =*/ img_size / 2.0,
+ /*yc =*/ img_size / 2.0,
+ /*radius =*/ img_size / 4.0,
+ /*angle1 =*/ 0,
+ /*angle2 =*/ 2 * M_PI
+ );
+ if (outside)
+ {
+ /* add outer subpath in anticlockwise direction */
+ cairo_new_sub_path(cr);
+ cairo_move_to(cr, img_size, 0);
+ cairo_line_to(cr, 0, 0);
+ cairo_line_to(cr, 0, img_size);
+ cairo_line_to(cr, img_size, img_size);
+ cairo_close_path(cr);
+ } /*if*/
+ cairo_clip(cr);
+ if (outside) /* use different colours to distinguish cases */
+ {
+ cairo_set_source_rgb(cr, 1.0, 0.91, 0.83);
+ }
+ else
+ {
+ cairo_set_source_rgb(cr, 0.1, 0.7, 0.67);
+ } /*if*/
+ cairo_rectangle
+ /* example shape that extends both inside and outside inner clipping region */
+ (
+ /*cr =*/ cr,
+ /*x =*/ 0,
+ /*y =*/ img_size / 4.0,
+ /*width =*/ img_size,
+ /*height =*/ img_size / 2.0
+ );
+ cairo_fill(cr);
+ if (outside)
+ break;
+ outside = true;
+ } /*for*/
+
+Sample output:
+
+[[!img "outside_clip.png" link="no"]]
+
+This technique also extends to more than one inner subpath, defining multiple discontiguous
+inner regions to be clipped out of the drawing area.
diff --git a/src/cookbook/outside_clipping/outside_clip.png b/src/cookbook/outside_clipping/outside_clip.png
new file mode 100644
index 0000000..e9d406c
Binary files /dev/null and b/src/cookbook/outside_clipping/outside_clip.png differ
More information about the cairo-commit
mailing list