summaryrefslogtreecommitdiff
path: root/src/cairo-win32-printing-surface.c
diff options
context:
space:
mode:
authorVladimir Vukicevic <vladimir@pobox.com>2008-01-24 11:01:55 -0800
committerVladimir Vukicevic <vladimir@pobox.com>2008-01-24 11:24:02 -0800
commit8e7c0db8018b258fc367da1e5502e9e13bad098c (patch)
tree15ecc2629adbb56c7b5a8c0ab5271e2a9c78ce32 /src/cairo-win32-printing-surface.c
parentc05e3b08b4cfa820a18e33b5012a6138b931788f (diff)
[win32] Better tracking of initial clip
There were a few corner cases that the win32 surface was failing at when there was an initial clip set; the win32-printing surface had more serious problems when painting meta surface patterns. This cleans up the initial DC clip tracking for both surfaces.
Diffstat (limited to 'src/cairo-win32-printing-surface.c')
-rw-r--r--src/cairo-win32-printing-surface.c69
1 files changed, 27 insertions, 42 deletions
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index ee08d4af..cc74bcf7 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -460,11 +460,14 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
EndPath (surface->dc);
SelectClipPath (surface->dc, RGN_AND);
+ SaveDC (surface->dc); /* Allow clip path to be reset during replay */
status = _cairo_meta_surface_replay (meta_surface, &surface->base);
+
+ /* Restore both the clip save and our earlier path SaveDC */
+ RestoreDC (surface->dc, -2);
+
if (status)
return status;
-
- RestoreDC (surface->dc, -1);
}
}
@@ -970,9 +973,8 @@ _cairo_win32_printing_surface_show_page (void *abstract_surface)
{
cairo_win32_surface_t *surface = abstract_surface;
- if (surface->clip_saved_dc != 0)
- RestoreDC (surface->dc, surface->clip_saved_dc);
- RestoreDC (surface->dc, -1);
+ /* Undo both SaveDC's that we did in start_page */
+ RestoreDC (surface->dc, -2);
return CAIRO_STATUS_SUCCESS;
}
@@ -991,10 +993,9 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
return CAIRO_STATUS_SUCCESS;
if (path == NULL) {
- if (surface->clip_saved_dc != 0) {
- RestoreDC (surface->dc, surface->clip_saved_dc);
- surface->clip_saved_dc = 0;
- }
+ RestoreDC (surface->dc, -1);
+ SaveDC (surface->dc);
+
return CAIRO_STATUS_SUCCESS;
}
@@ -1013,8 +1014,6 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
ASSERT_NOT_REACHED;
}
- if (surface->clip_saved_dc == 0)
- surface->clip_saved_dc = SaveDC (surface->dc);
SelectClipPath (surface->dc, RGN_AND);
return status;
@@ -1417,7 +1416,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
cairo_win32_surface_t *surface = abstract_surface;
XFORM xform;
- SaveDC (surface->dc);
+ SaveDC (surface->dc); /* Save application context first, before doing MWT */
+
SetGraphicsMode (surface->dc, GM_ADVANCED);
GetWorldTransform(surface->dc, &xform);
surface->ctm.xx = xform.eM11;
@@ -1430,6 +1430,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
+ SaveDC (surface->dc); /* Then save Cairo's known-good clip state, so the clip path can be reset */
+
return CAIRO_STATUS_SUCCESS;
}
@@ -1462,21 +1464,18 @@ cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc)
{
cairo_win32_surface_t *surface;
- RECT rect;
int xr, yr;
-
- /* Try to figure out the drawing bounds for the Device context
- */
- if (GetClipBox (hdc, &rect) == ERROR) {
- _cairo_win32_print_gdi_error ("cairo_win32_surface_create");
- /* XXX: Can we make a more reasonable guess at the error cause here? */
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
+ RECT rect;
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ if (_cairo_win32_save_initial_clip (hdc, surface) != CAIRO_STATUS_SUCCESS) {
+ free (surface);
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ }
+
surface->image = NULL;
surface->format = CAIRO_FORMAT_RGB24;
surface->content = CAIRO_CONTENT_COLOR_ALPHA;
@@ -1488,28 +1487,14 @@ cairo_win32_printing_surface_create (HDC hdc)
surface->brush = NULL;
surface->old_brush = NULL;
- surface->clip_rect.x = (int16_t) rect.left;
- surface->clip_rect.y = (int16_t) rect.top;
- surface->clip_rect.width = (uint16_t) (rect.right - rect.left);
- surface->clip_rect.height = (uint16_t) (rect.bottom - rect.top);
-
- 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;
+ GetClipBox(hdc, &rect);
+ surface->extents.x = rect.left;
+ surface->extents.y = rect.top;
+ surface->extents.width = rect.right - rect.left;
+ surface->extents.height = rect.bottom - rect.top;
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
- surface->clip_saved_dc = 0;
_cairo_win32_printing_surface_init_ps_mode (surface);
_cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend,
@@ -1521,8 +1506,8 @@ cairo_win32_printing_surface_create (HDC hdc)
return _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA,
- rect.right - rect.left,
- rect.bottom - rect.top,
+ surface->extents.width,
+ surface->extents.height,
&cairo_win32_surface_paginated_backend);
}