mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 00:25:27 +00:00
236 lines
7.1 KiB
Diff
236 lines
7.1 KiB
Diff
Index: cairo-glitz/src/cairo-surface.c
|
|
===================================================================
|
|
--- cairo-glitz.orig/src/cairo-surface.c
|
|
+++ cairo-glitz/src/cairo-surface.c
|
|
@@ -502,6 +502,10 @@ cairo_surface_mark_dirty (cairo_surface_
|
|
* Like cairo_surface_mark_dirty(), but drawing has been done only to
|
|
* the specified rectangle, so that cairo can retain cached contents
|
|
* for other parts of the surface.
|
|
+ *
|
|
+ * Any cached clip set on the surface will be reset by this function,
|
|
+ * to make sure that future cairo calls have the clip set that they
|
|
+ * expect.
|
|
*/
|
|
void
|
|
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
|
@@ -520,6 +524,12 @@ cairo_surface_mark_dirty_rectangle (cair
|
|
return;
|
|
}
|
|
|
|
+ /* Always reset the clip here, to avoid having a SaveDC/RestoreDC around
|
|
+ * cairo calls that update the surface clip resulting in a desync between
|
|
+ * the cairo clip and the backend clip.
|
|
+ */
|
|
+ surface->current_clip_serial = -1;
|
|
+
|
|
if (surface->backend->mark_dirty_rectangle) {
|
|
cairo_status_t status;
|
|
|
|
@@ -1329,6 +1339,12 @@ _cairo_surface_set_clip (cairo_surface_t
|
|
if (!surface)
|
|
return CAIRO_STATUS_NULL_POINTER;
|
|
|
|
+ if (surface->status)
|
|
+ return surface->status;
|
|
+
|
|
+ if (surface->finished)
|
|
+ return CAIRO_STATUS_SURFACE_FINISHED;
|
|
+
|
|
if (clip) {
|
|
serial = clip->serial;
|
|
if (serial == 0)
|
|
@@ -1336,7 +1352,7 @@ _cairo_surface_set_clip (cairo_surface_t
|
|
}
|
|
|
|
surface->clip = clip;
|
|
-
|
|
+
|
|
if (serial == _cairo_surface_get_current_clip_serial (surface))
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
Index: cairo-glitz/src/cairo-win32-private.h
|
|
===================================================================
|
|
--- cairo-glitz.orig/src/cairo-win32-private.h
|
|
+++ cairo-glitz/src/cairo-win32-private.h
|
|
@@ -62,9 +62,9 @@ typedef struct _cairo_win32_surface {
|
|
|
|
cairo_rectangle_t clip_rect;
|
|
|
|
- int set_clip;
|
|
HRGN saved_clip;
|
|
|
|
+ cairo_rectangle_t extents;
|
|
} cairo_win32_surface_t;
|
|
|
|
cairo_status_t
|
|
Index: cairo-glitz/src/cairo-win32-surface.c
|
|
===================================================================
|
|
--- cairo-glitz.orig/src/cairo-win32-surface.c
|
|
+++ cairo-glitz/src/cairo-win32-surface.c
|
|
@@ -274,9 +274,14 @@ _cairo_win32_surface_create_for_dc (HDC
|
|
surface->clip_rect.width = width;
|
|
surface->clip_rect.height = height;
|
|
|
|
- surface->set_clip = 0;
|
|
- surface->saved_clip = NULL;
|
|
-
|
|
+ surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
|
+ if (GetClipRgn (surface->dc, surface->saved_clip) == 0) {
|
|
+ DeleteObject(surface->saved_clip);
|
|
+ surface->saved_clip = NULL;
|
|
+ }
|
|
+
|
|
+ surface->extents = surface->clip_rect;
|
|
+
|
|
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
|
|
|
return (cairo_surface_t *)surface;
|
|
@@ -340,9 +345,8 @@ _cairo_win32_surface_finish (void *abstr
|
|
if (surface->image)
|
|
cairo_surface_destroy (surface->image);
|
|
|
|
- if (surface->saved_clip) {
|
|
+ if (surface->saved_clip)
|
|
DeleteObject (surface->saved_clip);
|
|
- }
|
|
|
|
/* If we created the Bitmap and DC, destroy them */
|
|
if (surface->bitmap) {
|
|
@@ -403,7 +407,7 @@ _cairo_win32_surface_acquire_source_imag
|
|
cairo_win32_surface_t *surface = abstract_surface;
|
|
cairo_win32_surface_t *local = NULL;
|
|
cairo_status_t status;
|
|
-
|
|
+
|
|
if (surface->image) {
|
|
*image_out = (cairo_image_surface_t *)surface->image;
|
|
*image_extra = NULL;
|
|
@@ -446,7 +450,7 @@ _cairo_win32_surface_acquire_dest_image
|
|
cairo_status_t status;
|
|
RECT clip_box;
|
|
int x1, y1, x2, y2;
|
|
-
|
|
+
|
|
if (surface->image) {
|
|
image_rect->x = 0;
|
|
image_rect->y = 0;
|
|
@@ -461,12 +465,12 @@ _cairo_win32_surface_acquire_dest_image
|
|
|
|
if (GetClipBox (surface->dc, &clip_box) == ERROR)
|
|
return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
|
|
-
|
|
+
|
|
x1 = clip_box.left;
|
|
x2 = clip_box.right;
|
|
y1 = clip_box.top;
|
|
y2 = clip_box.bottom;
|
|
-
|
|
+
|
|
if (interest_rect->x > x1)
|
|
x1 = interest_rect->x;
|
|
if (interest_rect->y > y1)
|
|
@@ -855,19 +859,9 @@ _cairo_win32_surface_set_clip_region (vo
|
|
|
|
if (region == NULL) {
|
|
/* Clear any clip set by cairo, return to the original */
|
|
-
|
|
- if (surface->set_clip) {
|
|
- if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
|
|
- return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
|
-
|
|
- if (surface->saved_clip) {
|
|
- DeleteObject (surface->saved_clip);
|
|
- surface->saved_clip = NULL;
|
|
- }
|
|
+ if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
|
|
+ return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
|
|
|
|
- surface->set_clip = 0;
|
|
- }
|
|
-
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
} else {
|
|
@@ -910,36 +904,16 @@ _cairo_win32_surface_set_clip_region (vo
|
|
if (!gdi_region)
|
|
return CAIRO_STATUS_NO_MEMORY;
|
|
|
|
- if (surface->set_clip) {
|
|
- /* Combine the new region with the original clip */
|
|
+ /* Combine the new region with the original clip */
|
|
|
|
- if (surface->saved_clip) {
|
|
- if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
|
|
- goto FAIL;
|
|
- }
|
|
-
|
|
- if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
|
+ if (surface->saved_clip) {
|
|
+ if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
|
|
goto FAIL;
|
|
-
|
|
- } else {
|
|
- /* Save the the current region */
|
|
-
|
|
- surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
|
- if (!surface->saved_clip) {
|
|
- goto FAIL; }
|
|
-
|
|
- /* This function has no error return! */
|
|
- if (GetClipRgn (surface->dc, surface->saved_clip) == 0) { /* No clip */
|
|
- DeleteObject (surface->saved_clip);
|
|
- surface->saved_clip = NULL;
|
|
- }
|
|
-
|
|
- if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
|
|
- goto FAIL;
|
|
-
|
|
- surface->set_clip = 1;
|
|
}
|
|
|
|
+ if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
|
+ goto FAIL;
|
|
+
|
|
DeleteObject (gdi_region);
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
@@ -955,15 +929,8 @@ _cairo_win32_surface_get_extents (void
|
|
cairo_rectangle_t *rectangle)
|
|
{
|
|
cairo_win32_surface_t *surface = abstract_surface;
|
|
- RECT clip_box;
|
|
|
|
- if (GetClipBox (surface->dc, &clip_box) == ERROR)
|
|
- return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
|
|
-
|
|
- rectangle->x = clip_box.left;
|
|
- rectangle->y = clip_box.top;
|
|
- rectangle->width = clip_box.right - clip_box.left;
|
|
- rectangle->height = clip_box.bottom - clip_box.top;
|
|
+ *rectangle = surface->extents;
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
@@ -1007,8 +974,19 @@ cairo_win32_surface_create (HDC hdc)
|
|
surface->clip_rect.width = rect.right - rect.left;
|
|
surface->clip_rect.height = rect.bottom - rect.top;
|
|
|
|
- surface->set_clip = 0;
|
|
- surface->saved_clip = NULL;
|
|
+ if (surface->clip_rect.width == 0 ||
|
|
+ surface->clip_rect.height == 0)
|
|
+ {
|
|
+ surface->saved_clip = NULL;
|
|
+ } else {
|
|
+ surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
|
+ if (GetClipRgn (hdc, surface->saved_clip) == 0) {
|
|
+ DeleteObject(surface->saved_clip);
|
|
+ surface->saved_clip = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ surface->extents = surface->clip_rect;
|
|
|
|
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
|
|