commit 857df0583365228150b3319475efc43b22077d06 Author: Jeff Muizelaar <jmuizelaar@mozilla.com> Date: Tue Apr 20 15:43:54 2010 -0400 native clipping diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index df063bf..819e53e 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -39,6 +39,8 @@ #include "cairo-quartz-private.h" #include "cairo-surface-clipper-private.h" +#include "cairo-gstate-private.h" +#include "cairo-private.h" #include <dlfcn.h> @@ -3095,6 +3097,61 @@ cairo_quartz_surface_get_cg_context (cairo_surface_t *surface) return quartz->cgContext; } +CGContextRef +cairo_quartz_get_cg_context_with_clip (cairo_t *cr) +{ + + cairo_surface_t *surface = cr->gstate->target; + cairo_clip_t *clip = &cr->gstate->clip; + cairo_status_t status; + + cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t*)surface; + + if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_QUARTZ) + return NULL; + + if (!clip->path) { + if (clip->all_clipped) { + /* Save the state before we set an empty clip rect so that + * our previous clip will be restored */ + CGContextSaveGState (quartz->cgContext); + + /* _cairo_surface_clipper_set_clip doesn't deal with + * clip->all_clipped because drawing is normally discarded earlier */ + CGRect empty = {{0,0}, {0,0}}; + CGContextClipToRect (quartz->cgContext, empty); + + return quartz->cgContext; + } + + /* an empty clip is represented by NULL */ + clip = NULL; + } + + status = _cairo_surface_clipper_set_clip (&quartz->clipper, clip); + + /* Save the state after we set the clip so that it persists + * after we restore */ + CGContextSaveGState (quartz->cgContext); + + if (unlikely (status)) + return NULL; + + return quartz->cgContext; +} + +void +cairo_quartz_finish_cg_context_with_clip (cairo_t *cr) +{ + cairo_surface_t *surface = cr->gstate->target; + + cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t*)surface; + + if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_QUARTZ) + return; + + CGContextRestoreGState (quartz->cgContext); +} /* Debug stuff */ diff --git a/src/cairo-quartz.h b/src/cairo-quartz.h index e8b71ba..aa1cdd2 100644 --- a/src/cairo-quartz.h +++ b/src/cairo-quartz.h @@ -57,6 +57,12 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext, cairo_public CGContextRef cairo_quartz_surface_get_cg_context (cairo_surface_t *surface); +cairo_public CGContextRef +cairo_quartz_get_cg_context_with_clip (cairo_t *cr); + +cairo_public void +cairo_quartz_finish_cg_context_with_clip (cairo_t *cr); + #if CAIRO_HAS_QUARTZ_FONT /* diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index d4575a3..c10e134 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -52,7 +52,9 @@ #include "cairo-win32-private.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-surface-fallback-private.h" - +#include "cairo-surface-clipper-private.h" +#include "cairo-gstate-private.h" +#include "cairo-private.h" #include <wchar.h> #include <windows.h> @@ -1914,6 +1916,61 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface) return NULL; } + +HDC +cairo_win32_get_dc_with_clip (cairo_t *cr) +{ + cairo_surface_t *surface = cr->gstate->target; + cairo_clip_t clip; + _cairo_clip_init_copy(&clip, &cr->gstate->clip); + + if (_cairo_surface_is_win32 (surface)){ + cairo_win32_surface_t *winsurf = (cairo_win32_surface_t *) surface; + cairo_region_t *clip_region = NULL; + cairo_status_t status; + + if (clip.path) { + status = _cairo_clip_get_region (&clip, &clip_region); + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + if (status) { + _cairo_clip_fini(&clip); + return NULL; + } + } + _cairo_win32_surface_set_clip_region (winsurf, clip_region); + + _cairo_clip_fini(&clip); + return winsurf->dc; + } + + if (_cairo_surface_is_paginated (surface)) { + cairo_surface_t *target; + + target = _cairo_paginated_surface_get_target (surface); + +#ifndef CAIRO_OMIT_WIN32_PRINTING + if (_cairo_surface_is_win32_printing (target)) { + cairo_status_t status; + cairo_win32_surface_t *winsurf = (cairo_win32_surface_t *) target; + + status = _cairo_surface_clipper_set_clip (&winsurf->clipper, &clip); + + _cairo_clip_fini(&clip); + + if (status) + return NULL; + + return winsurf->dc; + } +#endif + } + + _cairo_clip_fini(&clip); + return NULL; +} + + + /** * cairo_win32_surface_get_image * @surface: a #cairo_surface_t diff --git a/src/cairo-win32.h b/src/cairo-win32.h index 7d04d2a..c304f92 100644 --- a/src/cairo-win32.h +++ b/src/cairo-win32.h @@ -65,6 +65,9 @@ cairo_win32_surface_create_with_dib (cairo_format_t format, cairo_public HDC cairo_win32_surface_get_dc (cairo_surface_t *surface); +cairo_public HDC +cairo_win32_get_dc_with_clip (cairo_t *cr); + cairo_public cairo_surface_t * cairo_win32_surface_get_image (cairo_surface_t *surface);