[cairo-commit] cairo/src cairo.c, 1.33, 1.34 cairo_gstate.c, 1.42,
1.43 cairo_image_surface.c, 1.7, 1.8 cairo_ps_surface.c, 1.6,
1.7 cairo_surface.c, 1.23, 1.24 cairo_xlib_surface.c, 1.16,
1.17 cairoint.h, 1.52, 1.53
Graydon Hoare
commit at pdx.freedesktop.org
Fri Mar 19 15:47:27 PST 2004
Committed by: graydon
Update of /cvs/cairo/cairo/src
In directory pdx:/tmp/cvs-serv14228/src
Modified Files:
cairo.c cairo_gstate.c cairo_image_surface.c
cairo_ps_surface.c cairo_surface.c cairo_xlib_surface.c
cairoint.h
Log Message:
2004-03-19 Graydon Hoare <graydon at redhat.com>
* src/cairo.c (cairo_init_clip): Add.
* src/cairo_gstate.c:
Initialize, finalize and copy clip.region.
Detect rectangular clips and push down to backend.
* src/cairoint.h
(cairo_surface_backend_t): Add set_clip_region slot.
(cairo_clip_rec_t): Add region slot.
(_cairo_gstate_init_clip)
(_cairo_surface_set_clip_region): Prototype.
* src/cairo_surface.c
(_cairo_surface_set_clip_region): Add.
* src/cairo_xlib_surface.c
(_cairo_xlib_surface_set_clip_region): Add.
* src/cairo_image_surface.c
(_cairo_image_surface_set_clip_region): Add.
* src/cairo_ps_surface.c
(_cairo_ps_surface_set_clip_region): Stub, not implemented.
Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** a/cairo.c 18 Feb 2004 02:38:23 -0000 1.33
--- b/cairo.c 19 Mar 2004 23:47:25 -0000 1.34
***************
*** 637,640 ****
--- 637,649 ----
void
+ cairo_init_clip (cairo_t *cr)
+ {
+ if (cr->status)
+ return;
+
+ cr->status = _cairo_gstate_init_clip (cr->gstate);
+ }
+
+ void
cairo_clip (cairo_t *cr)
{
Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -d -r1.42 -r1.43
*** a/cairo_gstate.c 18 Feb 2004 02:38:23 -0000 1.42
--- b/cairo_gstate.c 19 Mar 2004 23:47:25 -0000 1.43
***************
*** 82,85 ****
--- 82,86 ----
gstate->source_is_solid = 1;
+ gstate->clip.region = NULL;
gstate->clip.surface = NULL;
***************
*** 124,127 ****
--- 125,134 ----
}
+ if (other->clip.region)
+ {
+ gstate->clip.region = pixman_region_create ();
+ pixman_region_copy (gstate->clip.region, other->clip.region);
+ }
+
cairo_surface_reference (gstate->surface);
cairo_surface_reference (gstate->source);
***************
*** 167,170 ****
--- 174,181 ----
gstate->clip.surface = NULL;
+ if (gstate->clip.region)
+ pixman_region_destroy (gstate->clip.region);
+ gstate->clip.region = NULL;
+
_cairo_color_fini (&gstate->color);
***************
*** 1437,1440 ****
--- 1448,1452 ----
cairo_surface_destroy (white);
BAIL0:
+
if (status)
return status;
***************
*** 1549,1552 ****
--- 1561,1629 ----
}
+
+ cairo_status_t
+ _cairo_gstate_init_clip (cairo_gstate_t *gstate)
+ {
+ pixman_region16_t *rect = NULL;
+ pixman_box16_t box;
+
+ /* destroy any existing clip-region artifacts */
+
+ if (gstate->clip.surface)
+ cairo_surface_destroy (gstate->clip.surface);
+ gstate->clip.surface = NULL;
+
+ if (gstate->clip.region)
+ pixman_region_destroy (gstate->clip.region);
+ gstate->clip.region = NULL;
+
+ /* reset the surface's clip to the whole surface */
+ _cairo_surface_set_clip_region (gstate->surface,
+ gstate->clip.region);
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ static int
+ extract_transformed_rectangle(cairo_matrix_t *mat,
+ cairo_traps_t *tr,
+ pixman_box16_t *box)
+ {
+ #define CAIRO_FIXED_IS_INTEGER(x) (((x) & 0xFFFF) == 0)
+ #define CAIRO_FIXED_INTEGER_PART(x) ((x) >> 16)
+
+ double a, b, c, d, tx, ty;
+ cairo_status_t st;
+
+ st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
+ if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.))
+ return 0;
+
+ if (tr->num_traps == 1
+ && tr->traps[0].left.p1.x == tr->traps[0].left.p2.x
+ && tr->traps[0].right.p1.x == tr->traps[0].right.p2.x
+ && tr->traps[0].left.p1.y == tr->traps[0].right.p1.y
+ && tr->traps[0].left.p2.y == tr->traps[0].right.p2.y
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p1.x)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p1.y)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p2.x)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].left.p2.y)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p1.x)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p1.y)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p2.x)
+ && CAIRO_FIXED_IS_INTEGER(tr->traps[0].right.p2.y)) {
+
+ box->x1 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p1.x);
+ box->x2 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].right.p1.x);
+ box->y1 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p1.y);
+ box->y2 = (short) CAIRO_FIXED_INTEGER_PART(tr->traps[0].left.p2.y);
+ return 1;
+ }
+ return 0;
+
+ #undef CAIRO_FIXED_IS_INTEGER
+ #undef CAIRO_FIXED_INTEGER_PART
+ }
+
cairo_status_t
_cairo_gstate_clip (cairo_gstate_t *gstate)
***************
*** 1556,1559 ****
--- 1633,1685 ----
cairo_traps_t traps;
cairo_color_t white_color;
+ pixman_box16_t box;
+
+ /* Fill the clip region as traps. */
+
+ _cairo_traps_init (&traps);
+ status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
+ if (status) {
+ _cairo_traps_fini (&traps);
+ return status;
+ }
+
+ /* Check to see if we can represent these traps as a PixRegion. */
+
+ if (extract_transformed_rectangle (&gstate->ctm, &traps, &box)) {
+
+ pixman_region16_t *rect = NULL;
+ pixman_region16_t *intersection = NULL;
+
+ status = CAIRO_STATUS_SUCCESS;
+ rect = pixman_region_create_simple (&box);
+
+ if (rect == NULL) {
+ status = CAIRO_STATUS_NO_MEMORY;
+
+ } else {
+
+ if (gstate->clip.region == NULL) {
+ gstate->clip.region = rect;
+ } else {
+ intersection = pixman_region_create();
+ if (pixman_region_intersect (intersection,
+ gstate->clip.region, rect)
+ == PIXMAN_REGION_STATUS_SUCCESS) {
+ pixman_region_destroy (gstate->clip.region);
+ gstate->clip.region = intersection;
+ } else {
+ status = CAIRO_STATUS_NO_MEMORY;
+ }
+ pixman_region_destroy (rect);
+ }
+
+ _cairo_surface_set_clip_region (gstate->surface,
+ gstate->clip.region);
+ }
+ _cairo_traps_fini (&traps);
+ return status;
+ }
+
+ /* Otherwise represent the clip as a mask surface. */
_cairo_color_init (&white_color);
***************
*** 1584,1594 ****
cairo_surface_set_repeat (alpha_one, 1);
- _cairo_traps_init (&traps);
- status = _cairo_path_fill_to_traps (&gstate->path, gstate, &traps);
- if (status) {
- _cairo_traps_fini (&traps);
- return status;
- }
-
_cairo_gstate_clip_and_composite_trapezoids (gstate,
alpha_one,
--- 1710,1713 ----
Index: cairo_image_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_image_surface.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** a/cairo_image_surface.c 11 Dec 2003 21:04:39 -0000 1.7
--- b/cairo_image_surface.c 19 Mar 2004 23:47:25 -0000 1.8
***************
*** 450,453 ****
--- 450,462 ----
}
+ static cairo_int_status_t
+ _cairo_image_surface_set_clip_region (void *abstract_surface,
+ pixman_region16_t *region)
+ {
+ cairo_image_surface_t *surf = (cairo_image_surface_t *) abstract_surface;
+ pixman_image_set_clip_region (surf->pixman_image, region);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
static const cairo_surface_backend_t cairo_image_surface_backend = {
_cairo_image_surface_create_similar,
***************
*** 463,466 ****
_cairo_image_surface_composite_trapezoids,
_cairo_image_surface_copy_page,
! _cairo_image_surface_show_page
};
--- 472,476 ----
_cairo_image_surface_composite_trapezoids,
_cairo_image_surface_copy_page,
! _cairo_image_surface_show_page,
! _cairo_image_surface_set_clip_region
};
Index: cairo_ps_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ps_surface.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** a/cairo_ps_surface.c 11 Dec 2003 20:43:58 -0000 1.6
--- b/cairo_ps_surface.c 19 Mar 2004 23:47:25 -0000 1.7
***************
*** 395,398 ****
--- 395,407 ----
}
+ static cairo_int_status_t
+ _cairo_ps_surface_set_clip_region (void *abstract_surface,
+ pixman_region16_t *region)
+ {
+ /* FIXME: I don't really understand this backend. */
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+
static const cairo_surface_backend_t cairo_ps_surface_backend = {
_cairo_ps_surface_create_similar,
***************
*** 408,411 ****
_cairo_ps_surface_composite_trapezoids,
_cairo_ps_surface_copy_page,
! _cairo_ps_surface_show_page
};
--- 417,421 ----
_cairo_ps_surface_composite_trapezoids,
_cairo_ps_surface_copy_page,
! _cairo_ps_surface_show_page,
! _cairo_ps_surface_set_clip_region
};
Index: cairo_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_surface.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** a/cairo_surface.c 17 Mar 2004 17:44:26 -0000 1.23
--- b/cairo_surface.c 19 Mar 2004 23:47:25 -0000 1.24
***************
*** 373,374 ****
--- 373,379 ----
}
+ cairo_status_t
+ _cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region)
+ {
+ return surface->backend->set_clip_region (surface, region);
+ }
Index: cairo_xlib_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** a/cairo_xlib_surface.c 2 Feb 2004 19:20:45 -0000 1.16
--- b/cairo_xlib_surface.c 19 Mar 2004 23:47:25 -0000 1.17
***************
*** 456,460 ****
cairo_xlib_surface_t *src_clone = NULL;
cairo_xlib_surface_t *mask_clone = NULL;
!
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
--- 456,460 ----
cairo_xlib_surface_t *src_clone = NULL;
cairo_xlib_surface_t *mask_clone = NULL;
!
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
***************
*** 574,577 ****
--- 574,620 ----
}
+ static cairo_int_status_t
+ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
+ pixman_region16_t *region)
+ {
+ Region xregion;
+ XRectangle xr;
+ pixman_box16_t *box;
+ cairo_xlib_surface_t *surf;
+ int n, m;
+
+ surf = (cairo_xlib_surface_t *) abstract_surface;
+
+ if (region == NULL) {
+ /* NULL region == reset the clip */
+ xregion = XCreateRegion();
+ xr.x = 0;
+ xr.y = 0;
+ xr.width = surf->width;
+ xr.height = surf->height;
+ XUnionRectWithRegion (&xr, xregion, xregion);
+
+ } else {
+ n = pixman_region_num_rects (region);
+ if (n == 0)
+ return;
+ box = pixman_region_rects (region);
+ xregion = XCreateRegion();
+
+ m = n;
+ for (; n > 0; --n, ++box) {
+ xr.x = (short) box->x1;
+ xr.y = (short) box->y1;
+ xr.width = (unsigned short) (box->x2 - box->x1);
+ xr.height = (unsigned short) (box->y2 - box->y1);
+ XUnionRectWithRegion (&xr, xregion, xregion);
+ }
+ }
+
+ XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion);
+ XDestroyRegion(xregion);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
static const struct cairo_surface_backend cairo_xlib_surface_backend = {
_cairo_xlib_surface_create_similar,
***************
*** 587,591 ****
_cairo_xlib_surface_composite_trapezoids,
_cairo_xlib_surface_copy_page,
! _cairo_xlib_surface_show_page
};
--- 630,635 ----
_cairo_xlib_surface_composite_trapezoids,
_cairo_xlib_surface_copy_page,
! _cairo_xlib_surface_show_page,
! _cairo_xlib_surface_set_clip_region
};
***************
*** 646,650 ****
else
surface->picture = 0;
!
return (cairo_surface_t *) surface;
}
--- 690,694 ----
else
surface->picture = 0;
!
return (cairo_surface_t *) surface;
}
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** a/cairoint.h 18 Feb 2004 02:38:23 -0000 1.52
--- b/cairoint.h 19 Mar 2004 23:47:25 -0000 1.53
***************
*** 373,376 ****
--- 373,380 ----
cairo_int_status_t
(*show_page) (void *surface);
+
+ cairo_int_status_t
+ (*set_clip_region) (void *surface,
+ pixman_region16_t *region);
} cairo_surface_backend_t;
***************
*** 464,467 ****
--- 468,472 ----
int width;
int height;
+ pixman_region16_t *region;
cairo_surface_t *surface;
} cairo_clip_rec_t;
***************
*** 753,756 ****
--- 758,764 ----
extern cairo_status_t __internal_linkage
+ _cairo_gstate_init_clip (cairo_gstate_t *gstate);
+
+ extern cairo_status_t __internal_linkage
_cairo_gstate_clip (cairo_gstate_t *gstate);
***************
*** 1035,1038 ****
--- 1043,1049 ----
_cairo_surface_show_page (cairo_surface_t *surface);
+ extern cairo_status_t __internal_linkage
+ _cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region);
+
extern double __internal_linkage
_cairo_surface_pixels_per_inch (cairo_surface_t *surface);
More information about the cairo-commit
mailing list