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