pjs/gfx/cairo/native-clipping.patch

190 строки
4.9 KiB
Diff

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);