diff options
Diffstat (limited to 'src/cairo.c')
-rw-r--r-- | src/cairo.c | 93 |
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. **/ |