mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
347084e968
A problem happens when clip->all_clipped is set and we go to get a clipped context. Normally backends don't see operations with clip->all_clipped and so _cairo_surface_clipper_set_clip is designed with the assumption that clip->all_clipped is never true. I added a work-around by manually setting the CGContextClip with an empty rectangle, however this caused cairo to be confused about what the actual clip was. This patch fixes the problem by adding a new function cairo_quartz_finish_cg_context_with_clip that is called after we're done with the native context. It moves the CGContextSave/RestoreGState calls out of gfxNativeDrawing into cairo and uses them to ensure that the clip remains consistent with cairo's model of them.
190 lines
4.9 KiB
Diff
190 lines
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 */
|
|
+
|
|
+ /* _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);
|
|
+ CGContextSaveGState (quartz->cgContext);
|
|
+
|
|
+ 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);
|
|
|