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.
This commit is contained in:
Neil Roberts 2010-06-23 13:40:43 +01:00
parent 95317b9623
commit 3a1456f34e
7 changed files with 120 additions and 18 deletions

View File

@ -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;

View File

@ -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);

View File

@ -53,6 +53,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
@ -65,6 +107,31 @@ typedef struct _CoglPath CoglPath;
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:
*
@ -72,21 +139,8 @@ cogl_is_path (CoglHandle handle);
* 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
*/

View File

@ -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

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB