diff options
author | Vladimir Vukicevic <vladimir@pobox.com> | 2008-01-24 11:01:55 -0800 |
---|---|---|
committer | Vladimir Vukicevic <vladimir@pobox.com> | 2008-01-24 11:24:02 -0800 |
commit | 8e7c0db8018b258fc367da1e5502e9e13bad098c (patch) | |
tree | 15ecc2629adbb56c7b5a8c0ab5271e2a9c78ce32 /src/cairo-win32-printing-surface.c | |
parent | c05e3b08b4cfa820a18e33b5012a6138b931788f (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.c | 69 |
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); } |