[cairo-commit]
cairo/src cairo_gstate.c, 1.76, 1.77 cairoint.h, 1.88, 1.89
Kristian Hogsberg
commit at pdx.freedesktop.org
Thu Jan 27 17:21:16 PST 2005
Committed by: krh
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv30935/src
Modified Files:
cairo_gstate.c cairoint.h
Log Message:
2005-01-27 Kristian Høgsberg <krh at redhat.com>
* src/cairoint.h (cairo_clip_rect_t):
* src/cairo_gstate.c (_cairo_gstate_clip_and_composite_trapezoids)
(_cairo_gstate_clip, _cairo_gstate_show_glyphs): Simplify code for
computing the extents of clipping area, by introducing a couple of
cairo_rectangle_t functions.
Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- cairo_gstate.c 27 Jan 2005 18:46:20 -0000 1.76
+++ cairo_gstate.c 28 Jan 2005 01:21:13 -0000 1.77
@@ -1387,51 +1387,60 @@
return status;
}
-static cairo_status_t
-_calculate_region_for_intermediate_clip_surface (pixman_region16_t *out,
- cairo_box_t *extents,
- cairo_clip_rec_t *clip_rect)
+/* XXX We currently have a confusing mix of boxes and rectangles as
+ * exemplified by this function. A cairo_box_t is a rectangular area
+ * represented by the coordinates of the upper left and lower right
+ * corners, expressed in fixed point numbers. A cairo_rectangle_t is
+ * also a rectangular area, but represented by the upper left corner
+ * and the width and the height, as integer numbers.
+ *
+ * This function converts a cairo_box_t to a cairo_rectangle_t by
+ * increasing the area to the nearest integer coordinates. We should
+ * standardize on cairo_rectangle_t and cairo_rectangle_fixed_t, and
+ * this function could be renamed to the more reasonable
+ * _cairo_rectangle_fixed_round.
+ */
+
+static void
+_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle)
{
- cairo_status_t status;
- pixman_region16_t *extents_region, *clip_region;
- pixman_box16_t clip_box, pixman_extents;
-
- pixman_extents.x1 = _cairo_fixed_integer_floor (extents->p1.x);
- pixman_extents.y1 = _cairo_fixed_integer_floor (extents->p1.y);
- pixman_extents.x2 = _cairo_fixed_integer_ceil (extents->p2.x);
- pixman_extents.y2 = _cairo_fixed_integer_ceil (extents->p2.y);
- extents_region = pixman_region_create_simple (&pixman_extents);
- if (extents_region == NULL)
- {
- status = CAIRO_STATUS_NO_MEMORY;
- goto BAIL0;
- }
+ rectangle->x = _cairo_fixed_integer_floor (box->p1.x);
+ rectangle->y = _cairo_fixed_integer_floor (box->p1.y);
+ rectangle->width = _cairo_fixed_integer_ceil (box->p2.x) - rectangle->x;
+ rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y;
+}
- clip_box.x1 = clip_rect->x;
- clip_box.y1 = clip_rect->y;
- clip_box.x2 = clip_rect->x + clip_rect->width;
- clip_box.y2 = clip_rect->y + clip_rect->height;
- clip_region = pixman_region_create_simple (&clip_box);
- if (clip_region == NULL)
- {
- status = CAIRO_STATUS_NO_MEMORY;
- goto BAIL1;
- }
+static void
+_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src)
+{
+ if (dest->x < src->x)
+ dest->x = src->x;
- if (pixman_region_intersect (out,
- extents_region,
- clip_region)
- == PIXMAN_REGION_STATUS_FAILURE)
- status = CAIRO_STATUS_NO_MEMORY;
+ if (dest->y < src->y)
+ dest->y = src->y;
+
+ if (dest->x + dest->width < src->x + src->width)
+ dest->width = dest->x + dest->width - dest->x;
else
- status = CAIRO_STATUS_SUCCESS;
-
- pixman_region_destroy (extents_region);
- BAIL1:
- pixman_region_destroy (clip_region);
-
- BAIL0:
- return status;
+ dest->width = src->x + src->width - dest->x;
+
+ if (dest->y + dest->height < src->y + src->height)
+ dest->height = dest->y + dest->height - dest->y;
+ else
+ dest->height = src->y + src->height - dest->y;
+
+ if (dest->width <= 0 || dest->height == 0) {
+ dest->x = 0;
+ dest->y = 0;
+ dest->width = 0;
+ dest->height = 0;
+ }
+}
+
+static int
+_cairo_rectangle_empty (cairo_rectangle_t *rect)
+{
+ return rect->width == 0 || rect->height == 0;
}
static void
@@ -1474,9 +1483,8 @@
{
cairo_status_t status;
cairo_pattern_t pattern;
- cairo_box_t extents;
- int x, y;
- unsigned int width, height;
+ cairo_rectangle_t extents;
+ cairo_box_t trap_extents;
if (traps->num_traps == 0)
return CAIRO_STATUS_SUCCESS;
@@ -1484,45 +1492,28 @@
if (gstate->surface == NULL)
return CAIRO_STATUS_NO_TARGET_SURFACE;
+ _cairo_traps_extents (traps, &trap_extents);
+ _cairo_box_round_to_rectangle (&trap_extents, &extents);
+
if (gstate->clip.surface) {
cairo_surface_t *intermediate;
cairo_color_t empty_color;
- pixman_box16_t *draw_extents;
- pixman_region16_t *draw_region;
- draw_region = pixman_region_create ();
- if (draw_region == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto BAIL0;
- }
-
- _cairo_traps_extents (traps, &extents);
-
- status = _calculate_region_for_intermediate_clip_surface (draw_region,
- &extents,
- &gstate->clip);
- if (status)
- goto BAIL1;
+ _cairo_rectangle_intersect (&extents, &gstate->clip.rect);
- /* Shortcut if empty */
- if (!pixman_region_not_empty (draw_region)) {
+ if (_cairo_rectangle_empty (&extents)) {
status = CAIRO_STATUS_SUCCESS;
goto BAIL1;
}
- draw_extents = pixman_region_extents (draw_region);
- x = draw_extents->x1;
- y = draw_extents->y1;
- width = draw_extents->x2 - x;
- height = draw_extents->y2 - y;
-
- translate_traps (traps, -x, -y);
+ translate_traps (traps, -extents.x, -extents.y);
_cairo_color_init (&empty_color);
_cairo_color_set_alpha (&empty_color, 0.);
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_FORMAT_A8,
- width, height,
+ extents.width,
+ extents.height,
&empty_color);
if (intermediate == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
@@ -1536,9 +1527,10 @@
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
&pattern, intermediate,
- x, y,
+ extents.x, extents.y,
0, 0,
- width, height,
+ extents.width,
+ extents.height,
traps->traps,
traps->num_traps);
_cairo_pattern_fini (&pattern);
@@ -1555,11 +1547,11 @@
&pattern,
NULL,
intermediate,
- x - gstate->clip.x,
- y - gstate->clip.y,
+ extents.x - gstate->clip.rect.x,
+ extents.y - gstate->clip.rect.y,
0, 0,
0, 0,
- width, height);
+ extents.width, extents.height);
_cairo_pattern_fini (&pattern);
if (status)
@@ -1570,38 +1562,30 @@
status = _cairo_surface_composite (operator,
&pattern, intermediate, dst,
- x, y,
+ extents.x, extents.y,
0, 0,
- x, y,
- width, height);
+ extents.x, extents.y,
+ extents.width, extents.height);
_cairo_pattern_fini (&pattern);
BAIL2:
cairo_surface_destroy (intermediate);
BAIL1:
- pixman_region_destroy (draw_region);
- BAIL0:
if (status)
return status;
} else {
- _cairo_traps_extents (traps, &extents);
-
- x = _cairo_fixed_integer_floor (extents.p1.x);
- y = _cairo_fixed_integer_floor (extents.p1.y);
- width = _cairo_fixed_integer_ceil (extents.p2.x) - x;
- height = _cairo_fixed_integer_ceil (extents.p2.y) - y;
-
_cairo_pattern_init_copy (&pattern, src);
_cairo_gstate_create_pattern (gstate, &pattern);
status = _cairo_surface_composite_trapezoids (gstate->operator,
&pattern, dst,
- x, y,
- x, y,
- width, height,
+ extents.x, extents.y,
+ extents.x, extents.y,
+ extents.width,
+ extents.height,
traps->traps,
traps->num_traps);
@@ -1829,8 +1813,6 @@
cairo_color_t white_color;
cairo_box_t extents;
pixman_box16_t box;
- int x, y;
- unsigned int width, height;
/* Fill the clip region as traps. */
@@ -1890,29 +1872,20 @@
_cairo_color_init (&white_color);
- _cairo_traps_extents (&traps, &extents);
- x = _cairo_fixed_integer_floor (extents.p1.x);
- y = _cairo_fixed_integer_floor (extents.p1.y);
- width = _cairo_fixed_integer_ceil (extents.p2.x) - x;
- height = _cairo_fixed_integer_ceil (extents.p2.y) - y;
-
-
if (gstate->clip.surface == NULL) {
- gstate->clip.x = x;
- gstate->clip.y = y;
- gstate->clip.width = width;
- gstate->clip.height = height;
+ _cairo_traps_extents (&traps, &extents);
+ _cairo_box_round_to_rectangle (&extents, &gstate->clip.rect);
gstate->clip.surface =
_cairo_surface_create_similar_solid (gstate->surface,
CAIRO_FORMAT_A8,
- gstate->clip.width,
- gstate->clip.height,
+ gstate->clip.rect.width,
+ gstate->clip.rect.height,
&white_color);
if (gstate->clip.surface == NULL)
return CAIRO_STATUS_NO_MEMORY;
}
- translate_traps (&traps, -gstate->clip.x, -gstate->clip.y);
+ translate_traps (&traps, -gstate->clip.rect.x, -gstate->clip.rect.y);
_cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
_cairo_gstate_create_pattern (gstate, &pattern);
_cairo_pattern_set_alpha (&pattern, 1.0);
@@ -1922,8 +1895,8 @@
gstate->clip.surface,
0, 0,
0, 0,
- gstate->clip.width,
- gstate->clip.height,
+ gstate->clip.rect.width,
+ gstate->clip.rect.height,
traps.traps,
traps.num_traps);
@@ -2015,6 +1988,7 @@
double device_width, device_height;
cairo_pattern_t pattern;
cairo_box_t pattern_extents;
+ cairo_rectangle_t extents;
cairo_surface_get_matrix (surface, &user_to_image);
cairo_matrix_multiply (&device_to_image, &gstate->ctm_inverse, &user_to_image);
@@ -2038,62 +2012,47 @@
pattern_extents.p1.y = _cairo_fixed_from_double (device_y);
pattern_extents.p2.x = _cairo_fixed_from_double (device_x + device_width);
pattern_extents.p2.y = _cairo_fixed_from_double (device_y + device_height);
+ _cairo_box_round_to_rectangle (&pattern_extents, &extents);
if (gstate->clip.surface)
{
- pixman_box16_t *draw_extents;
- pixman_region16_t *draw_region;
-
- draw_region = pixman_region_create ();
- if (draw_region == NULL)
- {
- status = CAIRO_STATUS_NO_MEMORY;
- goto BAIL0;
- }
-
- status = _calculate_region_for_intermediate_clip_surface (draw_region,
- &pattern_extents,
- &gstate->clip);
- if (status)
- goto BAIL1;
+ _cairo_rectangle_intersect (&extents, &gstate->clip.rect);
/* Shortcut if empty */
- if (!pixman_region_not_empty (draw_region)) {
+ if (_cairo_rectangle_empty (&extents)) {
status = CAIRO_STATUS_SUCCESS;
goto BAIL1;
}
- draw_extents = pixman_region_extents (draw_region);
-
status = _cairo_surface_composite (gstate->operator,
&pattern,
gstate->clip.surface,
gstate->surface,
- draw_extents->x1, draw_extents->y1,
+ extents.x, extents.y,
0, 0,
- draw_extents->x1, draw_extents->y1,
- draw_extents->x2 - draw_extents->x1,
- draw_extents->y2 - draw_extents->y1);
+ extents.x, extents.y,
+ extents.width, extents.height);
BAIL1:
- pixman_region_destroy (draw_region);
- BAIL0:
;
}
else
{
-
- /* XXX: The rendered size is sometimes 1 or 2 pixels short from
- what I expect. Need to fix this. */
+ /* XXX: The rendered size is sometimes 1 or 2 pixels short
+ * from what I expect. Need to fix this.
+ * KRH: I'm guessing this was due to rounding error when
+ * passing double coordinates for integer arguments. Using
+ * the extents rectangle should fix this, since it's properly
+ * rounded. Is this still the case?
+ */
status = _cairo_surface_composite (gstate->operator,
&pattern,
NULL,
gstate->surface,
- device_x, device_y,
+ extents.x, extents.y,
0, 0,
- device_x, device_y,
- device_width,
- device_height);
+ extents.x, extents.y,
+ extents.width, extents.height);
}
@@ -2437,8 +2396,7 @@
cairo_glyph_t *transformed_glyphs = NULL;
cairo_pattern_t pattern;
cairo_box_t bbox;
- int x, y;
- unsigned int width, height;
+ cairo_rectangle_t extents;
status = _cairo_gstate_ensure_font (gstate);
if (status)
@@ -2459,6 +2417,8 @@
status = _cairo_font_glyph_bbox (gstate->font,
transformed_glyphs, num_glyphs,
&bbox);
+ _cairo_box_round_to_rectangle (&bbox, &extents);
+
if (status)
goto CLEANUP_GLYPHS;
@@ -2466,41 +2426,21 @@
{
cairo_surface_t *intermediate;
cairo_color_t empty_color;
- pixman_box16_t *draw_extents;
- pixman_region16_t *draw_region;
-
- draw_region = pixman_region_create ();
- if (draw_region == NULL)
- {
- status = CAIRO_STATUS_NO_MEMORY;
- goto BAIL0;
- }
- status = _calculate_region_for_intermediate_clip_surface (draw_region,
- &bbox,
- &gstate->clip);
- if (status) {
- goto BAIL1;
- }
+ _cairo_rectangle_intersect (&extents, &gstate->clip.rect);
/* Shortcut if empty */
- if (!pixman_region_not_empty (draw_region)) {
+ if (_cairo_rectangle_empty (&extents)) {
status = CAIRO_STATUS_SUCCESS;
goto BAIL1;
}
- draw_extents = pixman_region_extents (draw_region);
-
- x = draw_extents->x1;
- y = draw_extents->y1;
- width = draw_extents->x2 - x;
- height = draw_extents->y2 - y;
-
_cairo_color_init (&empty_color);
_cairo_color_set_alpha (&empty_color, .0);
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_FORMAT_A8,
- width, height,
+ extents.width,
+ extents.height,
&empty_color);
if (intermediate == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
@@ -2510,8 +2450,8 @@
/* move the glyphs again, from dev space to intermediate space */
for (i = 0; i < num_glyphs; ++i)
{
- transformed_glyphs[i].x -= x;
- transformed_glyphs[i].y -= y;
+ transformed_glyphs[i].x -= extents.x;
+ transformed_glyphs[i].y -= extents.y;
}
_cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
@@ -2521,9 +2461,9 @@
status = _cairo_font_show_glyphs (gstate->font,
CAIRO_OPERATOR_ADD,
&pattern, intermediate,
- x, y,
+ extents.x, extents.y,
0, 0,
- width, height,
+ extents.width, extents.height,
transformed_glyphs, num_glyphs);
_cairo_pattern_fini (&pattern);
@@ -2539,12 +2479,11 @@
&pattern,
NULL,
intermediate,
- draw_extents->x1 - gstate->clip.x,
- draw_extents->y1 - gstate->clip.y,
+ extents.x - gstate->clip.rect.x,
+ extents.y - gstate->clip.rect.y,
0, 0,
0, 0,
- draw_extents->x2 - draw_extents->x1,
- draw_extents->y2 - draw_extents->y1);
+ extents.width, extents.height);
_cairo_pattern_fini (&pattern);
@@ -2558,35 +2497,28 @@
&pattern,
intermediate,
gstate->surface,
- x, y,
+ extents.x, extents.y,
0, 0,
- x, y,
- width, height);
+ extents.x, extents.y,
+ extents.width, extents.height);
_cairo_pattern_fini (&pattern);
BAIL2:
cairo_surface_destroy (intermediate);
BAIL1:
- pixman_region_destroy (draw_region);
- BAIL0:
;
}
else
{
- x = _cairo_fixed_integer_floor (bbox.p1.x);
- y = _cairo_fixed_integer_floor (bbox.p1.y);
- width = _cairo_fixed_integer_ceil (bbox.p2.x) - x;
- height = _cairo_fixed_integer_ceil (bbox.p2.y) - y;
-
_cairo_pattern_init_copy (&pattern, gstate->pattern);
_cairo_gstate_create_pattern (gstate, &pattern);
status = _cairo_font_show_glyphs (gstate->font,
gstate->operator, &pattern,
gstate->surface,
- x, y,
- x, y,
- width, height,
+ extents.x, extents.y,
+ extents.x, extents.y,
+ extents.width, extents.height,
transformed_glyphs, num_glyphs);
_cairo_pattern_fini (&pattern);
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -d -r1.88 -r1.89
--- cairoint.h 27 Jan 2005 18:46:20 -0000 1.88
+++ cairoint.h 28 Jan 2005 01:21:13 -0000 1.89
@@ -781,10 +781,7 @@
/* Need a name distinct from the cairo_clip function */
typedef struct _cairo_clip_rec {
- int x;
- int y;
- int width;
- int height;
+ cairo_rectangle_t rect;
pixman_region16_t *region;
cairo_surface_t *surface;
} cairo_clip_rec_t;
More information about the cairo-commit
mailing list