diff options
-rw-r--r-- | cogl/cogl-path-private.h | 3 | ||||
-rw-r--r-- | cogl/cogl-path.c | 38 | ||||
-rw-r--r-- | cogl/cogl-path.h | 88 | ||||
-rw-r--r-- | doc/reference/cogl/Makefile.am | 6 | ||||
-rw-r--r-- | doc/reference/cogl/cogl-sections.txt | 3 | ||||
-rw-r--r-- | doc/reference/cogl/fill-rule-even-odd.png (renamed from doc/reference/cogl/fill-rule.png) | bin | 3121 -> 3121 bytes | |||
-rw-r--r-- | doc/reference/cogl/fill-rule-non-zero.png | bin | 0 -> 3143 bytes |
7 files changed, 120 insertions, 18 deletions
diff --git a/cogl/cogl-path-private.h b/cogl/cogl-path-private.h index ecfb5202..8addddaa 100644 --- a/cogl/cogl-path-private.h +++ b/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/cogl/cogl-path.c b/cogl/cogl-path.c index f27218f0..687fdaa1 100644 --- a/cogl/cogl-path.c +++ b/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/cogl/cogl-path.h b/cogl/cogl-path.h index a4c74c08..edeefe0d 100644 --- a/cogl/cogl-path.h +++ b/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 <xref + * linkend="fill-rule-non-zero"/>. + * @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 <xref linkend="fill-rule-even-odd"/>. + * + * #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. + * + * <figure id="fill-rule-non-zero"> + * <title>Example of filling various paths using the non-zero rule</title> + * <graphic fileref="fill-rule-non-zero.png" format="PNG"/> + * </figure> + * + * <figure id="fill-rule-even-odd"> + * <title>Example of filling various paths using the even-odd rule</title> + * <graphic fileref="fill-rule-even-odd.png" format="PNG"/> + * </figure> + * + * 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 <xref linkend="fill-rule"/> for a demonstration of the fill - * rule. - * - * <figure id="fill-rule"> - * <title>Example of filling various paths</title> - * <graphic fileref="fill-rule.png" format="PNG"/> - * </figure> + * 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 5b1d1fb5..3ea04633 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 6a4b7e40..3ab3ad69 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 <SUBSECTION> +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 Binary files differindex 1e4fbb0f..1e4fbb0f 100644 --- a/doc/reference/cogl/fill-rule.png +++ b/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 Binary files differnew file mode 100644 index 00000000..2d8ad314 --- /dev/null +++ b/doc/reference/cogl/fill-rule-non-zero.png |