From c382f9daf091331a37df61a8cfe883b7606af66b Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 27 Apr 2005 10:16:47 +0000 Subject: [PATCH] src/cairo-traps.c src/cairoint.h (_cairo_traps_init_box): New function to create a single trapezoid box. src/cairo.c src/cairo-gstate.c src/cairoint.h: Move the implementation of cairo_paint() into cairo-gstate.c for a better fix for the problem with backend/user coordinate confusion. Also no longer clear the current path on cairo_paint() --- ChangeLog | 11 +++++++++++ src/cairo-gstate.c | 30 +++++++++++++++++++++++++++--- src/cairo-traps.c | 37 +++++++++++++++++++++++++++++++++++++ src/cairo.c | 26 +------------------------- src/cairoint.h | 11 +++++++---- 5 files changed, 83 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index bcb903cb7..1d0cada2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-04-27 Owen Taylor + + * src/cairo-traps.c src/cairoint.h (_cairo_traps_init_box): + New function to create a single trapezoid box. + + * src/cairo.c src/cairo-gstate.c src/cairoint.h: Move + the implementation of cairo_paint() into cairo-gstate.c + for a better fix for the problem with backend/user coordinate + confusion. Also no longer clear the current path on + cairo_paint(). + 2005-04-26 Carl Worth * src/cairo.c (cairo_paint): Build rectangle with an identity diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index c0cb7dbd4..e3295bce9 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -715,10 +715,34 @@ _cairo_gstate_pattern_transform (cairo_gstate_t *gstate, } cairo_status_t -_cairo_gstate_get_clip_extents (cairo_gstate_t *gstate, - cairo_rectangle_t *rectangle) +_cairo_gstate_paint (cairo_gstate_t *gstate) { - return _cairo_surface_get_clip_extents (gstate->surface, rectangle); + cairo_rectangle_t rectangle; + cairo_status_t status; + cairo_box_t box; + cairo_traps_t traps; + + status = _cairo_surface_get_clip_extents (gstate->surface, &rectangle); + if (!CAIRO_OK (status)) + return status; + + box.p1.x = _cairo_fixed_from_int (rectangle.x); + box.p1.y = _cairo_fixed_from_int (rectangle.y); + box.p2.x = _cairo_fixed_from_int (rectangle.x + rectangle.width); + box.p2.y = _cairo_fixed_from_int (rectangle.y + rectangle.height); + status = _cairo_traps_init_box (&traps, &box); + if (!CAIRO_OK (status)) + return status; + + _cairo_gstate_clip_and_composite_trapezoids (gstate, + gstate->source, + gstate->operator, + gstate->surface, + &traps); + + _cairo_traps_fini (&traps); + + return CAIRO_STATUS_SUCCESS; } cairo_status_t diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 9cd7ce7ce..15dfc1bca 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -88,6 +88,43 @@ _cairo_traps_fini (cairo_traps_t *traps) } } +/** + * _cairo_traps_init_box: + * @traps: a #cairo_traps_t + * @box: a box that will be converted to a single trapezoid + * to store in @traps. + * + * Initializes a cairo_traps_t to contain a single rectangular + * trapezoid. + **/ +cairo_status_t +_cairo_traps_init_box (cairo_traps_t *traps, + cairo_box_t *box) +{ + cairo_status_t status; + + _cairo_traps_init (traps); + + status = _cairo_traps_grow_by (traps, 1); + if (status) + return status; + + traps->num_traps = 1; + + traps->traps[0].top = box->p1.y; + traps->traps[0].bottom = box->p2.y; + traps->traps[0].left.p1 = box->p1; + traps->traps[0].left.p2.x = box->p1.x; + traps->traps[0].left.p2.y = box->p2.y; + traps->traps[0].right.p1.x = box->p2.x; + traps->traps[0].right.p1.y = box->p1.y; + traps->traps[0].right.p2 = box->p2; + + traps->extents = *box; + + return CAIRO_STATUS_SUCCESS; +} + static cairo_status_t _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, cairo_line_t *left, cairo_line_t *right) diff --git a/src/cairo.c b/src/cairo.c index dc703f248..316827f74 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1485,35 +1485,11 @@ slim_hidden_def(cairo_close_path); void cairo_paint (cairo_t *cr) { - cairo_rectangle_t rectangle; - CAIRO_CHECK_SANITY (cr); if (cr->status) return; - cr->status = _cairo_gstate_get_clip_extents (cr->gstate, &rectangle); - if (cr->status) - return; - - /* Use an indentity matrix, but only while creating the path, - * since _cairo_gstate_get_clip_extents returns a rectangle in - * device space. Using an identity matrix simply saves a pair of - * conversions from device to user space then back again. - * - * The identity matrix is not used for the fill so that the source - * will be properly transformed. - */ - - cairo_save (cr); - cairo_identity_matrix (cr); - - cairo_rectangle (cr, - rectangle.x, rectangle.y, - rectangle.width, rectangle.height); - - cairo_restore (cr); - - cairo_fill (cr); + cr->status = _cairo_gstate_paint (cr->gstate); CAIRO_CHECK_SANITY (cr); } diff --git a/src/cairoint.h b/src/cairoint.h index 324c2f32f..44618cc71 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1048,16 +1048,15 @@ _cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y); cairo_private void _cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y); +cairo_private cairo_status_t +_cairo_gstate_paint (cairo_gstate_t *gstate); + cairo_private cairo_status_t _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path); cairo_private cairo_status_t _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path); -cairo_private cairo_status_t -_cairo_gstate_get_clip_extents (cairo_gstate_t *gstate, - cairo_rectangle_t *rectangle); - cairo_private cairo_status_t _cairo_gstate_copy_page (cairo_gstate_t *gstate); @@ -1615,6 +1614,10 @@ _cairo_matrix_is_integer_translation(cairo_matrix_t *matrix, int *itx, int *ity) cairo_private void _cairo_traps_init (cairo_traps_t *traps); +cairo_private cairo_status_t +_cairo_traps_init_box (cairo_traps_t *traps, + cairo_box_t *box); + cairo_private void _cairo_traps_fini (cairo_traps_t *traps);