PATCH cairo-www: add outside-clipping cookbook example
Lawrence D'Oliveiro <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Organization | Geek Central |
| Message-ID | <[email protected]> |
Thought it might be useful to demonstrate this technique. -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo
0001-add-outside-clipping-cookbook-example.patch
(text/x-patch, 9.4 KB)
From 6ffa8c1dd0979bc75b93af20534822a370283d88 Mon Sep 17 00:00:00 2001 From: Lawrence D'Oliveiro <[email protected]> Date: Sat, 16 Jan 2016 01:33:13 +0000 Subject: [PATCH] add outside-clipping cookbook example --- src/cookbook.mdwn | 1 + src/cookbook/outside_clipping.mdwn | 89 +++++++++++++++++++++++++ src/cookbook/outside_clipping/outside_clip.png | Bin 0 -> 3988 bytes 3 files changed, 90 insertions(+) create mode 100644 src/cookbook/outside_clipping.mdwn create mode 100644 src/cookbook/outside_clipping/outside_clip.png 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 0000000000000000000000000000000000000000..e9d406caf79903eb68aeffcac3af39747e60a2d2 GIT binary patch literal 3988 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 aY}cb~fjGd&q?0zANl)8I3#aku)qep>n`w>! literal 0 HcmV?d00001 -- 2.6.0