From 9cbf80703d1b36be068e68eb0bf65981c94c78b7 Mon Sep 17 00:00:00 2001 From: "vladimir%pobox.com" Date: Wed, 5 Mar 2008 05:45:09 +0000 Subject: [PATCH] b=421017; upgrade cairo to 1.5.12-14-gd89edde -- additional fixes ; r=me git-svn-id: svn://10.0.0.236/trunk@247072 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/cairo/README | 2 +- mozilla/gfx/cairo/buggy-repeat.patch | 21 +- .../cairo/cairo/src/cairo-compiler-private.h | 2 +- .../gfx/cairo/cairo/src/cairo-features.h.in | 4 +- mozilla/gfx/cairo/cairo/src/cairo-ft-font.c | 10 +- .../gfx/cairo/cairo/src/cairo-meta-surface.c | 24 +- .../cairo/cairo/src/cairo-quartz-surface.c | 2 +- .../gfx/cairo/cairo/src/cairo-win32-private.h | 2 +- .../gfx/cairo/cairo/src/cairo-xlib-display.c | 13 + mozilla/gfx/cairo/cairo/src/cairoint.h | 7 + mozilla/gfx/cairo/max-font-size.patch | 40 +- mozilla/gfx/cairo/quartz-image-surface.patch | 729 ------------------ 12 files changed, 84 insertions(+), 772 deletions(-) delete mode 100644 mozilla/gfx/cairo/quartz-image-surface.patch diff --git a/mozilla/gfx/cairo/README b/mozilla/gfx/cairo/README index a5438879e57..9d99d2862bc 100644 --- a/mozilla/gfx/cairo/README +++ b/mozilla/gfx/cairo/README @@ -7,7 +7,7 @@ http://www.cairographics.org/. VERSIONS: - cairo (1.5.x - 1.5.12-11-g2f93504) + cairo (1.5.x - 1.5.12-14-gd89edde) pixman (0.9.x - pixman-0.9.6-37-g8d79c48) glitz 0.5.2 (cvs - 2006-01-10) diff --git a/mozilla/gfx/cairo/buggy-repeat.patch b/mozilla/gfx/cairo/buggy-repeat.patch index 947a2daf62d..ca53a3f60a5 100644 --- a/mozilla/gfx/cairo/buggy-repeat.patch +++ b/mozilla/gfx/cairo/buggy-repeat.patch @@ -1,12 +1,29 @@ diff --git a/gfx/cairo/cairo/src/cairo-xlib-display.c b/gfx/cairo/cairo/src/cairo-xlib-display.c --- a/gfx/cairo/cairo/src/cairo-xlib-display.c +++ b/gfx/cairo/cairo/src/cairo-xlib-display.c -@@ -302,6 +302,9 @@ _cairo_xlib_display_get (Display *dpy) +@@ -63,6 +63,8 @@ struct _cairo_xlib_job { + }; + + static cairo_xlib_display_t *_cairo_xlib_display_list; ++ ++static int buggy_repeat_force = -1; + + static void + _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display) +@@ -302,6 +304,17 @@ _cairo_xlib_display_get (Display *dpy) display->buggy_repeat = TRUE; } + /* XXX workaround; see https://bugzilla.mozilla.org/show_bug.cgi?id=413583 */ -+ display->buggy_repeat = TRUE; ++ if (buggy_repeat_force == -1) { ++ if (getenv("MOZ_CAIRO_NO_BUGGY_REPEAT")) ++ buggy_repeat_force = 0; ++ else ++ buggy_repeat_force = 1; ++ } ++ ++ if (buggy_repeat_force) ++ display->buggy_repeat = TRUE; + display->next = _cairo_xlib_display_list; _cairo_xlib_display_list = display; diff --git a/mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h b/mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h index 99659495b3f..06d3bfdaa16 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h +++ b/mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h @@ -111,7 +111,7 @@ CAIRO_BEGIN_DECLS #define __attribute__(x) #endif -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(_MSC_VER) #define snprintf _snprintf #endif diff --git a/mozilla/gfx/cairo/cairo/src/cairo-features.h.in b/mozilla/gfx/cairo/cairo/src/cairo-features.h.in index 230ffadf3c5..a7e15c98fbf 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-features.h.in +++ b/mozilla/gfx/cairo/cairo/src/cairo-features.h.in @@ -53,9 +53,9 @@ #define CAIRO_VERSION_MAJOR 1 #define CAIRO_VERSION_MINOR 5 -#define CAIRO_VERSION_MICRO 5 +#define CAIRO_VERSION_MICRO 12 -#define CAIRO_VERSION_STRING "1.5.5" +#define CAIRO_VERSION_STRING "1.5.12" @PS_SURFACE_FEATURE@ diff --git a/mozilla/gfx/cairo/cairo/src/cairo-ft-font.c b/mozilla/gfx/cairo/cairo/src/cairo-ft-font.c index 85ebce58029..9c52c2ace14 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-ft-font.c +++ b/mozilla/gfx/cairo/cairo/src/cairo-ft-font.c @@ -64,6 +64,10 @@ */ #define MAX_OPEN_FACES 10 +/* This is the maximum font size we allow to be passed to FT_Set_Char_Size + */ +#define MAX_FONT_SIZE 1000 + /* * The simple 2x2 matrix is converted into separate scale and shape * factors so that hinting works right @@ -682,9 +686,11 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, FT_Set_Transform(unscaled->face, &mat, NULL); if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) { + double x_scale = MIN(sf.x_scale, MAX_FONT_SIZE); + double y_scale = MIN(sf.y_scale, MAX_FONT_SIZE); error = FT_Set_Char_Size (unscaled->face, - sf.x_scale * 64.0 + .5, - sf.y_scale * 64.0 + .5, + x_scale * 64.0 + .5, + y_scale * 64.0 + .5, 0, 0); if (error) return _cairo_error (CAIRO_STATUS_NO_MEMORY); diff --git a/mozilla/gfx/cairo/cairo/src/cairo-meta-surface.c b/mozilla/gfx/cairo/cairo/src/cairo-meta-surface.c index 52489475b08..66849b484de 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-meta-surface.c +++ b/mozilla/gfx/cairo/cairo/src/cairo-meta-surface.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ /* cairo - a vector graphics library with display and print output * * Copyright © 2005 Red Hat, Inc @@ -803,21 +804,28 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, case CAIRO_COMMAND_SHOW_GLYPHS: { cairo_glyph_t *glyphs = command->show_glyphs.glyphs; - cairo_glyph_t *dev_glyphs = glyphs; + cairo_glyph_t *dev_glyphs; int i, num_glyphs = command->show_glyphs.num_glyphs; + /* show_glyphs is special because _cairo_surface_show_glyphs is allowed + * to modify the glyph array that's passed in. We must always + * copy the array before handing it to the backend. + */ + dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); + if (dev_glyphs == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + break; + } + if (has_device_transform) { - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (dev_glyphs == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - break; - } for (i = 0; i < num_glyphs; i++) { dev_glyphs[i] = glyphs[i]; cairo_matrix_transform_point (device_transform, &dev_glyphs[i].x, &dev_glyphs[i].y); } + } else { + memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); } status = _cairo_surface_show_glyphs (target, @@ -826,9 +834,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, dev_glyphs, num_glyphs, command->show_glyphs.scaled_font); - if (dev_glyphs != glyphs) - free (dev_glyphs); - + free (dev_glyphs); break; } case CAIRO_COMMAND_INTERSECT_CLIP_PATH: diff --git a/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c b/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c index e39ba56be4d..f26cc51ad3c 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c +++ b/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c @@ -146,7 +146,7 @@ _cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc) { } /* This will cause a (harmless) warning to be printed if called on a non-bitmap context */ - return CGBitmapContextGetBitsPerPixel(surface->cgContext) != 0; + return CGBitmapContextGetBitsPerPixel(cgc) != 0; } /* CoreGraphics limitation with flipped CTM surfaces: height must be less than signed 16-bit max */ diff --git a/mozilla/gfx/cairo/cairo/src/cairo-win32-private.h b/mozilla/gfx/cairo/cairo/src/cairo-win32-private.h index 704ec4ed43d..be01ec61039 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-win32-private.h +++ b/mozilla/gfx/cairo/cairo/src/cairo-win32-private.h @@ -46,7 +46,7 @@ #define SB_NONE 0 #endif -#define WIN32_FONT_LOGICAL_SCALE 32 +#define WIN32_FONT_LOGICAL_SCALE 1 typedef struct _cairo_win32_surface { cairo_surface_t base; diff --git a/mozilla/gfx/cairo/cairo/src/cairo-xlib-display.c b/mozilla/gfx/cairo/cairo/src/cairo-xlib-display.c index d10ed1e0b96..13fd7c7a51e 100644 --- a/mozilla/gfx/cairo/cairo/src/cairo-xlib-display.c +++ b/mozilla/gfx/cairo/cairo/src/cairo-xlib-display.c @@ -64,6 +64,8 @@ struct _cairo_xlib_job { static cairo_xlib_display_t *_cairo_xlib_display_list; +static int buggy_repeat_force = -1; + static void _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display) { @@ -302,6 +304,17 @@ _cairo_xlib_display_get (Display *dpy) display->buggy_repeat = TRUE; } + /* XXX workaround; see https://bugzilla.mozilla.org/show_bug.cgi?id=413583 */ + if (buggy_repeat_force == -1) { + if (getenv("MOZ_CAIRO_NO_BUGGY_REPEAT")) + buggy_repeat_force = 0; + else + buggy_repeat_force = 1; + } + + if (buggy_repeat_force) + display->buggy_repeat = TRUE; + display->next = _cairo_xlib_display_list; _cairo_xlib_display_list = display; diff --git a/mozilla/gfx/cairo/cairo/src/cairoint.h b/mozilla/gfx/cairo/cairo/src/cairoint.h index 773daf6d4c0..829288eb699 100644 --- a/mozilla/gfx/cairo/cairo/src/cairoint.h +++ b/mozilla/gfx/cairo/cairo/src/cairoint.h @@ -94,6 +94,13 @@ _cairo_win32_tmpfile (void); #define M_PI 3.14159265358979323846 #endif +#ifndef NDEBUG +#undef assert +#define assert(expr) \ + do { if (!(expr)) fprintf(stderr, "Assertion failed at %s:%d: %s\n", \ + __FILE__, __LINE__, #expr); } while (0) +#endif + #ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880 #endif diff --git a/mozilla/gfx/cairo/max-font-size.patch b/mozilla/gfx/cairo/max-font-size.patch index 46566840732..99be23906ab 100644 --- a/mozilla/gfx/cairo/max-font-size.patch +++ b/mozilla/gfx/cairo/max-font-size.patch @@ -1,36 +1,28 @@ -diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c -index 59a5acb..8851387 100644 ---- a/cairo/src/cairo-ft-font.c -+++ b/cairo/src/cairo-ft-font.c -@@ -62,6 +62,10 @@ +diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c +--- a/gfx/cairo/cairo/src/cairo-ft-font.c ++++ b/gfx/cairo/cairo/src/cairo-ft-font.c +@@ -63,6 +63,10 @@ + /* This is the max number of FT_face objects we keep open at once */ #define MAX_OPEN_FACES 10 - ++ +/* This is the maximum font size we allow to be passed to FT_Set_Char_Size + */ +#define MAX_FONT_SIZE 1000 -+ + /* * The simple 2x2 matrix is converted into separate scale and shape - * factors so that hinting works right -@@ -643,9 +647,18 @@ _cairo_ft_unscaled_font_set_scale (cairo +@@ -682,9 +686,11 @@ _cairo_ft_unscaled_font_set_scale (cairo FT_Set_Transform(unscaled->face, &mat, NULL); if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) { -+ double x_scale = sf.x_scale; -+ double y_scale = sf.y_scale; -+ if (x_scale > MAX_FONT_SIZE) { -+ x_scale = MAX_FONT_SIZE; -+ } -+ if (y_scale > MAX_FONT_SIZE) { -+ y_scale = MAX_FONT_SIZE; -+ } -+ ++ double x_scale = MIN(sf.x_scale, MAX_FONT_SIZE); ++ double y_scale = MIN(sf.y_scale, MAX_FONT_SIZE); error = FT_Set_Char_Size (unscaled->face, -- sf.x_scale * 64.0, -- sf.y_scale * 64.0, -+ x_scale * 64.0, -+ y_scale * 64.0, +- sf.x_scale * 64.0 + .5, +- sf.y_scale * 64.0 + .5, ++ x_scale * 64.0 + .5, ++ y_scale * 64.0 + .5, 0, 0); - assert (error == 0); - } else { + if (error) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); diff --git a/mozilla/gfx/cairo/quartz-image-surface.patch b/mozilla/gfx/cairo/quartz-image-surface.patch deleted file mode 100644 index 5dcb07ed8b5..00000000000 --- a/mozilla/gfx/cairo/quartz-image-surface.patch +++ /dev/null @@ -1,729 +0,0 @@ -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 -@@ -46,12 +46,11 @@ typedef struct cairo_quartz_surface { - typedef struct cairo_quartz_surface { - cairo_surface_t base; - -- void *imageData; -- -- cairo_surface_t *imageSurfaceEquiv; -- - CGContextRef cgContext; - CGAffineTransform cgContextBaseCTM; -+ -+ void *imageData; -+ cairo_surface_t *imageSurfaceEquiv; - - cairo_rectangle_int_t extents; - -@@ -66,6 +65,30 @@ typedef struct cairo_quartz_surface { - CGShadingRef sourceShading; - CGPatternRef sourcePattern; - } cairo_quartz_surface_t; -+ -+typedef struct cairo_quartz_image_surface { -+ cairo_surface_t base; -+ -+ cairo_rectangle_int_t extents; -+ -+ CGImageRef image; -+ cairo_image_surface_t *imageSurface; -+} cairo_quartz_image_surface_t; -+ -+cairo_bool_t -+_cairo_quartz_verify_surface_size(int width, int height); -+ -+CGImageRef -+_cairo_quartz_create_cgimage (cairo_format_t format, -+ unsigned int width, -+ unsigned int height, -+ unsigned int stride, -+ void *data, -+ cairo_bool_t interpolate, -+ CGColorSpaceRef colorSpaceOverride, -+ CGDataProviderReleaseDataCallback releaseCallback, -+ void *releaseInfo); -+ - #endif /* CAIRO_HAS_QUARTZ_SURFACE */ - - #if CAIRO_HAS_ATSUI_FONT -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 -@@ -140,7 +140,8 @@ static void quartz_ensure_symbols(void) - #define CG_MAX_WIDTH USHRT_MAX - - /* is the desired size of the surface within bounds? */ --static cairo_bool_t verify_surface_size(int width, int height) -+cairo_bool_t -+_cairo_quartz_verify_surface_size(int width, int height) - { - /* hmmm, allow width, height == 0 ? */ - if (width < 0 || height < 0) { -@@ -393,114 +394,93 @@ CreateGradientFunction (cairo_gradient_p - &callbacks); - } - --/* generic cairo surface -> cairo_quartz_surface_t function */ --static cairo_int_status_t --_cairo_quartz_surface_to_quartz (cairo_surface_t *target, -- cairo_surface_t *pat_surf, -- cairo_quartz_surface_t **quartz_surf) -+/* Obtain a CGImageRef from a cairo_surface_t * */ -+ -+static CGImageRef -+_cairo_surface_to_cgimage (cairo_surface_t *target, -+ cairo_surface_t *source) - { -+ cairo_surface_type_t stype = cairo_surface_get_type (source); -+ cairo_image_surface_t *isurf; -+ CGImageRef image, image2; -+ void *image_extra; - -- if (cairo_surface_get_type(pat_surf) != CAIRO_SURFACE_TYPE_QUARTZ) { -- /* XXXtodo/perf don't use clone if the source surface is an image surface! Instead, -- * just create the CGImage directly! -- */ -- -- cairo_surface_t *ref_type = target; -- cairo_surface_t *new_surf = NULL; -- cairo_rectangle_int_t rect; -- cairo_status_t status; -- -- if (ref_type == NULL) -- ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); -- -- status = _cairo_surface_get_extents (pat_surf, &rect); -- if (status) -- return status; -- -- status = _cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y, -- rect.width, rect.height, &new_surf); -- if (target == NULL) -- cairo_surface_destroy(ref_type); -- -- if (status) -- return status; -- -- if (new_surf && -- cairo_surface_get_type (new_surf) != CAIRO_SURFACE_TYPE_QUARTZ) -- { -- ND((stderr, "got a non-quartz surface, format=%d width=%u height=%u type=%d\n", cairo_surface_get_type (pat_surf), rect.width, rect.height, cairo_surface_get_type (new_surf))); -- cairo_surface_destroy (new_surf); -- return CAIRO_INT_STATUS_UNSUPPORTED; -- } -- -- *quartz_surf = (cairo_quartz_surface_t *) new_surf; -- } else { -- /* If it's a quartz surface, we can try to see if it's a CGBitmapContext; -- * we do this when we call CGBitmapContextCreateImage below. -- */ -- cairo_surface_reference (pat_surf); -- *quartz_surf = (cairo_quartz_surface_t*) pat_surf; -+ if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) { -+ cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source; -+ return CGImageRetain (surface->image); - } - -- return CAIRO_STATUS_SUCCESS; -+ if (stype == CAIRO_SURFACE_TYPE_QUARTZ) { -+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) source; -+ image = CGBitmapContextCreateImage (surface->cgContext); -+ if (image) -+ return image; -+ } -+ -+ if (stype != CAIRO_SURFACE_TYPE_IMAGE) { -+ cairo_status_t status = -+ _cairo_surface_acquire_source_image (source, &isurf, &image_extra); -+ if (status) -+ return NULL; -+ } else { -+ isurf = (cairo_image_surface_t *) source; -+ } -+ -+ image2 = _cairo_quartz_create_cgimage (isurf->format, -+ isurf->width, -+ isurf->height, -+ isurf->stride, -+ isurf->data, -+ FALSE, -+ NULL, NULL, NULL); -+ -+ image = CGImageCreateCopy (image2); -+ CGImageRelease (image2); -+ -+ if ((cairo_surface_t*) isurf != source) -+ _cairo_surface_release_source_image (source, isurf, image_extra); -+ -+ return image; - } - - /* Generic cairo_pattern -> CGPattern function */ -+ -+typedef struct { -+ CGImageRef image; -+ CGRect imageBounds; -+ cairo_bool_t do_reflect; -+} SurfacePatternDrawInfo; -+ - static void --SurfacePatternDrawFunc (void *info, CGContextRef context) -+SurfacePatternDrawFunc (void *ainfo, CGContextRef context) - { -- cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info; -- cairo_surface_t *pat_surf = spat->surface; -- cairo_int_status_t status; -+ SurfacePatternDrawInfo *info = (SurfacePatternDrawInfo*) ainfo; - -- cairo_quartz_surface_t *quartz_surf; -- CGImageRef img; -- CGRect imageBounds; -+ CGContextTranslateCTM (context, 0, info->imageBounds.size.height); -+ CGContextScaleCTM (context, 1, -1); - -- status = _cairo_quartz_surface_to_quartz (NULL, pat_surf, &quartz_surf); -- if (status) -- return; -+ CGContextDrawImage (context, info->imageBounds, info->image); -+ if (info->do_reflect) { -+ /* draw 3 more copies of the image, flipped. */ -+ CGContextTranslateCTM (context, 0, 2 * info->imageBounds.size.height); -+ CGContextScaleCTM (context, 1, -1); -+ CGContextDrawImage (context, info->imageBounds, info->image); -+ CGContextTranslateCTM (context, 2 * info->imageBounds.size.width, 0); -+ CGContextScaleCTM (context, -1, 1); -+ CGContextDrawImage (context, info->imageBounds, info->image); -+ CGContextTranslateCTM (context, 0, 2 * info->imageBounds.size.height); -+ CGContextScaleCTM (context, 1, -1); -+ CGContextDrawImage (context, info->imageBounds, info->image); -+ } -+} - -- img = CGBitmapContextCreateImage (quartz_surf->cgContext); -- if (!img) { -- // ... give up. -- ND((stderr, "CGBitmapContextCreateImage failed\n")); -- _cairo_error (CAIRO_STATUS_NO_MEMORY); -- cairo_surface_destroy ((cairo_surface_t*)quartz_surf); -- return; -- } -+static void -+SurfacePatternReleaseInfoFunc (void *ainfo) -+{ -+ SurfacePatternDrawInfo *info = (SurfacePatternDrawInfo*) ainfo; - -- /* XXXtodo WHY does this need to be flipped? Writing this stuff -- * to disk shows that in both this path and the path above the source image -- * has an identical orientation, and the destination context at all times has a Y -- * flip. So why do we need to flip in this case? -- */ -- if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { -- CGContextTranslateCTM (context, 0, CGImageGetHeight(img)); -- CGContextScaleCTM (context, 1, -1); -- } -- -- imageBounds.size = CGSizeMake (CGImageGetWidth(img), CGImageGetHeight(img)); -- imageBounds.origin.x = 0; -- imageBounds.origin.y = 0; -- -- CGContextDrawImage (context, imageBounds, img); -- if (spat->base.extend == CAIRO_EXTEND_REFLECT) { -- /* draw 3 more copies of the image, flipped. */ -- CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height); -- CGContextScaleCTM (context, 1, -1); -- CGContextDrawImage (context, imageBounds, img); -- CGContextTranslateCTM (context, 2 * imageBounds.size.width, 0); -- CGContextScaleCTM (context, -1, 1); -- CGContextDrawImage (context, imageBounds, img); -- CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height); -- CGContextScaleCTM (context, 1, -1); -- CGContextDrawImage (context, imageBounds, img); -- } -- -- CGImageRelease (img); -- -- cairo_surface_destroy ((cairo_surface_t*) quartz_surf); -+ CGImageRelease (info->image); -+ free (info); - } - - /* Borrowed from cairo-meta-surface */ -@@ -532,48 +512,62 @@ _init_pattern_with_snapshot (cairo_patte - - static cairo_int_status_t - _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t *dest, -- cairo_pattern_t *abspat, -+ cairo_pattern_t *apattern, - CGPatternRef *cgpat) - { -- cairo_surface_pattern_t *spat; -+ cairo_surface_pattern_t *spattern; - cairo_surface_t *pat_surf; - cairo_rectangle_int_t extents; - -+ CGImageRef image; - CGRect pbounds; - CGAffineTransform ptransform, stransform; - CGPatternCallbacks cb = { 0, - SurfacePatternDrawFunc, -- (CGFunctionReleaseInfoCallback) cairo_pattern_destroy }; -+ SurfacePatternReleaseInfoFunc }; -+ SurfacePatternDrawInfo *info; - float rw, rh; - cairo_status_t status; - -- cairo_pattern_union_t *snap_pattern = NULL; -- cairo_pattern_t *target_pattern = abspat; -+ cairo_matrix_t m; - -- cairo_matrix_t m; - /* SURFACE is the only type we'll handle here */ -- if (abspat->type != CAIRO_PATTERN_TYPE_SURFACE) -+ if (apattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_INT_STATUS_UNSUPPORTED; - -- spat = (cairo_surface_pattern_t *) abspat; -- pat_surf = spat->surface; -+ spattern = (cairo_surface_pattern_t *) apattern; -+ pat_surf = spattern->surface; - - status = _cairo_surface_get_extents (pat_surf, &extents); - if (status) - return status; - -+ image = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf); -+ if (image == NULL) -+ return CAIRO_INT_STATUS_UNSUPPORTED; -+ -+ info = malloc(sizeof(SurfacePatternDrawInfo)); -+ if (!info) -+ return CAIRO_STATUS_NO_MEMORY; -+ -+ /* XXX -- if we're printing, we may need to call CGImageCreateCopy to make sure -+ * that the data will stick around for this image when the printer gets to it. -+ * Otherwise, the underlying data store may disappear from under us! -+ * -+ * _cairo_surface_to_cgimage will copy when it converts non-Quartz surfaces, -+ * since the Quartz surfaces have a higher chance of sticking around. If the -+ * source is a quartz image surface, then it's set up to retain a ref to the -+ * image surface that it's backed by. -+ */ -+ info->image = image; -+ -+ info->imageBounds = CGRectMake (0, 0, extents.width, extents.height); -+ info->do_reflect = (spattern->base.extend == CAIRO_EXTEND_REFLECT); -+ - pbounds.origin.x = 0; - pbounds.origin.y = 0; - -- // kjs seems to indicate this should work (setting to 0,0 to avoid -- // tiling); however, the pattern CTM scaling ends up being NaN in -- // the pattern draw function if either rw or rh are 0. -- // XXXtodo get pattern drawing working with extend options -- // XXXtodo/perf optimize CAIRO_EXTEND_NONE to a single DrawImage instead of a pattern -- if (spat->base.extend == CAIRO_EXTEND_REFLECT) { -- /* XXX broken; need to emulate by reflecting the image into 4 quadrants -- * and then tiling that -- */ -+ if (spattern->base.extend == CAIRO_EXTEND_REFLECT) { - pbounds.size.width = 2 * extents.width; - pbounds.size.height = 2 * extents.height; - } else { -@@ -583,7 +577,7 @@ _cairo_quartz_cairo_repeating_surface_pa - rw = pbounds.size.width; - rh = pbounds.size.height; - -- m = spat->base.matrix; -+ m = spattern->base.matrix; - cairo_matrix_invert(&m); - _cairo_quartz_cairo_matrix_to_quartz (&m, &stransform); - -@@ -601,25 +595,14 @@ _cairo_quartz_cairo_repeating_surface_pa - ND((stderr, " context xform: t: %f %f xx: %f xy: %f yx: %f yy: %f\n", xform.tx, xform.ty, xform.a, xform.b, xform.c, xform.d)); - #endif - -+ *cgpat = CGPatternCreate (info, -+ pbounds, -+ ptransform, -+ rw, rh, -+ kCGPatternTilingConstantSpacing, /* kCGPatternTilingNoDistortion, */ -+ TRUE, -+ &cb); - -- /* XXX fixme: only do snapshots if the context is for printing, or get rid of the -- other block if it doesn't fafect performance */ -- if (1 /* context is for printing */) { -- snap_pattern = (cairo_pattern_union_t*) malloc(sizeof(cairo_pattern_union_t)); -- target_pattern = (cairo_pattern_t*) snap_pattern; -- _init_pattern_with_snapshot (target_pattern, abspat); -- } else { -- cairo_pattern_reference (abspat); -- target_pattern = abspat; -- } -- -- *cgpat = CGPatternCreate (target_pattern, -- pbounds, -- ptransform, -- rw, rh, -- kCGPatternTilingConstantSpacing, /* kCGPatternTilingNoDistortion, */ -- TRUE, -- &cb); - return CAIRO_STATUS_SUCCESS; - } - -@@ -785,7 +768,6 @@ _cairo_quartz_setup_source (cairo_quartz - { - cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source; - cairo_surface_t *pat_surf = spat->surface; -- cairo_quartz_surface_t *quartz_surf; - CGImageRef img; - cairo_matrix_t m = spat->base.matrix; - cairo_rectangle_int_t extents; -@@ -794,16 +776,7 @@ _cairo_quartz_setup_source (cairo_quartz - CGRect srcRect; - cairo_fixed_t fw, fh; - -- status = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf, &quartz_surf); -- if (status) -- return DO_UNSUPPORTED; -- -- surface->sourceImageSurface = (cairo_surface_t *)quartz_surf; -- -- if (IS_EMPTY(quartz_surf)) -- return DO_NOTHING; -- -- img = CGBitmapContextCreateImage (quartz_surf->cgContext); -+ img = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf); - if (!img) - return DO_UNSUPPORTED; - -@@ -1132,7 +1105,7 @@ _cairo_quartz_surface_create_similar (vo - return NULL; - - // verify width and height of surface -- if (!verify_surface_size(width, height)) { -+ if (!_cairo_quartz_verify_surface_size(width, height)) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return NULL; - } -@@ -1142,12 +1115,12 @@ _cairo_quartz_surface_create_similar (vo - - static cairo_status_t - _cairo_quartz_surface_clone_similar (void *abstract_surface, -- cairo_surface_t *src, -- int src_x, -- int src_y, -- int width, -- int height, -- cairo_surface_t **clone_out) -+ cairo_surface_t *src, -+ int src_x, -+ int src_y, -+ int width, -+ int height, -+ cairo_surface_t **clone_out) - { - cairo_quartz_surface_t *new_surface = NULL; - cairo_format_t new_format; -@@ -1156,97 +1129,58 @@ _cairo_quartz_surface_clone_similar (voi - *clone_out = NULL; - - // verify width and height of surface -- if (!verify_surface_size(width, height)) { -+ if (!_cairo_quartz_verify_surface_size(width, height)) { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - -- if (cairo_surface_get_type(src) == CAIRO_SURFACE_TYPE_QUARTZ) { -+ if (width == 0 || height == 0) { -+ *clone_out = (cairo_surface_t*) -+ _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, -+ width, height); -+ return CAIRO_STATUS_SUCCESS; -+ } -+ -+ if (src->backend->type == CAIRO_SURFACE_TYPE_QUARTZ) { - cairo_quartz_surface_t *qsurf = (cairo_quartz_surface_t *) src; - - if (IS_EMPTY(qsurf)) { -- *clone_out = (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, qsurf->extents.width, qsurf->extents.height); -+ *clone_out = (cairo_surface_t*) -+ _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, -+ qsurf->extents.width, qsurf->extents.height); - return CAIRO_STATUS_SUCCESS; - } -- -- quartz_image = CGBitmapContextCreateImage (qsurf->cgContext); -- new_format = CAIRO_FORMAT_ARGB32; /* XXX bogus; recover a real format from the image */ -- } else if (_cairo_surface_is_image (src)) { -- cairo_image_surface_t *isurf = (cairo_image_surface_t *) src; -- CGDataProviderRef dataProvider; -- CGColorSpaceRef cgColorspace; -- CGBitmapInfo bitinfo; -- int bitsPerComponent, bitsPerPixel; -- -- if (isurf->width == 0 || isurf->height == 0) { -- *clone_out = (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA, isurf->width, isurf->height); -- return CAIRO_STATUS_SUCCESS; -- } -- -- if (isurf->format == CAIRO_FORMAT_ARGB32) { -- cgColorspace = CGColorSpaceCreateDeviceRGB(); -- bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; -- bitsPerComponent = 8; -- bitsPerPixel = 32; -- } else if (isurf->format == CAIRO_FORMAT_RGB24) { -- cgColorspace = CGColorSpaceCreateDeviceRGB(); -- bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; -- bitsPerComponent = 8; -- bitsPerPixel = 32; -- } else if (isurf->format == CAIRO_FORMAT_A8) { -- cgColorspace = CGColorSpaceCreateDeviceGray(); -- bitinfo = kCGImageAlphaNone; -- bitsPerComponent = 8; -- bitsPerPixel = 8; -- } else { -- /* SUPPORT A1, maybe */ -- return CAIRO_INT_STATUS_UNSUPPORTED; -- } -- -- new_format = isurf->format; -- -- dataProvider = CGDataProviderCreateWithData (NULL, -- isurf->data, -- isurf->height * isurf->stride, -- NULL); -- -- quartz_image = CGImageCreate (isurf->width, isurf->height, -- bitsPerComponent, -- bitsPerPixel, -- isurf->stride, -- cgColorspace, -- bitinfo, -- dataProvider, -- NULL, -- false, -- kCGRenderingIntentDefault); -- CGDataProviderRelease (dataProvider); -- CGColorSpaceRelease (cgColorspace); -- } else { -- return CAIRO_INT_STATUS_UNSUPPORTED; - } - -+ quartz_image = _cairo_surface_to_cgimage ((cairo_surface_t*) abstract_surface, src); - if (!quartz_image) - 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; -+ } -+ - new_surface = (cairo_quartz_surface_t *) -- cairo_quartz_surface_create (new_format, -- CGImageGetWidth (quartz_image), -- CGImageGetHeight (quartz_image)); -+ cairo_quartz_surface_create (new_format, width, height); - if (!new_surface || new_surface->base.status) { - CGImageRelease (quartz_image); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - -+ CGContextSaveGState (new_surface->cgContext); -+ - CGContextSetCompositeOperation (new_surface->cgContext, - kPrivateCGCompositeCopy); - -- quartz_image_to_png (quartz_image, NULL); -+ CGContextTranslateCTM (new_surface->cgContext, -src_x, -src_y); -+ CGContextDrawImage (new_surface->cgContext, -+ CGRectMake (0, 0, CGImageGetWidth(quartz_image), CGImageGetHeight(quartz_image)), -+ quartz_image); - -- CGContextDrawImage (new_surface->cgContext, -- CGRectMake (src_x, src_y, width, height), -- quartz_image); -+ CGContextRestoreGState (new_surface->cgContext); -+ - CGImageRelease (quartz_image); -- -+ - *clone_out = (cairo_surface_t*) new_surface; - - return CAIRO_STATUS_SUCCESS; -@@ -1265,8 +1199,8 @@ _cairo_quartz_surface_get_extents (void - - static cairo_int_status_t - _cairo_quartz_surface_paint (void *abstract_surface, -- cairo_operator_t op, -- cairo_pattern_t *source) -+ cairo_operator_t op, -+ cairo_pattern_t *source) - { - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; -@@ -1292,17 +1226,11 @@ _cairo_quartz_surface_paint (void *abstr - } else if (action == DO_SHADING) { - CGContextDrawShading (surface->cgContext, surface->sourceShading); - } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) { -- cairo_surface_pattern_t *surface_pattern = -- (cairo_surface_pattern_t *) source; -- cairo_surface_t *pat_surf = surface_pattern->surface; -- - CGContextSaveGState (surface->cgContext); - - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); -- if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { -- CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); -- CGContextScaleCTM (surface->cgContext, 1, -1); -- } -+ CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height); -+ CGContextScaleCTM (surface->cgContext, 1, -1); - - if (action == DO_IMAGE) - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); -@@ -1372,19 +1300,14 @@ _cairo_quartz_surface_fill (void *abstra - - CGContextDrawShading (surface->cgContext, surface->sourceShading); - } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) { -- cairo_surface_pattern_t *surface_pattern = -- (cairo_surface_pattern_t *) source; -- cairo_surface_t *pat_surf = surface_pattern->surface; - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (surface->cgContext); - else - CGContextEOClip (surface->cgContext); - - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); -- if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { -- CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); -- CGContextScaleCTM (surface->cgContext, 1, -1); -- } -+ CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height); -+ CGContextScaleCTM (surface->cgContext, 1, -1); - - if (action == DO_IMAGE) - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); -@@ -1481,10 +1404,8 @@ _cairo_quartz_surface_stroke (void *abst - CGContextClip (surface->cgContext); - - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); -- if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) { -- CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); -- CGContextScaleCTM (surface->cgContext, 1, -1); -- } -+ CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height); -+ CGContextScaleCTM (surface->cgContext, 1, -1); - - if (action == DO_IMAGE) - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); -@@ -1633,10 +1554,8 @@ _cairo_quartz_surface_show_glyphs (void - - if (action == DO_IMAGE || action == DO_TILED_IMAGE) { - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); -- if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) { -- CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); -- CGContextScaleCTM (surface->cgContext, 1, -1); -- } -+ CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height); -+ CGContextScaleCTM (surface->cgContext, 1, -1); - - if (action == DO_IMAGE) - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); -@@ -1670,7 +1589,6 @@ _cairo_quartz_surface_mask_with_surface - cairo_surface_pattern_t *mask) - { - cairo_rectangle_int_t extents; -- cairo_quartz_surface_t *quartz_surf; - CGRect rect; - CGImageRef img; - cairo_surface_t *pat_surf = mask->surface; -@@ -1680,15 +1598,11 @@ _cairo_quartz_surface_mask_with_surface - if (status) - return status; - -- status = _cairo_quartz_surface_to_quartz (NULL, pat_surf, &quartz_surf); -- if (status) -- return status; -- - // everything would be masked out, so do nothing -- if (IS_EMPTY(quartz_surf)) -+ if (extents.width == 0 || extents.height == 0) - goto BAIL; - -- img = CGBitmapContextCreateImage (quartz_surf->cgContext); -+ img = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf); - if (!img) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; -@@ -1702,7 +1616,6 @@ _cairo_quartz_surface_mask_with_surface - CGContextRestoreGState (surface->cgContext); - CGImageRelease (img); - BAIL: -- cairo_surface_destroy ((cairo_surface_t*) quartz_surf); - return status; - } - -@@ -1965,7 +1878,7 @@ cairo_quartz_surface_create (cairo_forma - int bitsPerComponent; - - // verify width and height of surface -- if (!verify_surface_size(width, height)) -+ if (!_cairo_quartz_verify_surface_size(width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - if (width == 0 || height == 0) { -@@ -2006,6 +1919,7 @@ cairo_quartz_surface_create (cairo_forma - CGColorSpaceRelease (cgColorspace); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } -+ - /* zero the memory to match the image surface behaviour */ - memset (imageData, 0, height * stride); - -@@ -2164,15 +2078,3 @@ quartz_surface_to_png (cairo_quartz_surf - CGImageRelease(imgref); - #endif - } -- --cairo_surface_t * --cairo_quartz_surface_get_image (cairo_surface_t *surface) --{ -- cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t*)surface; -- -- if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_QUARTZ) -- return NULL; -- -- return quartz->imageSurfaceEquiv; --} -- -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 -@@ -58,7 +58,10 @@ cairo_quartz_surface_get_cg_context (cai - cairo_quartz_surface_get_cg_context (cairo_surface_t *surface); - - cairo_public cairo_surface_t * --cairo_quartz_surface_get_image (cairo_surface_t *surface); -+cairo_quartz_image_surface_create (cairo_surface_t *image_surface); -+ -+cairo_public cairo_surface_t * -+cairo_quartz_image_surface_get_image (cairo_surface_t *surface); - - CAIRO_END_DECLS - -diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h ---- a/gfx/cairo/cairo/src/cairo.h -+++ b/gfx/cairo/cairo/src/cairo.h -@@ -1481,7 +1481,8 @@ typedef enum _cairo_surface_type { - CAIRO_SURFACE_TYPE_DIRECTFB, - CAIRO_SURFACE_TYPE_SVG, - CAIRO_SURFACE_TYPE_OS2, -- CAIRO_SURFACE_TYPE_WIN32_PRINTING -+ CAIRO_SURFACE_TYPE_WIN32_PRINTING, -+ CAIRO_SURFACE_TYPE_QUARTZ_IMAGE - } cairo_surface_type_t; - - cairo_public cairo_surface_type_t