diff options
author | Andrea Canciani <ranma42@gmail.com> | 2010-07-28 19:03:13 +0200 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-10-13 00:27:01 +0200 |
commit | c22e75e9f6cb471c764af0d721ad07cdf30a3bad (patch) | |
tree | 72b761015fdb13fa2b38173054612eb6eba55397 | |
parent | 6bc1376cf52a9815b75f8c0ce66e149fbc64495e (diff) | |
download | cairo-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.h | 2 | ||||
-rw-r--r-- | src/cairo-quartz-surface.c | 69 |
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)) |