diff options
author | Carl Worth <cworth@cworth.org> | 2005-10-31 16:55:21 +0000 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2005-10-31 16:55:21 +0000 |
commit | a7228cc37a0cd967296e41639e624e9af1520a22 (patch) | |
tree | ba89701b461b3b0aebc367a57b260c2a676bc72d | |
parent | 3cae05c4c503ce71c4967bd3f748cdfa3bb76ebc (diff) |
Originally 2005-10-28 Keith Packard <keithp@keithp.com>:
Remove pen_regular field from the gstate.
Move stroke fallback from gstate to surface where it belongs.
Eliminate dependence on cairo_gstate_t object.
Fix to include just cairo-clip-private.h rather than cairo-gstate.private.h.
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | src/cairo-gstate-private.h | 2 | ||||
-rw-r--r-- | src/cairo-gstate.c | 113 | ||||
-rw-r--r-- | src/cairo-meta-surface.c | 2 | ||||
-rw-r--r-- | src/cairo-path-stroke.c | 185 | ||||
-rw-r--r-- | src/cairo-pen.c | 27 | ||||
-rw-r--r-- | src/cairo-surface.c | 90 | ||||
-rw-r--r-- | src/cairoint.h | 41 |
8 files changed, 335 insertions, 153 deletions
@@ -1,3 +1,31 @@ +2005-10-31 Carl Worth <cworth@cworth.org> + + Originally 2005-10-28 Keith Packard <keithp@keithp.com>: + + * src/cairo-gstate-private.h: Remove pen_regular field from the + gstate. + + * src/cairoint.h: + * src/cairo-gstate.c: (_cairo_gstate_init), + (_cairo_gstate_init_copy), (_cairo_gstate_fini), + (_cairo_gstate_stroke), (_cairo_gstate_in_stroke), + (_cairo_gstate_stroke_extents): + * src/cairo-path-stroke.c: (_cairo_stroker_start_dash), + (_cairo_stroker_step_dash), (_cairo_stroker_init), + (_cairo_stroker_fini), (_cairo_stroker_join), + (_cairo_stroker_add_cap), (_compute_face), + (_cairo_stroker_add_sub_edge), (_cairo_stroker_line_to_dashed), + (_cairo_stroker_curve_to), (_cairo_stroker_curve_to_dashed), + (_cairo_path_fixed_stroke_to_traps): + * src/cairo-surface.c: (_fallback_stroke), (_cairo_surface_stroke): + Move stroke fallback from gstate to surface where it belongs. + + * src/cairo-pen.c: (_cairo_pen_init): Eliminate dependence + on cairo_gstate_t object. + + * src/cairo-meta-surface.c: Fix to include just + cairo-clip-private.h rather than cairo-gstate.private.h. + 2005-10-31 T Rowley <tim.rowley@gmail.com> * src/cairo-win32-font.c (_cairo_win32_scaled_font_init_glyph_path): diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index cf4a22156..b174115f3 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -69,8 +69,6 @@ struct _cairo_gstate { cairo_matrix_t ctm_inverse; cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */ - cairo_pen_t pen_regular; - cairo_pattern_t *source; struct _cairo_gstate *next; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 40403657c..f8239d23a 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -53,10 +53,6 @@ static void _cairo_gstate_fini (cairo_gstate_t *gstate); static cairo_status_t -_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, - cairo_traps_t *traps); - -static cairo_status_t _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate); static cairo_status_t @@ -121,8 +117,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate, _cairo_gstate_identity_matrix (gstate); gstate->source_ctm_inverse = gstate->ctm_inverse; - _cairo_pen_init_empty (&gstate->pen_regular); - gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK); if (gstate->source->status) return CAIRO_STATUS_NO_MEMORY; @@ -135,7 +129,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate, static cairo_status_t _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) { - cairo_status_t status; cairo_gstate_t *next; /* Copy all members, but don't smash the next pointer */ @@ -163,20 +156,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) cairo_pattern_reference (gstate->source); - status = _cairo_pen_init_copy (&gstate->pen_regular, &other->pen_regular); - if (status) - goto CLEANUP_FONT; - - return status; - - CLEANUP_FONT: - cairo_scaled_font_destroy (gstate->scaled_font); - gstate->scaled_font = NULL; - - free (gstate->dash); - gstate->dash = NULL; - - return CAIRO_STATUS_NO_MEMORY; + return CAIRO_STATUS_SUCCESS; } static void @@ -197,8 +177,6 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) cairo_pattern_destroy (gstate->source); - _cairo_pen_fini (&gstate->pen_regular); - if (gstate->dash) { free (gstate->dash); gstate->dash = NULL; @@ -1157,7 +1135,7 @@ cairo_status_t _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { cairo_status_t status; - cairo_traps_t traps; + cairo_pattern_union_t source_pattern; if (gstate->source->status) return gstate->source->status; @@ -1169,21 +1147,28 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (status) return status; - _cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate); - - _cairo_traps_init (&traps); - - status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps); - if (status) { - _cairo_traps_fini (&traps); - return status; - } - - _cairo_gstate_clip_and_composite_trapezoids (gstate, &traps); + _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - _cairo_traps_fini (&traps); + status = _cairo_surface_stroke (gstate->operator, + &source_pattern.base, + gstate->target, + path, + gstate->tolerance, + &gstate->ctm, + &gstate->ctm_inverse, + gstate->antialias, + + gstate->line_width, + gstate->line_cap, + gstate->line_join, + gstate->miter_limit, + + gstate->dash, + gstate->num_dashes, + gstate->dash_offset); + + return status; - return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -1198,11 +1183,21 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate, _cairo_gstate_user_to_backend (gstate, &x, &y); - _cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate); - _cairo_traps_init (&traps); - status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps); + status = _cairo_path_fixed_stroke_to_traps (path, &traps, + gstate->tolerance, + &gstate->ctm, + &gstate->ctm_inverse, + + gstate->line_width, + gstate->line_cap, + gstate->line_join, + gstate->miter_limit, + + gstate->dash, + gstate->num_dashes, + gstate->dash_offset); if (status) goto BAIL; @@ -1498,28 +1493,6 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, return status; } -/* Warning: This call modifies the coordinates of traps */ -static cairo_status_t -_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, - cairo_traps_t *traps) -{ - cairo_pattern_union_t pattern; - cairo_status_t status; - - _cairo_gstate_copy_transformed_source (gstate, &pattern.base); - - status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base, - gstate->operator, - gstate->target, - traps, - &gstate->clip, - gstate->antialias); - - _cairo_pattern_fini (&pattern.base); - - return status; -} - cairo_status_t _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { @@ -1598,11 +1571,21 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate, cairo_traps_t traps; cairo_box_t extents; - _cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate); - _cairo_traps_init (&traps); - status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps); + status = _cairo_path_fixed_stroke_to_traps (path, &traps, + gstate->tolerance, + &gstate->ctm, + &gstate->ctm_inverse, + + gstate->line_width, + gstate->line_cap, + gstate->line_join, + gstate->miter_limit, + + gstate->dash, + gstate->num_dashes, + gstate->dash_offset); if (status) goto BAIL; diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 0801ca5eb..17498bba0 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -35,7 +35,7 @@ #include "cairoint.h" #include "cairo-meta-surface-private.h" -#include "cairo-gstate-private.h" +#include "cairo-clip-private.h" static const cairo_surface_backend_t cairo_meta_surface_backend; diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 788973100..ad5c51016 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -36,12 +36,26 @@ #include "cairoint.h" -#include "cairo-gstate-private.h" - typedef struct cairo_stroker { - cairo_gstate_t *gstate; cairo_traps_t *traps; + cairo_pen_t pen; + + cairo_matrix_t *ctm; + cairo_matrix_t *ctm_inverse; + double tolerance; + + /* stroke style */ + double line_width; + cairo_line_cap_t line_cap; + cairo_line_join_t line_join; + double miter_limit; + + /* dash style */ + double *dash; + int num_dashes; + double dash_offset; + cairo_bool_t has_current_point; cairo_point_t current_point; cairo_point_t first_point; @@ -60,7 +74,21 @@ typedef struct cairo_stroker { /* private functions */ static void -_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps); +_cairo_stroker_init (cairo_stroker_t *stroker, + cairo_traps_t *traps, + + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset); static void _cairo_stroker_fini (cairo_stroker_t *stroker); @@ -101,49 +129,75 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st static void _cairo_stroker_start_dash (cairo_stroker_t *stroker) { - cairo_gstate_t *gstate = stroker->gstate; double offset; int on = 1; int i = 0; - offset = gstate->dash_offset; - while (offset >= gstate->dash[i]) { - offset -= gstate->dash[i]; + offset = stroker->dash_offset; + while (offset >= stroker->dash[i]) { + offset -= stroker->dash[i]; on = 1-on; - if (++i == gstate->num_dashes) + if (++i == stroker->num_dashes) i = 0; } stroker->dashed = TRUE; stroker->dash_index = i; stroker->dash_on = on; - stroker->dash_remain = gstate->dash[i] - offset; + stroker->dash_remain = stroker->dash[i] - offset; } static void _cairo_stroker_step_dash (cairo_stroker_t *stroker, double step) { - cairo_gstate_t *gstate = stroker->gstate; stroker->dash_remain -= step; if (stroker->dash_remain <= 0) { stroker->dash_index++; - if (stroker->dash_index == gstate->num_dashes) + if (stroker->dash_index == stroker->num_dashes) stroker->dash_index = 0; stroker->dash_on = 1-stroker->dash_on; - stroker->dash_remain = gstate->dash[stroker->dash_index]; + stroker->dash_remain = stroker->dash[stroker->dash_index]; } } static void -_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps) +_cairo_stroker_init (cairo_stroker_t *stroker, + cairo_traps_t *traps, + + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset) { - stroker->gstate = gstate; stroker->traps = traps; + _cairo_pen_init (&stroker->pen, line_width / 2.0, tolerance, ctm); + + stroker->tolerance = tolerance; + stroker->ctm = ctm; + stroker->ctm_inverse = ctm_inverse; + + stroker->line_width = line_width; + stroker->line_cap = line_cap; + stroker->line_join = line_join; + stroker->miter_limit = miter_limit; + + stroker->dash = dash; + stroker->num_dashes = num_dashes; + stroker->dash_offset = dash_offset; + stroker->has_current_point = FALSE; stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; - if (gstate->dash) + if (stroker->dash) _cairo_stroker_start_dash (stroker); else stroker->dashed = FALSE; @@ -152,7 +206,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_tra static void _cairo_stroker_fini (cairo_stroker_t *stroker) { - /* nothing to do here */ + _cairo_pen_fini (&stroker->pen); } static void @@ -177,8 +231,7 @@ static cairo_status_t _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_stroke_face_t *out) { cairo_status_t status; - cairo_gstate_t *gstate = stroker->gstate; - int clockwise = _cairo_stroker_face_clockwise (out, in); + int clockwise = _cairo_stroker_face_clockwise (out, in); cairo_point_t *inpt, *outpt; if (in->cw.x == out->cw.x @@ -196,12 +249,12 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st outpt = &out->cw; } - switch (gstate->line_join) { + switch (stroker->line_join) { case CAIRO_LINE_JOIN_ROUND: { int i; int start, step, stop; cairo_point_t tri[3]; - cairo_pen_t *pen = &gstate->pen_regular; + cairo_pen_t *pen = &stroker->pen; tri[0] = in->point; if (clockwise) { @@ -237,7 +290,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st /* dot product of incoming slope vector with outgoing slope vector */ double in_dot_out = ((-in->usr_vector.x * out->usr_vector.x)+ (-in->usr_vector.y * out->usr_vector.y)); - double ml = gstate->miter_limit; + double ml = stroker->miter_limit; /* * Check the miter limit -- lines meeting at an acute angle @@ -285,14 +338,14 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st y1 = _cairo_fixed_to_double (inpt->y); dx1 = in->usr_vector.x; dy1 = in->usr_vector.y; - cairo_matrix_transform_distance (&gstate->ctm, &dx1, &dy1); + cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); /* outer point of outgoing line face */ x2 = _cairo_fixed_to_double (outpt->x); y2 = _cairo_fixed_to_double (outpt->y); dx2 = out->usr_vector.x; dy2 = out->usr_vector.y; - cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2); + cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); /* * Compute the location of the outer corner of the miter. @@ -344,18 +397,17 @@ static cairo_status_t _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) { cairo_status_t status; - cairo_gstate_t *gstate = stroker->gstate; - if (gstate->line_cap == CAIRO_LINE_CAP_BUTT) + if (stroker->line_cap == CAIRO_LINE_CAP_BUTT) return CAIRO_STATUS_SUCCESS; - switch (gstate->line_cap) { + switch (stroker->line_cap) { case CAIRO_LINE_CAP_ROUND: { int i; int start, stop; cairo_slope_t slope; cairo_point_t tri[3]; - cairo_pen_t *pen = &gstate->pen_regular; + cairo_pen_t *pen = &stroker->pen; slope = f->dev_vector; _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start); @@ -383,9 +435,9 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) dx = f->usr_vector.x; dy = f->usr_vector.y; - dx *= gstate->line_width / 2.0; - dy *= gstate->line_width / 2.0; - cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy); + dx *= stroker->line_width / 2.0; + dy *= stroker->line_width / 2.0; + cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); fvector.dx = _cairo_fixed_from_double (dx); fvector.dy = _cairo_fixed_from_double (dy); occw.x = f->ccw.x + fvector.dx; @@ -460,7 +512,7 @@ _cairo_stroker_add_caps (cairo_stroker_t *stroker) } static void -_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face) +_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_stroker_t *stroker, cairo_stroke_face_t *face) { double mag, det; double line_dx, line_dy; @@ -472,7 +524,7 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat line_dy = _cairo_fixed_to_double (slope->dy); /* faces are normal in user space, not device space */ - cairo_matrix_transform_distance (&gstate->ctm_inverse, &line_dx, &line_dy); + cairo_matrix_transform_distance (stroker->ctm_inverse, &line_dx, &line_dy); mag = sqrt (line_dx * line_dx + line_dy * line_dy); if (mag == 0) { @@ -494,20 +546,20 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat * whether the ctm reflects or not, and that can be determined * by looking at the determinant of the matrix. */ - _cairo_matrix_compute_determinant (&gstate->ctm, &det); + _cairo_matrix_compute_determinant (stroker->ctm, &det); if (det >= 0) { - face_dx = - line_dy * (gstate->line_width / 2.0); - face_dy = line_dx * (gstate->line_width / 2.0); + face_dx = - line_dy * (stroker->line_width / 2.0); + face_dy = line_dx * (stroker->line_width / 2.0); } else { - face_dx = line_dy * (gstate->line_width / 2.0); - face_dy = - line_dx * (gstate->line_width / 2.0); + face_dx = line_dy * (stroker->line_width / 2.0); + face_dy = - line_dx * (stroker->line_width / 2.0); } /* back to device space */ - cairo_matrix_transform_distance (&gstate->ctm, &face_dx, &face_dy); + cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); offset_ccw.x = _cairo_fixed_from_double (face_dx); offset_ccw.y = _cairo_fixed_from_double (face_dy); @@ -533,7 +585,6 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_ cairo_stroke_face_t *start, cairo_stroke_face_t *end) { cairo_status_t status; - cairo_gstate_t *gstate = stroker->gstate; cairo_polygon_t polygon; cairo_slope_t slope; @@ -545,12 +596,12 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_ } _cairo_slope_init (&slope, p1, p2); - _compute_face (p1, &slope, gstate, start); + _compute_face (p1, &slope, stroker, start); /* XXX: This could be optimized slightly by not calling _compute_face again but rather translating the relevant fields from start. */ - _compute_face (p2, &slope, gstate, end); + _compute_face (p2, &slope, stroker, end); /* XXX: I should really check the return value of the move_to/line_to functions here to catch out of memory @@ -648,7 +699,6 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; - cairo_gstate_t *gstate = stroker->gstate; double mag, remain, tmp; double dx, dy; double dx2, dy2; @@ -664,7 +714,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) dx = _cairo_fixed_to_double (p2->x - p1->x); dy = _cairo_fixed_to_double (p2->y - p1->y); - cairo_matrix_transform_distance (&gstate->ctm_inverse, &dx, &dy); + cairo_matrix_transform_distance (stroker->ctm_inverse, &dx, &dy); mag = sqrt (dx *dx + dy * dy); remain = mag; @@ -676,7 +726,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) remain -= tmp; dx2 = dx * (mag - remain)/mag; dy2 = dy * (mag - remain)/mag; - cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2); + cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); fd2.x = _cairo_fixed_from_double (dx2); fd2.y = _cairo_fixed_from_double (dy2); fd2.x += p1->x; @@ -764,7 +814,6 @@ _cairo_stroker_curve_to (void *closure, { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; - cairo_gstate_t *gstate = stroker->gstate; cairo_spline_t spline; cairo_pen_t pen; cairo_stroke_face_t start, end; @@ -775,12 +824,12 @@ _cairo_stroker_curve_to (void *closure, if (status == CAIRO_INT_STATUS_DEGENERATE) return CAIRO_STATUS_SUCCESS; - status = _cairo_pen_init_copy (&pen, &gstate->pen_regular); + status = _cairo_pen_init_copy (&pen, &stroker->pen); if (status) goto CLEANUP_SPLINE; - _compute_face (a, &spline.initial_slope, gstate, &start); - _compute_face (d, &spline.final_slope, gstate, &end); + _compute_face (a, &spline.initial_slope, stroker, &start); + _compute_face (d, &spline.final_slope, stroker, &end); if (stroker->has_current_face) { status = _cairo_stroker_join (stroker, &stroker->current_face, &start); @@ -812,7 +861,7 @@ _cairo_stroker_curve_to (void *closure, if (status) goto CLEANUP_PEN; - status = _cairo_pen_stroke_spline (&pen, &spline, gstate->tolerance, stroker->traps); + status = _cairo_pen_stroke_spline (&pen, &spline, stroker->tolerance, stroker->traps); if (status) goto CLEANUP_PEN; @@ -852,7 +901,6 @@ _cairo_stroker_curve_to_dashed (void *closure, { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; - cairo_gstate_t *gstate = stroker->gstate; cairo_spline_t spline; cairo_point_t *a = &stroker->current_point; cairo_line_join_t line_join_save; @@ -864,15 +912,15 @@ _cairo_stroker_curve_to_dashed (void *closure, /* If the line width is so small that the pen is reduced to a single point, then we have nothing to do. */ - if (gstate->pen_regular.num_vertices <= 1) + if (stroker->pen.num_vertices <= 1) goto CLEANUP_SPLINE; - /* Temporarily modify the gstate to use round joins to guarantee + /* Temporarily modify the stroker to use round joins to guarantee * smooth stroked curves. */ - line_join_save = gstate->line_join; - gstate->line_join = CAIRO_LINE_JOIN_ROUND; + line_join_save = stroker->line_join; + stroker->line_join = CAIRO_LINE_JOIN_ROUND; - status = _cairo_spline_decompose (&spline, gstate->tolerance); + status = _cairo_spline_decompose (&spline, stroker->tolerance); if (status) goto CLEANUP_GSTATE; @@ -886,7 +934,7 @@ _cairo_stroker_curve_to_dashed (void *closure, } CLEANUP_GSTATE: - gstate->line_join = line_join_save; + stroker->line_join = line_join_save; CLEANUP_SPLINE: _cairo_spline_fini (&spline); @@ -923,16 +971,29 @@ _cairo_stroker_close_path (void *closure) } cairo_status_t -_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, - cairo_gstate_t *gstate, - cairo_traps_t *traps) +_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, + cairo_traps_t *traps, + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t stroker; - _cairo_stroker_init (&stroker, gstate, traps); + _cairo_stroker_init (&stroker, traps, tolerance, ctm, ctm_inverse, + line_width, line_cap, line_join, miter_limit, + dash, num_dashes, dash_offset); - if (gstate->dash) + if (stroker.dash) status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_stroker_move_to, diff --git a/src/cairo-pen.c b/src/cairo-pen.c index d1a3c6117..a2cd55d93 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -36,8 +36,6 @@ #include "cairoint.h" -#include "cairo-gstate-private.h" - static int _cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix); @@ -59,35 +57,28 @@ _cairo_pen_init_empty (cairo_pen_t *pen) } cairo_status_t -_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) +_cairo_pen_init (cairo_pen_t *pen, + double radius, + double tolerance, + cairo_matrix_t *ctm) { int i; int reflect; double det; - if (pen->num_vertices) { - /* XXX: It would be nice to notice that the pen is already properly constructed. - However, this test would also have to account for possible changes in the transformation - matrix. - if (pen->radius == radius && pen->tolerance == tolerance) - return CAIRO_STATUS_SUCCESS; - */ - _cairo_pen_fini (pen); - } - pen->radius = radius; - pen->tolerance = gstate->tolerance; + pen->tolerance = tolerance; - _cairo_matrix_compute_determinant (&gstate->ctm, &det); + _cairo_matrix_compute_determinant (ctm, &det); if (det >= 0) { reflect = 0; } else { reflect = 1; } - pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance, + pen->num_vertices = _cairo_pen_vertices_needed (tolerance, radius, - &gstate->ctm); + ctm); pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t)); if (pen->vertices == NULL) { @@ -105,7 +96,7 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) double dx = radius * cos (reflect ? -theta : theta); double dy = radius * sin (reflect ? -theta : theta); cairo_pen_vertex_t *v = &pen->vertices[i]; - cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy); + cairo_matrix_transform_distance (ctm, &dx, &dy); v->point.x = _cairo_fixed_from_double (dx); v->point.y = _cairo_fixed_from_double (dy); } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index de088450d..4279eb5a6 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -38,7 +38,7 @@ #include <stdlib.h> #include "cairoint.h" -#include "cairo-gstate-private.h" +#include "cairo-clip-private.h" const cairo_surface_t _cairo_surface_nil = { &cairo_image_surface_backend, /* backend */ @@ -1303,6 +1303,94 @@ _cairo_surface_mask (cairo_operator_t operator, } static cairo_status_t +_fallback_stroke (cairo_operator_t operator, + cairo_pattern_t *source_pattern, + cairo_surface_t *dst, + cairo_path_fixed_t *path, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset) +{ + cairo_status_t status; + cairo_traps_t traps; + + _cairo_traps_init (&traps); + + status = _cairo_path_fixed_stroke_to_traps (path, &traps, tolerance, + ctm, ctm_inverse, + line_width, line_cap, + line_join, miter_limit, + dash, num_dashes, + dash_offset); + + if (status) { + _cairo_traps_fini (&traps); + return status; + } + + _cairo_surface_clip_and_composite_trapezoids (source_pattern, + operator, + dst, + &traps, + dst->clip, + antialias); + + _cairo_traps_fini (&traps); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_surface_stroke (cairo_operator_t operator, + cairo_pattern_t *source_pattern, + cairo_surface_t *dst, + cairo_path_fixed_t *path, + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + cairo_antialias_t antialias, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset) +{ + assert (! dst->is_snapshot); + + /* XXX: Need to add this to the backend. + if (dst->backend->stroke) { + cairo_status_t status; + status = dst->backend->stroke (operator, source_pattern, dst, path, + ctm, ctm_inverse, tolerance, antialias, + line_width, line_cap, + line_join, miter_limit, + dash, num_dashes, dash_offset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + */ + + return _fallback_stroke (operator, source_pattern, dst, path, + ctm, ctm_inverse, tolerance, antialias, + line_width, line_cap, line_join, miter_limit, + dash, num_dashes, dash_offset); +} + +static cairo_status_t _fallback_fill_path (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *dst, diff --git a/src/cairoint.h b/src/cairoint.h index 6dbef66de..72f29bd7e 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1419,9 +1419,20 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, /* cairo_path_stroke.c */ cairo_private cairo_status_t -_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, - cairo_gstate_t *gstate, - cairo_traps_t *traps); +_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, + cairo_traps_t *traps, + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset); /* cairo-scaled-font.c */ @@ -1582,6 +1593,25 @@ _cairo_surface_mask (cairo_operator_t operator, cairo_surface_t *dst); cairo_private cairo_status_t +_cairo_surface_stroke (cairo_operator_t operator, + cairo_pattern_t *source_pattern, + cairo_surface_t *dst, + cairo_path_fixed_t *path, + double tolerance, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + cairo_antialias_t antialias, + + double line_width, + cairo_line_cap_t line_cap, + cairo_line_join_t line_join, + double miter_limit, + + double *dash, + int num_dashes, + double dash_offset); + +cairo_private cairo_status_t _cairo_surface_fill_path (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *dst, @@ -1762,7 +1792,10 @@ _cairo_surface_is_image (const cairo_surface_t *surface); /* cairo_pen.c */ cairo_private cairo_status_t -_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate); +_cairo_pen_init (cairo_pen_t *pen, + double radius, + double tolerance, + cairo_matrix_t *ctm); cairo_private cairo_status_t _cairo_pen_init_empty (cairo_pen_t *pen); |