summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2010-07-28 19:03:13 +0200
committerAndrea Canciani <ranma42@gmail.com>2010-10-13 00:27:01 +0200
commitc22e75e9f6cb471c764af0d721ad07cdf30a3bad (patch)
tree72b761015fdb13fa2b38173054612eb6eba55397
parent6bc1376cf52a9815b75f8c0ce66e149fbc64495e (diff)
downloadcairo-c22e75e9f6cb471c764af0d721ad07cdf30a3bad.tar.gz
quartz: Set operator when setting up source
Share some code between the drawing functions by saving the state and setting the operator when setting up the source and by restoring the state during teardown. Based on a patch by Robert O'Callahan <robert@ocallahan.org>. See https://bugzilla.mozilla.org/show_bug.cgi?id=522859
-rw-r--r--src/cairo-quartz-private.h2
-rw-r--r--src/cairo-quartz-surface.c69
2 files changed, 21 insertions, 50 deletions
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index 55bc84dfb..9a45c66e9 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -83,8 +83,6 @@ typedef struct cairo_quartz_surface {
CGShadingRef sourceShading;
CGPatternRef sourcePattern;
-
- CGInterpolationQuality oldInterpolationQuality;
} cairo_quartz_surface_t;
typedef struct cairo_quartz_image_surface {
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index a76adee77..4f111ad8a 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1417,12 +1417,25 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
static cairo_int_status_t
_cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
+ cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_rectangle_int_t *extents)
{
+ cairo_status_t status;
+
assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern));
- surface->oldInterpolationQuality = CGContextGetInterpolationQuality (surface->cgContext);
+ /* Save before we change the pattern, colorspace, etc. so that
+ * we can restore and make sure that quartz releases our
+ * pattern (which may be stack allocated)
+ */
+
+ CGContextSaveGState (surface->cgContext);
+
+ status = _cairo_quartz_surface_set_cairo_operator (surface, op);
+ if (unlikely (status))
+ return status;
+
CGContextSetInterpolationQuality (surface->cgContext, _cairo_quartz_filter_to_quartz (source->filter));
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
@@ -1461,7 +1474,6 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
CGImageRef img;
cairo_matrix_t m = spat->base.matrix;
cairo_rectangle_int_t extents;
- cairo_status_t status;
CGAffineTransform xform;
CGRect srcRect;
cairo_fixed_t fw, fh;
@@ -1536,11 +1548,6 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
if (unlikely (status))
return status;
- // Save before we change the pattern, colorspace, etc. so that
- // we can restore and make sure that quartz releases our
- // pattern (which may be stack allocated)
- CGContextSaveGState (surface->cgContext);
-
patternSpace = CGColorSpaceCreatePattern (NULL);
CGContextSetFillColorSpace (surface->cgContext, patternSpace);
CGContextSetFillPattern (surface->cgContext, pattern, &patternAlpha);
@@ -1566,7 +1573,7 @@ static void
_cairo_quartz_teardown_source (cairo_quartz_surface_t *surface,
const cairo_pattern_t *source)
{
- CGContextSetInterpolationQuality (surface->cgContext, surface->oldInterpolationQuality);
+ CGContextRestoreGState (surface->cgContext);
if (surface->sourceImage) {
CGImageRelease (surface->sourceImage);
@@ -1583,21 +1590,19 @@ _cairo_quartz_teardown_source (cairo_quartz_surface_t *surface,
if (surface->sourcePattern) {
CGPatternRelease (surface->sourcePattern);
- // To tear down the pattern and colorspace
- CGContextRestoreGState (surface->cgContext);
-
surface->sourcePattern = NULL;
}
}
static cairo_int_status_t
_cairo_quartz_setup_source_safe (cairo_quartz_surface_t *surface,
+ cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_rectangle_int_t *extents)
{
cairo_int_status_t status;
- status = _cairo_quartz_setup_source (surface, source, extents);
+ status = _cairo_quartz_setup_source (surface, op, source, extents);
if (unlikely (status))
_cairo_quartz_teardown_source (surface, source);
@@ -1986,15 +1991,11 @@ _cairo_quartz_surface_paint_cg (cairo_quartz_surface_t *surface,
if (unlikely (rv))
return rv;
- rv = _cairo_quartz_surface_set_cairo_operator (surface, op);
- if (unlikely (rv))
- return rv;
-
extents = surface->virtual_extents;
extents.x -= surface->base.device_transform.x0;
extents.y -= surface->base.device_transform.y0;
_cairo_rectangle_union (&extents, &surface->extents);
- rv = _cairo_quartz_setup_source_safe (surface, source, &extents);
+ rv = _cairo_quartz_setup_source_safe (surface, op, source, &extents);
if (unlikely (rv))
return rv;
@@ -2004,14 +2005,10 @@ _cairo_quartz_surface_paint_cg (cairo_quartz_surface_t *surface,
surface->extents.width,
surface->extents.height));
} else if (surface->action == DO_SHADING) {
- CGContextSaveGState (surface->cgContext);
CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
CGContextDrawShading (surface->cgContext, surface->sourceShading);
- CGContextRestoreGState (surface->cgContext);
} else if (surface->action == DO_IMAGE || surface->action == DO_TILED_IMAGE) {
- CGContextSaveGState (surface->cgContext);
_cairo_quartz_draw_image (surface, op);
- CGContextRestoreGState (surface->cgContext);
}
_cairo_quartz_teardown_source (surface, source);
@@ -2070,20 +2067,14 @@ _cairo_quartz_surface_fill_cg (cairo_quartz_surface_t *surface,
if (unlikely (rv))
return rv;
- rv = _cairo_quartz_surface_set_cairo_operator (surface, op);
- if (unlikely (rv))
- return rv;
-
extents = surface->virtual_extents;
extents.x -= surface->base.device_transform.x0;
extents.y -= surface->base.device_transform.y0;
_cairo_rectangle_union (&extents, &surface->extents);
- rv = _cairo_quartz_setup_source_safe (surface, source, &extents);
+ rv = _cairo_quartz_setup_source_safe (surface, op, source, &extents);
if (unlikely (rv))
return rv;
- CGContextSaveGState (surface->cgContext);
-
CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
_cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext);
@@ -2118,8 +2109,6 @@ _cairo_quartz_surface_fill_cg (cairo_quartz_surface_t *surface,
_cairo_quartz_teardown_source (surface, source);
- CGContextRestoreGState (surface->cgContext);
-
if (path_for_unbounded) {
unbounded_op_data_t ub;
ub.op = UNBOUNDED_STROKE_FILL;
@@ -2197,10 +2186,6 @@ _cairo_quartz_surface_stroke_cg (cairo_quartz_surface_t *surface,
if (unlikely (rv))
return rv;
- rv = _cairo_quartz_surface_set_cairo_operator (surface, op);
- if (unlikely (rv))
- return rv;
-
// Turning antialiasing off used to cause misrendering with
// single-pixel lines (e.g. 20,10.5 -> 21,10.5 end up being rendered as 2 pixels).
// That's been since fixed in at least 10.5, and in the latest 10.4 dot releases.
@@ -2239,12 +2224,10 @@ _cairo_quartz_surface_stroke_cg (cairo_quartz_surface_t *surface,
extents.x -= surface->base.device_transform.x0;
extents.y -= surface->base.device_transform.y0;
_cairo_rectangle_union (&extents, &surface->extents);
- rv = _cairo_quartz_setup_source_safe (surface, source, &extents);
+ rv = _cairo_quartz_setup_source_safe (surface, op, source, &extents);
if (unlikely (rv))
return rv;
- CGContextSaveGState (surface->cgContext);
-
_cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext);
if (!_cairo_operator_bounded_by_mask (op) && CGContextCopyPathPtr)
@@ -2273,8 +2256,6 @@ _cairo_quartz_surface_stroke_cg (cairo_quartz_surface_t *surface,
_cairo_quartz_teardown_source (surface, source);
- CGContextRestoreGState (surface->cgContext);
-
if (path_for_unbounded) {
unbounded_op_data_t ub;
ub.op = UNBOUNDED_STROKE_FILL;
@@ -2375,20 +2356,14 @@ _cairo_quartz_surface_show_glyphs_cg (cairo_quartz_surface_t *surface,
if (unlikely (rv))
return rv;
- rv = _cairo_quartz_surface_set_cairo_operator (surface, op);
- if (unlikely (rv))
- return rv;
-
extents = surface->virtual_extents;
extents.x -= surface->base.device_transform.x0;
extents.y -= surface->base.device_transform.y0;
_cairo_rectangle_union (&extents, &surface->extents);
- rv = _cairo_quartz_setup_source_safe (surface, source, &extents);
+ rv = _cairo_quartz_setup_source_safe (surface, op, source, &extents);
if (unlikely (rv))
return rv;
- CGContextSaveGState (surface->cgContext);
-
if (surface->action == DO_SOLID || surface->action == DO_PATTERN) {
CGContextSetTextDrawingMode (surface->cgContext, kCGTextFill);
} else if (surface->action == DO_IMAGE || surface->action == DO_TILED_IMAGE || surface->action == DO_SHADING) {
@@ -2488,8 +2463,6 @@ BAIL:
if (didForceFontSmoothing)
CGContextSetAllowsFontSmoothingPtr (surface->cgContext, FALSE);
- CGContextRestoreGState (surface->cgContext);
-
if (rv == CAIRO_STATUS_SUCCESS &&
cgfref &&
!_cairo_operator_bounded_by_mask (op))