summaryrefslogtreecommitdiff
path: root/src/cairo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo.c')
-rw-r--r--src/cairo.c93
1 files changed, 54 insertions, 39 deletions
diff --git a/src/cairo.c b/src/cairo.c
index 5117f8a..73dbaee 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -117,11 +117,13 @@ static const cairo_t _cairo_nil = {
{ 0, 0 }, /* last_move_point */
{ 0, 0 }, /* current point */
FALSE, /* has_current_point */
- FALSE, /* has_last_move_point */
+ TRUE, /* needs_move_to */
+ FALSE, /* has_extents */
FALSE, /* has_curve_to */
- FALSE, /* is_box */
- FALSE, /* maybe_fill_region */
- TRUE, /* is_empty_fill */
+ TRUE, /* stroke_is_rectilinear */
+ TRUE, /* fill_is_rectilinear */
+ TRUE, /* fill_maybe_region */
+ TRUE, /* fill_is_empty */
{ {0, 0}, {0, 0}}, /* extents */
{{{NULL,NULL}}} /* link */
}}
@@ -138,11 +140,13 @@ static const cairo_t _cairo_nil__null_pointer = {
{ 0, 0 }, /* last_move_point */
{ 0, 0 }, /* current point */
FALSE, /* has_current_point */
- FALSE, /* has_last_move_point */
+ TRUE, /* needs_move_to */
+ FALSE, /* has_extents */
FALSE, /* has_curve_to */
- FALSE, /* is_box */
- FALSE, /* maybe_fill_region */
- TRUE, /* is_empty_fill */
+ TRUE, /* stroke_is_rectilinear */
+ TRUE, /* fill_is_rectilinear */
+ TRUE, /* fill_maybe_region */
+ TRUE, /* fill_is_empty */
{ {0, 0}, {0, 0}}, /* extents */
{{{NULL,NULL}}} /* link */
}}
@@ -341,7 +345,8 @@ _cairo_reset_static_data (void)
* default values and with @target as a target surface. The target
* surface should be constructed with a backend-specific function such
* as cairo_image_surface_create() (or any other
- * cairo_<emphasis>backend</emphasis>_surface_create() variant).
+ * <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function>
+ * variant).
*
* This function references @target, so you can immediately
* call cairo_surface_destroy() on it if you don't need to
@@ -580,6 +585,11 @@ cairo_restore (cairo_t *cr)
if (unlikely (cr->status))
return;
+ if (unlikely (_cairo_gstate_is_group (cr->gstate))) {
+ _cairo_set_error (cr, _cairo_error (CAIRO_STATUS_INVALID_RESTORE));
+ return;
+ }
+
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
if (unlikely (status))
_cairo_set_error (cr, status);
@@ -749,7 +759,7 @@ slim_hidden_def(cairo_push_group_with_content);
cairo_pattern_t *
cairo_pop_group (cairo_t *cr)
{
- cairo_surface_t *group_surface, *parent_target;
+ cairo_surface_t *group_surface;
cairo_pattern_t *group_pattern;
cairo_matrix_t group_matrix, device_transform_matrix;
cairo_status_t status;
@@ -757,27 +767,18 @@ cairo_pop_group (cairo_t *cr)
if (unlikely (cr->status))
return _cairo_pattern_create_in_error (cr->status);
- /* Grab the active surfaces */
- group_surface = _cairo_gstate_get_target (cr->gstate);
- parent_target = _cairo_gstate_get_parent_target (cr->gstate);
-
/* Verify that we are at the right nesting level */
- if (parent_target == NULL) {
+ if (unlikely (! _cairo_gstate_is_group (cr->gstate))) {
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
}
- /* We need to save group_surface before we restore; we don't need
- * to reference parent_target and original_target, since the
- * gstate will still hold refs to them once we restore. */
+ /* Get a reference to the active surface before restoring */
+ group_surface = _cairo_gstate_get_target (cr->gstate);
group_surface = cairo_surface_reference (group_surface);
- cairo_restore (cr);
-
- if (unlikely (cr->status)) {
- group_pattern = _cairo_pattern_create_in_error (cr->status);
- goto done;
- }
+ status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
+ assert (status == CAIRO_STATUS_SUCCESS);
group_pattern = cairo_pattern_create_for_surface (group_surface);
status = group_pattern->status;
@@ -824,7 +825,7 @@ slim_hidden_def(cairo_pop_group);
* operations:
*
* <informalexample><programlisting>
- * #cairo_pattern_t *group = cairo_pop_group (cr);
+ * cairo_pattern_t *group = cairo_pop_group (cr);
* cairo_set_source (cr, group);
* cairo_pattern_destroy (group);
* </programlisting></informalexample>
@@ -1806,8 +1807,8 @@ slim_hidden_def (cairo_curve_to);
* Adds a circular arc of the given @radius to the current path. The
* arc is centered at (@xc, @yc), begins at @angle1 and proceeds in
* the direction of increasing angles to end at @angle2. If @angle2 is
- * less than @angle1 it will be progressively increased by 2*M_PI
- * until it is greater than @angle1.
+ * less than @angle1 it will be progressively increased by
+ * <literal>2*M_PI</literal> until it is greater than @angle1.
*
* If there is a current point, an initial line segment will be added
* to the path to connect the current point to the beginning of the
@@ -1815,11 +1816,12 @@ slim_hidden_def (cairo_curve_to);
* calling cairo_new_sub_path() before calling cairo_arc().
*
* Angles are measured in radians. An angle of 0.0 is in the direction
- * of the positive X axis (in user space). An angle of %M_PI/2.0 radians
- * (90 degrees) is in the direction of the positive Y axis (in
- * user space). Angles increase in the direction from the positive X
- * axis toward the positive Y axis. So with the default transformation
- * matrix, angles increase in a clockwise direction.
+ * of the positive X axis (in user space). An angle of
+ * <literal>M_PI/2.0</literal> radians (90 degrees) is in the
+ * direction of the positive Y axis (in user space). Angles increase
+ * in the direction from the positive X axis toward the positive Y
+ * axis. So with the default transformation matrix, angles increase in
+ * a clockwise direction.
*
* (To convert from degrees to radians, use <literal>degrees * (M_PI /
* 180.)</literal>.)
@@ -1857,8 +1859,14 @@ cairo_arc (cairo_t *cr,
return;
}
- while (angle2 < angle1)
- angle2 += 2 * M_PI;
+ if (angle2 < angle1) {
+ /* increase angle2 by multiples of full circle until it
+ * satisfies angle2 >= angle1 */
+ angle2 = fmod (angle2 - angle1, 2 * M_PI);
+ if (angle2 < 0)
+ angle2 += 2 * M_PI;
+ angle2 += angle1;
+ }
cairo_line_to (cr,
xc + radius * cos (angle1),
@@ -1880,8 +1888,8 @@ cairo_arc (cairo_t *cr,
* Adds a circular arc of the given @radius to the current path. The
* arc is centered at (@xc, @yc), begins at @angle1 and proceeds in
* the direction of decreasing angles to end at @angle2. If @angle2 is
- * greater than @angle1 it will be progressively decreased by 2*M_PI
- * until it is less than @angle1.
+ * greater than @angle1 it will be progressively decreased by
+ * <literal>2*M_PI</literal> until it is less than @angle1.
*
* See cairo_arc() for more details. This function differs only in the
* direction of the arc between the two angles.
@@ -1899,8 +1907,14 @@ cairo_arc_negative (cairo_t *cr,
if (radius <= 0.0)
return;
- while (angle2 > angle1)
- angle2 -= 2 * M_PI;
+ if (angle2 > angle1) {
+ /* decrease angle2 by multiples of full circle until it
+ * satisfies angle2 <= angle1 */
+ angle2 = fmod (angle2 - angle1, 2 * M_PI);
+ if (angle2 > 0)
+ angle2 -= 2 * M_PI;
+ angle2 += angle1;
+ }
cairo_line_to (cr,
xc + radius * cos (angle1),
@@ -3780,7 +3794,8 @@ slim_hidden_def (cairo_get_tolerance);
* cairo_get_antialias:
* @cr: a cairo context
*
- * Gets the current shape antialiasing mode, as set by cairo_set_shape_antialias().
+ * Gets the current shape antialiasing mode, as set by
+ * cairo_set_antialias().
*
* Return value: the current shape antialiasing mode.
**/