From: Neil Roberts Date: Wed, 23 Jun 2010 12:40:43 +0000 (+0100) Subject: cogl-path: Allow changing the fill rule X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3a1456f34e17161b54ecd8ec55692e8a40c46456;p=profile%2Fivi%2Fclutter.git cogl-path: Allow changing the fill rule This adds two new API calls- cogl_path_set_fill_rule and cogl_path_get_fill_rule. This allows modifying the fill rule of the current path. In addition to the previous default fill rule of 'even-odd' it now supports the 'non-zero' rule. The fill rule is a property of the path (not the Cogl context) so creating a new path or preserving a path with cogl_path_get_handle affects the fill rule. --- diff --git a/clutter/cogl/cogl/cogl-path-private.h b/clutter/cogl/cogl/cogl-path-private.h index ecfb520..8adddda 100644 --- a/clutter/cogl/cogl/cogl-path-private.h +++ b/clutter/cogl/cogl/cogl-path-private.h @@ -25,6 +25,7 @@ #define __COGL_PATH_PRIVATE_H #include "cogl-handle.h" +#include "cogl-path.h" #define COGL_PATH(tex) ((CoglPath *)(tex)) @@ -69,6 +70,8 @@ struct _CoglPathData { unsigned int ref_count; + CoglPathFillRule fill_rule; + GArray *path_nodes; floatVec2 path_start; diff --git a/clutter/cogl/cogl/cogl-path.c b/clutter/cogl/cogl/cogl-path.c index f27218f..687fdaa 100644 --- a/clutter/cogl/cogl/cogl-path.c +++ b/clutter/cogl/cogl/cogl-path.c @@ -103,6 +103,35 @@ _cogl_path_modify (CoglPath *path) } } +void +cogl_path_set_fill_rule (CoglPathFillRule fill_rule) +{ + CoglPath *path; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + path = COGL_PATH (ctx->current_path); + + if (path->data->fill_rule != fill_rule) + { + _cogl_path_modify (path); + + path->data->fill_rule = fill_rule; + } +} + +CoglPathFillRule +cogl_path_get_fill_rule (void) +{ + CoglPath *path; + + _COGL_GET_CONTEXT (ctx, 0); + + path = COGL_PATH (ctx->current_path); + + return path->data->fill_rule; +} + static void _cogl_path_add_node (gboolean new_sub_path, float x, @@ -945,6 +974,7 @@ _cogl_path_new (void) data = path->data = g_slice_new (CoglPathData); data->ref_count = 1; + data->fill_rule = COGL_PATH_FILL_RULE_EVEN_ODD; data->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode)); data->last_path = 0; data->vbo = COGL_INVALID_HANDLE; @@ -1400,6 +1430,14 @@ _cogl_path_build_vbo (CoglPath *path) _cogl_path_tesselator_allocate_indices_array (&tess); tess.glu_tess = gluNewTess (); + + if (data->fill_rule == COGL_PATH_FILL_RULE_EVEN_ODD) + gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE, + GLU_TESS_WINDING_ODD); + else + gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE, + GLU_TESS_WINDING_NONZERO); + /* All vertices are on the xy-plane */ gluTessNormal (tess.glu_tess, 0.0, 0.0, 1.0); diff --git a/clutter/cogl/cogl/cogl-path.h b/clutter/cogl/cogl/cogl-path.h index a4c74c0..edeefe0 100644 --- a/clutter/cogl/cogl/cogl-path.h +++ b/clutter/cogl/cogl/cogl-path.h @@ -54,6 +54,48 @@ G_BEGIN_DECLS typedef struct _CoglPath CoglPath; /** + * CoglPathFillRule: + * @COGL_PATH_FILL_RULE_NON_ZERO: Each time the line crosses an edge of + * the path from left to right one is added to a counter and each time + * it crosses from right to left the counter is decremented. If the + * counter is non-zero then the point will be filled. See . + * @COGL_PATH_FILL_RULE_EVEN_ODD: If the line crosses an edge of the + * path an odd number of times then the point will filled, otherwise + * it won't. See . + * + * #CoglPathFillRule is used to determine how a path is filled. There + * are two options - 'non-zero' and 'even-odd'. To work out whether any + * point will be filled imagine drawing an infinetely long line in any + * direction from that point. The number of times and the direction + * that the edges of the path crosses this line determines whether the + * line is filled as described below. Any open sub paths are treated + * as if there was an extra line joining the first point and the last + * point. + * + * The default fill rule is %COGL_PATH_FILL_RULE_EVEN_ODD. The fill + * rule is attached to the current path so preserving a path with + * cogl_get_path() also preserves the fill rule. Calling + * cogl_path_new() resets the current fill rule to the default. + * + *
+ * Example of filling various paths using the non-zero rule + * + *
+ * + *
+ * Example of filling various paths using the even-odd rule + * + *
+ * + * Since: 1.4 + */ +typedef enum { + COGL_PATH_FILL_RULE_NON_ZERO, + COGL_PATH_FILL_RULE_EVEN_ODD +} CoglPathFillRule; + +/** * cogl_is_path: * @handle: A CoglHandle * @@ -66,27 +108,39 @@ gboolean cogl_is_path (CoglHandle handle); /** + * cogl_path_set_fill_rule: + * @fill_rule: The new fill rule. + * + * Sets the fill rule of the current path to @fill_rule. This will + * affect how the path is filled when cogl_path_fill() is later + * called. Note that the fill rule state is attached to the path so + * calling cogl_get_path() will preserve the fill rule and calling + * cogl_path_new() will reset the fill rule back to the default. + * + * Since: 1.4 + */ +void +cogl_path_set_fill_rule (CoglPathFillRule fill_rule); + +/** + * cogl_path_get_fill_rule: + * + * Return value: the fill rule that is used for the current path. + * + * Since: 1.4 + */ +CoglPathFillRule +cogl_path_get_fill_rule (void); + +/** * cogl_path_fill: * * Fills the interior of the constructed shape using the current * drawing color. The current path is then cleared. To use the path * again, call cogl_path_fill_preserve() instead. * - * The interior of the shape is determined using the 'even-odd' - * rule. Any open sub-paths are treated as if there is an extra line - * joining the last point and first point. You can work out whether - * any point in the stage will be filled if you imagine drawing an - * infinitely long line in any direction from that point and then - * counting the number times it crosses a line in the path. If the - * number is odd it will be filled, otherwise it will not. - * - * See for a demonstration of the fill - * rule. - * - *
- * Example of filling various paths - * - *
+ * The interior of the shape is determined using the fill rule of the + * path. See %CoglPathFillRule for details. **/ void cogl_path_fill (void); @@ -129,7 +183,9 @@ cogl_path_stroke_preserve (void); /** * cogl_path_new: * - * Clears the current path and starts a new one. + * Clears the current path and starts a new one. Creating a new path + * also resets the fill rule to the default which is + * %COGL_PATH_FILL_RULE_EVEN_ODD. * * Since: 1.0 */ diff --git a/doc/reference/cogl/Makefile.am b/doc/reference/cogl/Makefile.am index 5b1d1fb..3ea0463 100644 --- a/doc/reference/cogl/Makefile.am +++ b/doc/reference/cogl/Makefile.am @@ -92,7 +92,8 @@ EXTRA_HFILES= # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES = \ - fill-rule.png \ + fill-rule-non-zero.png \ + fill-rule-even-odd.png \ cogl_ortho.png # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). @@ -122,5 +123,6 @@ include $(top_srcdir)/gtk-doc.make # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += \ - fill-rule.png \ + fill-rule-non-zero.png \ + fill-rule-even-odd.png \ cogl_ortho.png diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt index 6a4b7e4..3ab3ad6 100644 --- a/doc/reference/cogl/cogl-sections.txt +++ b/doc/reference/cogl/cogl-sections.txt @@ -181,6 +181,9 @@ cogl_path_round_rectangle cogl_path_ellipse +CoglPathFillRule +cogl_path_set_fill_rule +cogl_path_get_fill_rule cogl_path_fill cogl_path_fill_preserve cogl_path_stroke diff --git a/doc/reference/cogl/fill-rule.png b/doc/reference/cogl/fill-rule-even-odd.png similarity index 100% rename from doc/reference/cogl/fill-rule.png rename to doc/reference/cogl/fill-rule-even-odd.png diff --git a/doc/reference/cogl/fill-rule-non-zero.png b/doc/reference/cogl/fill-rule-non-zero.png new file mode 100644 index 0000000..2d8ad31 Binary files /dev/null and b/doc/reference/cogl/fill-rule-non-zero.png differ