diff options
Diffstat (limited to 'gfx/cairo/quartz-cglayers.patch')
-rw-r--r-- | gfx/cairo/quartz-cglayers.patch | 715 |
1 files changed, 0 insertions, 715 deletions
diff --git a/gfx/cairo/quartz-cglayers.patch b/gfx/cairo/quartz-cglayers.patch deleted file mode 100644 index bb3d44d9e1..0000000000 --- a/gfx/cairo/quartz-cglayers.patch +++ /dev/null @@ -1,715 +0,0 @@ -changeset: 42959:e1964291f8ff -user: Robert O'Callahan <robert@ocallahan.org> -date: Tue Jun 01 11:33:23 2010 +1200 -summary: Bug 568189. Implement CGLayer-backed cairo-quartz surfaces. r=jrmuizel - -diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h ---- a/gfx/cairo/cairo/src/cairo-quartz-private.h -+++ b/gfx/cairo/cairo/src/cairo-quartz-private.h -@@ -57,16 +57,21 @@ typedef struct cairo_quartz_surface { - - /** - * If non-null, this is a CGImage representing the contents of the surface. - * We clear this out before any painting into the surface, so that we - * don't force a copy to be created. - */ - CGImageRef bitmapContextImage; - -+ /** -+ * If non-null, this is the CGLayer for the surface. -+ */ -+ CGLayerRef cgLayer; -+ - cairo_rectangle_int_t extents; - } cairo_quartz_surface_t; - - typedef struct cairo_quartz_image_surface { - cairo_surface_t base; - - cairo_rectangle_int_t extents; - -diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c ---- a/gfx/cairo/cairo/src/cairo-quartz-surface.c -+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c -@@ -1110,18 +1110,17 @@ CreateRepeatingRadialGradientFunction (c - static void - DataProviderReleaseCallback (void *info, const void *data, size_t size) - { - cairo_surface_t *surface = (cairo_surface_t *) info; - cairo_surface_destroy (surface); - } - - static cairo_status_t --_cairo_surface_to_cgimage (cairo_surface_t *target, -- cairo_surface_t *source, -+_cairo_surface_to_cgimage (cairo_surface_t *source, - CGImageRef *image_out) - { - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_surface_type_t stype = cairo_surface_get_type (source); - cairo_image_surface_t *isurf; - CGImageRef image; - void *image_extra; - -@@ -1267,17 +1266,17 @@ _cairo_quartz_cairo_repeating_surface_pa - return CAIRO_INT_STATUS_UNSUPPORTED; - - spattern = (cairo_surface_pattern_t *) apattern; - pat_surf = spattern->surface; - - is_bounded = _cairo_surface_get_extents (pat_surf, &extents); - assert (is_bounded); - -- status = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf, &image); -+ status = _cairo_surface_to_cgimage (pat_surf, &image); - if (status) - return status; - if (image == NULL) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - info = malloc(sizeof(SurfacePatternDrawInfo)); - if (!info) - return CAIRO_STATUS_NO_MEMORY; -@@ -1339,33 +1338,39 @@ _cairo_quartz_cairo_repeating_surface_pa - } - - typedef enum { - DO_SOLID, - DO_SHADING, - DO_PATTERN, - DO_IMAGE, - DO_TILED_IMAGE, -+ DO_LAYER, - DO_UNSUPPORTED, - DO_NOTHING - } cairo_quartz_action_t; - - /* State used during a drawing operation. */ - typedef struct { - CGContextRef context; - cairo_quartz_action_t action; - -- // Used with DO_SHADING, DO_IMAGE and DO_TILED_IMAGE -+ // Used with DO_SHADING, DO_IMAGE, DO_TILED_IMAGE and DO_LAYER - CGAffineTransform transform; - - // Used with DO_IMAGE and DO_TILED_IMAGE - CGImageRef image; - cairo_surface_t *imageSurface; -+ -+ // Used with DO_IMAGE, DO_TILED_IMAGE and DO_LAYER - CGRect imageRect; - -+ // Used with DO_LAYER -+ CGLayerRef layer; -+ - // Used with DO_SHADING - CGShadingRef shading; - - // Used with DO_PATTERN - CGPatternRef pattern; - } cairo_quartz_drawing_state_t; - - static void -@@ -1423,17 +1428,17 @@ _cairo_quartz_setup_fallback_source (cai - _cairo_pattern_transform (&pattern.base, - &fallback->device_transform_inverse); - status = _cairo_surface_paint (fallback, - CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); - } - #endif - -- status = _cairo_surface_to_cgimage (&surface->base, fallback, &img); -+ status = _cairo_surface_to_cgimage (fallback, &img); - if (status) { - state->action = DO_UNSUPPORTED; - return; - } - if (img == NULL) { - state->action = DO_NOTHING; - return; - } -@@ -1624,16 +1629,17 @@ _cairo_quartz_setup_state (cairo_quartz_ - { - CGContextRef context = surface->cgContext; - cairo_quartz_drawing_state_t state; - cairo_status_t status; - - state.context = context; - state.image = NULL; - state.imageSurface = NULL; -+ state.layer = NULL; - state.shading = NULL; - state.pattern = NULL; - - _cairo_quartz_surface_will_change (surface); - - // 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) -@@ -1689,33 +1695,43 @@ _cairo_quartz_setup_state (cairo_quartz_ - CGImageRef img; - cairo_matrix_t m = spat->base.matrix; - cairo_rectangle_int_t extents; - CGAffineTransform xform; - CGRect srcRect; - cairo_fixed_t fw, fh; - cairo_bool_t is_bounded; - -- status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img); -+ cairo_matrix_invert(&m); -+ _cairo_quartz_cairo_matrix_to_quartz (&m, &state.transform); -+ -+ if (cairo_surface_get_type (pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { -+ cairo_quartz_surface_t *quartz_surf = (cairo_quartz_surface_t *) pat_surf; -+ if (quartz_surf->cgLayer && source->extend == CAIRO_EXTEND_NONE) { -+ state.imageRect = CGRectMake (0, 0, quartz_surf->extents.width, quartz_surf->extents.height); -+ state.layer = quartz_surf->cgLayer; -+ state.action = DO_LAYER; -+ return state; -+ } -+ } -+ -+ status = _cairo_surface_to_cgimage (pat_surf, &img); - if (status) { - state.action = DO_UNSUPPORTED; - return state; - } - if (img == NULL) { - state.action = DO_NOTHING; - return state; - } - - CGContextSetRGBFillColor (surface->cgContext, 0, 0, 0, 1); - - state.image = img; - -- cairo_matrix_invert(&m); -- _cairo_quartz_cairo_matrix_to_quartz (&m, &state.transform); -- - is_bounded = _cairo_surface_get_extents (pat_surf, &extents); - assert (is_bounded); - - if (source->extend == CAIRO_EXTEND_NONE) { - state.imageRect = CGRectMake (0, 0, extents.width, extents.height); - state.action = DO_IMAGE; - return state; - } -@@ -1820,33 +1836,48 @@ _cairo_quartz_teardown_state (cairo_quar - - CGContextRestoreGState(state->context); - } - - - static void - _cairo_quartz_draw_image (cairo_quartz_drawing_state_t *state, cairo_operator_t op) - { -- assert (state && state->image && (state->action == DO_IMAGE || state->action == DO_TILED_IMAGE)); -+ assert (state && -+ ((state->image && (state->action == DO_IMAGE || state->action == DO_TILED_IMAGE)) || -+ (state->layer && state->action == DO_LAYER))); - - CGContextConcatCTM (state->context, state->transform); - CGContextTranslateCTM (state->context, 0, state->imageRect.size.height); - CGContextScaleCTM (state->context, 1, -1); - -- if (state->action == DO_IMAGE) { -- CGContextDrawImage (state->context, state->imageRect, state->image); -+ if (state->action == DO_TILED_IMAGE) { -+ CGContextDrawTiledImagePtr (state->context, state->imageRect, state->image); -+ /* no need to worry about unbounded operators, since tiled images -+ fill the entire clip region */ -+ } else { -+ if (state->action == DO_LAYER) { -+ /* Note that according to Apple docs it's completely legal -+ * to draw a CGLayer to any CGContext, even one it wasn't -+ * created for. -+ */ -+ CGContextDrawLayerAtPoint (state->context, state->imageRect.origin, -+ state->layer); -+ } else { -+ CGContextDrawImage (state->context, state->imageRect, state->image); -+ } -+ - if (!_cairo_operator_bounded_by_source (op)) { - CGContextBeginPath (state->context); - CGContextAddRect (state->context, state->imageRect); - CGContextAddRect (state->context, CGContextGetClipBoundingBox (state->context)); - CGContextSetRGBFillColor (state->context, 0, 0, 0, 0); - CGContextEOFillPath (state->context); - } -- } else -- CGContextDrawTiledImagePtr (state->context, state->imageRect, state->image); -+ } - } - - - /* - * get source/dest image implementation - */ - - /* Read the image from the surface's front buffer */ -@@ -1971,95 +2002,153 @@ _cairo_quartz_surface_finish (void *abst - surface->imageSurfaceEquiv = NULL; - } - - if (surface->imageData) { - free (surface->imageData); - surface->imageData = NULL; - } - -+ if (surface->cgLayer) { -+ CGLayerRelease (surface->cgLayer); -+ } -+ - return CAIRO_STATUS_SUCCESS; - } - - static cairo_status_t --_cairo_quartz_surface_acquire_source_image (void *abstract_surface, -- cairo_image_surface_t **image_out, -- void **image_extra) -+_cairo_quartz_surface_acquire_image (void *abstract_surface, -+ cairo_image_surface_t **image_out, -+ void **image_extra) - { - cairo_int_status_t status; - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - -- //ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface)); -+ *image_extra = NULL; -+ -+ /* ND((stderr, "%p _cairo_quartz_surface_acquire_image\n", surface)); */ - - status = _cairo_quartz_get_image (surface, image_out); -+ -+ if (status == CAIRO_INT_STATUS_UNSUPPORTED && surface->cgLayer) { -+ /* copy the layer into a Quartz bitmap context so we can get the data */ -+ cairo_surface_t *tmp = -+ cairo_quartz_surface_create (CAIRO_CONTENT_COLOR_ALPHA, -+ surface->extents.width, -+ surface->extents.height); -+ cairo_quartz_surface_t *tmp_surface = (cairo_quartz_surface_t *) tmp; -+ -+ /* if surface creation failed, we won't have a Quartz surface here */ -+ if (cairo_surface_get_type (tmp) == CAIRO_SURFACE_TYPE_QUARTZ && -+ tmp_surface->imageSurfaceEquiv) { -+ CGContextSaveGState (tmp_surface->cgContext); -+ CGContextTranslateCTM (tmp_surface->cgContext, 0, surface->extents.height); -+ CGContextScaleCTM (tmp_surface->cgContext, 1, -1); -+ /* Note that according to Apple docs it's completely legal -+ * to draw a CGLayer to any CGContext, even one it wasn't -+ * created for. -+ */ -+ CGContextDrawLayerAtPoint (tmp_surface->cgContext, -+ CGPointMake (0.0, 0.0), -+ surface->cgLayer); -+ CGContextRestoreGState (tmp_surface->cgContext); -+ -+ *image_out = (cairo_image_surface_t*) -+ cairo_surface_reference(tmp_surface->imageSurfaceEquiv); -+ *image_extra = tmp; -+ } else { -+ cairo_surface_destroy (tmp); -+ } -+ } -+ - if (status) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - -- *image_extra = NULL; -- - return CAIRO_STATUS_SUCCESS; - } - - static void - _cairo_quartz_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) - { - cairo_surface_destroy ((cairo_surface_t *) image); -+ -+ if (image_extra) { -+ cairo_surface_destroy ((cairo_surface_t *) image_extra); -+ } - } - - - static cairo_status_t - _cairo_quartz_surface_acquire_dest_image (void *abstract_surface, - cairo_rectangle_int_t *interest_rect, - cairo_image_surface_t **image_out, - cairo_rectangle_int_t *image_rect, - void **image_extra) - { - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; -- cairo_int_status_t status; - - ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface)); - -- _cairo_quartz_surface_will_change (surface); -- -- status = _cairo_quartz_get_image (surface, image_out); -- if (status) -- return _cairo_error (CAIRO_STATUS_NO_MEMORY); -- - *image_rect = surface->extents; - *image_extra = NULL; - -- return CAIRO_STATUS_SUCCESS; -+ _cairo_quartz_surface_will_change (surface); -+ -+ return _cairo_quartz_surface_acquire_image (abstract_surface, -+ image_out, image_extra); - } - - static void - _cairo_quartz_surface_release_dest_image (void *abstract_surface, - cairo_rectangle_int_t *interest_rect, - cairo_image_surface_t *image, - cairo_rectangle_int_t *image_rect, - void *image_extra) - { -- //cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; -- -- //ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface)); -+ /* ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface)); */ - - cairo_surface_destroy ((cairo_surface_t *) image); -+ -+ if (image_extra) { -+ /* we need to write the data from the temp surface back to the layer */ -+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; -+ cairo_quartz_surface_t *tmp_surface = (cairo_quartz_surface_t *) image_extra; -+ CGImageRef img; -+ cairo_status_t status = _cairo_surface_to_cgimage (&tmp_surface->base, &img); -+ if (status) { -+ cairo_surface_destroy (&tmp_surface->base); -+ return; -+ } -+ -+ CGContextSaveGState (surface->cgContext); -+ CGContextTranslateCTM (surface->cgContext, 0, surface->extents.height); -+ CGContextScaleCTM (surface->cgContext, 1, -1); -+ CGContextDrawImage (surface->cgContext, -+ CGRectMake (0.0, 0.0, surface->extents.width, surface->extents.height), -+ img); -+ CGContextRestoreGState (surface->cgContext); -+ -+ cairo_surface_destroy (&tmp_surface->base); -+ } - } - - static cairo_surface_t * - _cairo_quartz_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) - { -- /*cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;*/ -- -+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - cairo_format_t format; - -+ if (surface->cgLayer) -+ return cairo_quartz_surface_create_cg_layer (abstract_surface, width, height); -+ - if (content == CAIRO_CONTENT_COLOR_ALPHA) - format = CAIRO_FORMAT_ARGB32; - else if (content == CAIRO_CONTENT_COLOR) - format = CAIRO_FORMAT_RGB24; - else if (content == CAIRO_CONTENT_ALPHA) - format = CAIRO_FORMAT_A8; - else - return NULL; -@@ -2113,17 +2202,17 @@ _cairo_quartz_surface_clone_similar (voi - _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, - qsurf->extents.width, qsurf->extents.height); - *clone_offset_x = 0; - *clone_offset_y = 0; - return CAIRO_STATUS_SUCCESS; - } - } - -- status = _cairo_surface_to_cgimage ((cairo_surface_t*) abstract_surface, src, &quartz_image); -+ status = _cairo_surface_to_cgimage (src, &quartz_image); - if (status) - return CAIRO_INT_STATUS_UNSUPPORTED; - - new_format = CAIRO_FORMAT_ARGB32; /* assumed */ - if (_cairo_surface_is_image (src)) { - new_format = ((cairo_image_surface_t *) src)->format; - } - -@@ -2194,17 +2283,18 @@ _cairo_quartz_surface_paint (void *abstr - if (state.action == DO_SOLID || state.action == DO_PATTERN) { - CGContextFillRect (state.context, CGRectMake(surface->extents.x, - surface->extents.y, - surface->extents.width, - surface->extents.height)); - } else if (state.action == DO_SHADING) { - CGContextConcatCTM (state.context, state.transform); - CGContextDrawShading (state.context, state.shading); -- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) { -+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || -+ state.action == DO_LAYER) { - _cairo_quartz_draw_image (&state, op); - } else if (state.action != DO_NOTHING) { - rv = CAIRO_INT_STATUS_UNSUPPORTED; - } - - _cairo_quartz_teardown_state (&state); - - ND((stderr, "-- paint\n")); -@@ -2291,17 +2381,18 @@ _cairo_quartz_surface_fill (void *abstra - // with the shading - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (state.context); - else - CGContextEOClip (state.context); - - CGContextConcatCTM (state.context, state.transform); - CGContextDrawShading (state.context, state.shading); -- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) { -+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || -+ state.action == DO_LAYER) { - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (state.context); - else - CGContextEOClip (state.context); - - _cairo_quartz_draw_image (&state, op); - } else if (state.action != DO_NOTHING) { - rv = CAIRO_INT_STATUS_UNSUPPORTED; -@@ -2416,17 +2507,18 @@ _cairo_quartz_surface_stroke (void *abst - if (rv) - goto BAIL; - - if (!_cairo_operator_bounded_by_mask (op) && CGContextCopyPathPtr) - path_for_unbounded = CGContextCopyPathPtr (state.context); - - if (state.action == DO_SOLID || state.action == DO_PATTERN) { - CGContextStrokePath (state.context); -- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) { -+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || -+ state.action == DO_LAYER) { - CGContextReplacePathWithStrokedPath (state.context); - CGContextClip (state.context); - - CGContextSetCTM (state.context, origCTM); - _cairo_quartz_draw_image (&state, op); - } else if (state.action == DO_SHADING) { - CGContextReplacePathWithStrokedPath (state.context); - CGContextClip (state.context); -@@ -2511,17 +2603,18 @@ _cairo_quartz_surface_show_glyphs (void - &glyph_extents, NULL); - state = _cairo_quartz_setup_state (surface, source, op, &glyph_extents); - } else { - state = _cairo_quartz_setup_state (surface, source, op, NULL); - } - - if (state.action == DO_SOLID || state.action == DO_PATTERN) { - CGContextSetTextDrawingMode (state.context, kCGTextFill); -- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || state.action == DO_SHADING) { -+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || -+ state.action == DO_SHADING || state.action == DO_LAYER) { - CGContextSetTextDrawingMode (state.context, kCGTextClip); - isClipping = TRUE; - } else { - if (state.action != DO_NOTHING) - rv = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } - -@@ -2622,17 +2715,18 @@ _cairo_quartz_surface_show_glyphs (void - - CGContextShowGlyphsWithAdvances (state.context, - cg_glyphs, - cg_advances, - num_glyphs); - - CGContextSetCTM (state.context, ctm); - -- if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) { -+ if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || -+ state.action == DO_LAYER) { - _cairo_quartz_draw_image (&state, op); - } else if (state.action == DO_SHADING) { - CGContextConcatCTM (state.context, state.transform); - CGContextDrawShading (state.context, state.shading); - } - - BAIL: - if (didForceFontSmoothing) -@@ -2679,17 +2773,17 @@ _cairo_quartz_surface_mask_with_surface - cairo_clip_t *clip) - { - CGRect rect; - CGImageRef img; - cairo_surface_t *pat_surf = mask->surface; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - CGAffineTransform ctm, mask_matrix; - -- status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img); -+ status = _cairo_surface_to_cgimage (pat_surf, &img); - if (status) - return status; - if (img == NULL) { - if (!_cairo_operator_bounded_by_mask (op)) - CGContextClearRect (surface->cgContext, CGContextGetClipBoundingBox (surface->cgContext)); - return CAIRO_STATUS_SUCCESS; - } - -@@ -2869,17 +2963,17 @@ _cairo_quartz_surface_clipper_intersect_ - } - - // XXXtodo implement show_page; need to figure out how to handle begin/end - - static const struct _cairo_surface_backend cairo_quartz_surface_backend = { - CAIRO_SURFACE_TYPE_QUARTZ, - _cairo_quartz_surface_create_similar, - _cairo_quartz_surface_finish, -- _cairo_quartz_surface_acquire_source_image, -+ _cairo_quartz_surface_acquire_image, - _cairo_quartz_surface_release_source_image, - _cairo_quartz_surface_acquire_dest_image, - _cairo_quartz_surface_release_dest_image, - _cairo_quartz_surface_clone_similar, - NULL, /* composite */ - NULL, /* fill_rectangles */ - NULL, /* composite_trapezoids */ - NULL, /* create_span_renderer */ -@@ -2950,16 +3044,17 @@ _cairo_quartz_surface_create_internal (C - CGContextSaveGState (cgContext); - - surface->cgContext = cgContext; - surface->cgContextBaseCTM = CGContextGetCTM (cgContext); - - surface->imageData = NULL; - surface->imageSurfaceEquiv = NULL; - surface->bitmapContextImage = NULL; -+ surface->cgLayer = NULL; - - return surface; - } - - /** - * cairo_quartz_surface_create_for_cg_context - * @cgContext: the existing CGContext for which to create the surface - * @width: width of the surface, in pixels -@@ -3002,16 +3097,88 @@ cairo_quartz_surface_create_for_cg_conte - // create_internal will have set an error - return (cairo_surface_t*) surf; - } - - return (cairo_surface_t *) surf; - } - - /** -+ * cairo_quartz_cglayer_surface_create_similar -+ * @surface: The returned surface can be efficiently drawn into this -+ * destination surface (if tiling is not used)." -+ * @width: width of the surface, in pixels -+ * @height: height of the surface, in pixels -+ * -+ * Creates a Quartz surface backed by a CGLayer, if the given surface -+ * is a Quartz surface; the CGLayer is created to match the surface's -+ * Quartz context. Otherwise just calls cairo_surface_create_similar -+ * with CAIRO_CONTENT_COLOR_ALPHA. -+ * The returned surface can be efficiently blitted to the given surface, -+ * but tiling and 'extend' modes other than NONE are not so efficient. -+ * -+ * Return value: the newly created surface. -+ * -+ * Since: 1.10 -+ **/ -+cairo_surface_t * -+cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface, -+ unsigned int width, -+ unsigned int height) -+{ -+ cairo_quartz_surface_t *surf; -+ CGLayerRef layer; -+ CGContextRef ctx; -+ CGContextRef cgContext; -+ -+ cgContext = cairo_quartz_surface_get_cg_context (surface); -+ if (!cgContext) -+ return cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA, -+ width, height); -+ -+ if (!_cairo_quartz_verify_surface_size(width, height)) -+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); -+ -+ /* If we pass zero width or height into CGLayerCreateWithContext below, -+ * it will fail. -+ */ -+ if (width == 0 || height == 0) { -+ return (cairo_surface_t*) -+ _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, -+ width, height); -+ } -+ -+ layer = CGLayerCreateWithContext (cgContext, -+ CGSizeMake (width, height), -+ NULL); -+ if (!layer) -+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); -+ -+ ctx = CGLayerGetContext (layer); -+ /* Flip it when we draw into it, so that when we finally composite it -+ * to a flipped target, the directions match and Quartz will optimize -+ * the composition properly -+ */ -+ CGContextTranslateCTM (ctx, 0, height); -+ CGContextScaleCTM (ctx, 1, -1); -+ -+ CGContextRetain (ctx); -+ surf = _cairo_quartz_surface_create_internal (ctx, CAIRO_CONTENT_COLOR_ALPHA, -+ width, height); -+ if (surf->base.status) { -+ CGLayerRelease (layer); -+ // create_internal will have set an error -+ return (cairo_surface_t*) surf; -+ } -+ surf->cgLayer = layer; -+ -+ return (cairo_surface_t *) surf; -+} -+ -+/** - * cairo_quartz_surface_create - * @format: format of pixels in the surface to create - * @width: width of the surface, in pixels - * @height: height of the surface, in pixels - * - * Creates a Quartz surface backed by a CGBitmap. The surface is - * created using the Device RGB (or Device Gray, for A8) color space. - * All Cairo operations, including those that require software -diff --git a/gfx/cairo/cairo/src/cairo-quartz.h b/gfx/cairo/cairo/src/cairo-quartz.h ---- a/gfx/cairo/cairo/src/cairo-quartz.h -+++ b/gfx/cairo/cairo/src/cairo-quartz.h -@@ -45,16 +45,21 @@ - CAIRO_BEGIN_DECLS - - cairo_public cairo_surface_t * - cairo_quartz_surface_create (cairo_format_t format, - unsigned int width, - unsigned int height); - - cairo_public cairo_surface_t * -+cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface, -+ unsigned int width, -+ unsigned int height); -+ -+cairo_public cairo_surface_t * - cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext, - unsigned int width, - unsigned int height); - - cairo_public CGContextRef - cairo_quartz_surface_get_cg_context (cairo_surface_t *surface); - - cairo_public CGContextRef - |