gfx/cairo/quartz-support-color-emoji-font.patch

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/quartz-support-color-emoji-font.patch	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,432 @@
     1.4 +From: Jonathan Kew <jkew@mozilla.com>
     1.5 +bug 715798 pt 1 - support Apple Color Emoji font in cairo-quartz backend. r=jrmuizel
     1.6 +
     1.7 +diff --git a/gfx/cairo/cairo/src/cairo-quartz-font.c b/gfx/cairo/cairo/src/cairo-quartz-font.c
     1.8 +--- a/gfx/cairo/cairo/src/cairo-quartz-font.c
     1.9 ++++ b/gfx/cairo/cairo/src/cairo-quartz-font.c
    1.10 +@@ -85,16 +85,20 @@ typedef struct {
    1.11 +     int descent;
    1.12 +     int leading;
    1.13 + } quartz_CGFontMetrics;
    1.14 + static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL;
    1.15 + static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL;
    1.16 + static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL;
    1.17 + static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL;
    1.18 + 
    1.19 ++/* CTFontCreateWithGraphicsFont is not public until 10.5. */
    1.20 ++typedef const struct __CTFontDescriptor *CTFontDescriptorRef;
    1.21 ++static CTFontRef (*CTFontCreateWithGraphicsFontPtr) (CGFontRef, CGFloat, const CGAffineTransform *, CTFontDescriptorRef) = NULL;
    1.22 ++
    1.23 + static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
    1.24 + static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
    1.25 + 
    1.26 + static void
    1.27 + quartz_font_ensure_symbols(void)
    1.28 + {
    1.29 +     if (_cairo_quartz_font_symbol_lookup_done)
    1.30 + 	return;
    1.31 +@@ -122,16 +126,18 @@ quartz_font_ensure_symbols(void)
    1.32 +     CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
    1.33 +     CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
    1.34 +     CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent");
    1.35 +     CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading");
    1.36 + 
    1.37 +     CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
    1.38 +     CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
    1.39 + 
    1.40 ++    CTFontCreateWithGraphicsFontPtr = dlsym(RTLD_DEFAULT, "CTFontCreateWithGraphicsFont");
    1.41 ++
    1.42 +     if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
    1.43 + 	CGFontGetGlyphBBoxesPtr &&
    1.44 + 	CGFontGetGlyphsForUnicharsPtr &&
    1.45 + 	CGFontGetUnitsPerEmPtr &&
    1.46 + 	CGFontGetGlyphAdvancesPtr &&
    1.47 + 	CGFontGetGlyphPathPtr &&
    1.48 + 	(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
    1.49 + 	_cairo_quartz_font_symbols_present = TRUE;
    1.50 +@@ -145,16 +151,17 @@ typedef struct _cairo_quartz_scaled_font
    1.51 + struct _cairo_quartz_scaled_font {
    1.52 +     cairo_scaled_font_t base;
    1.53 + };
    1.54 + 
    1.55 + struct _cairo_quartz_font_face {
    1.56 +     cairo_font_face_t base;
    1.57 + 
    1.58 +     CGFontRef cgFont;
    1.59 ++    CTFontRef ctFont;
    1.60 + };
    1.61 + 
    1.62 + /*
    1.63 +  * font face backend
    1.64 +  */
    1.65 + 
    1.66 + static cairo_status_t
    1.67 + _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
    1.68 +@@ -229,16 +236,20 @@ static cairo_status_t
    1.69 +     return CAIRO_STATUS_SUCCESS;
    1.70 + }
    1.71 + 
    1.72 + static void
    1.73 + _cairo_quartz_font_face_destroy (void *abstract_face)
    1.74 + {
    1.75 +     cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
    1.76 + 
    1.77 ++    if (font_face->ctFont) {
    1.78 ++        CFRelease (font_face->ctFont);
    1.79 ++    }
    1.80 ++
    1.81 +     CGFontRelease (font_face->cgFont);
    1.82 + }
    1.83 + 
    1.84 + static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend;
    1.85 + 
    1.86 + static cairo_status_t
    1.87 + _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
    1.88 + 					    const cairo_matrix_t *font_matrix,
    1.89 +@@ -353,16 +364,22 @@ cairo_quartz_font_face_create_for_cgfont
    1.90 +     if (!font_face) {
    1.91 + 	cairo_status_t ignore_status;
    1.92 + 	ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    1.93 + 	return (cairo_font_face_t *)&_cairo_font_face_nil;
    1.94 +     }
    1.95 + 
    1.96 +     font_face->cgFont = CGFontRetain (font);
    1.97 + 
    1.98 ++    if (CTFontCreateWithGraphicsFontPtr) {
    1.99 ++        font_face->ctFont = CTFontCreateWithGraphicsFontPtr (font, 1.0, NULL, NULL);
   1.100 ++    } else {
   1.101 ++        font_face->ctFont = NULL;
   1.102 ++    }
   1.103 ++
   1.104 +     _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
   1.105 + 
   1.106 +     return &font_face->base;
   1.107 + }
   1.108 + 
   1.109 + /*
   1.110 +  * scaled font backend
   1.111 +  */
   1.112 +@@ -772,16 +789,24 @@ static const cairo_scaled_font_backend_t
   1.113 + CGFontRef
   1.114 + _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
   1.115 + {
   1.116 +     cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
   1.117 + 
   1.118 +     return ffont->cgFont;
   1.119 + }
   1.120 + 
   1.121 ++CTFontRef
   1.122 ++_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *abstract_font)
   1.123 ++{
   1.124 ++    cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
   1.125 ++
   1.126 ++    return ffont->ctFont;
   1.127 ++}
   1.128 ++
   1.129 + #ifndef __LP64__
   1.130 + /*
   1.131 +  * compat with old ATSUI backend
   1.132 +  */
   1.133 + 
   1.134 + /**
   1.135 +  * cairo_quartz_font_face_create_for_atsu_font_id
   1.136 +  * @font_id: an ATSUFontID for the font.
   1.137 +diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h
   1.138 +--- a/gfx/cairo/cairo/src/cairo-quartz-private.h
   1.139 ++++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
   1.140 +@@ -45,16 +45,19 @@
   1.141 + #include "cairo-surface-clipper-private.h"
   1.142 + 
   1.143 + #ifdef CGFLOAT_DEFINED
   1.144 + typedef CGFloat cairo_quartz_float_t;
   1.145 + #else
   1.146 + typedef float cairo_quartz_float_t;
   1.147 + #endif
   1.148 + 
   1.149 ++/* define CTFontRef for pre-10.5 SDKs */
   1.150 ++typedef const struct __CTFont *CTFontRef;
   1.151 ++
   1.152 + typedef struct cairo_quartz_surface {
   1.153 +     cairo_surface_t base;
   1.154 + 
   1.155 +     CGContextRef cgContext;
   1.156 +     CGAffineTransform cgContextBaseCTM;
   1.157 + 
   1.158 +     void *imageData;
   1.159 +     cairo_surface_t *imageSurfaceEquiv;
   1.160 +@@ -99,15 +102,18 @@ CGImageRef
   1.161 + 			      cairo_bool_t interpolate,
   1.162 + 			      CGColorSpaceRef colorSpaceOverride,
   1.163 + 			      CGDataProviderReleaseDataCallback releaseCallback,
   1.164 + 			      void *releaseInfo);
   1.165 + 
   1.166 + CGFontRef
   1.167 + _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
   1.168 + 
   1.169 ++CTFontRef
   1.170 ++_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *sfont);
   1.171 ++
   1.172 + #else
   1.173 + 
   1.174 + # error Cairo was not compiled with support for the quartz backend
   1.175 + 
   1.176 + #endif /* CAIRO_HAS_QUARTZ_SURFACE */
   1.177 + 
   1.178 + #endif /* CAIRO_QUARTZ_PRIVATE_H */
   1.179 +diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
   1.180 +--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
   1.181 ++++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
   1.182 +@@ -130,16 +130,19 @@ static void (*CGContextClipToMaskPtr) (C
   1.183 + static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
   1.184 + static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
   1.185 + static void (*CGContextSetShouldAntialiasFontsPtr) (CGContextRef, bool) = NULL;
   1.186 + static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
   1.187 + static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
   1.188 + static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL;
   1.189 + static CGFloat (*CGContextGetAlphaPtr) (CGContextRef) = NULL;
   1.190 + 
   1.191 ++/* CTFontDrawGlyphs is not available until 10.7 */
   1.192 ++static void (*CTFontDrawGlyphsPtr) (CTFontRef, const CGGlyph[], const CGPoint[], size_t, CGContextRef) = NULL;
   1.193 ++
   1.194 + static SInt32 _cairo_quartz_osx_version = 0x0;
   1.195 + 
   1.196 + static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
   1.197 + 
   1.198 + /*
   1.199 +  * Utility functions
   1.200 +  */
   1.201 + 
   1.202 +@@ -167,16 +170,18 @@ static void quartz_ensure_symbols(void)
   1.203 +     CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
   1.204 +     CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetType");
   1.205 +     CGContextSetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldAntialiasFonts");
   1.206 +     CGContextCopyPathPtr = dlsym(RTLD_DEFAULT, "CGContextCopyPath");
   1.207 +     CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
   1.208 +     CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
   1.209 +     CGContextGetAlphaPtr = dlsym(RTLD_DEFAULT, "CGContextGetAlpha");
   1.210 + 
   1.211 ++    CTFontDrawGlyphsPtr = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs");
   1.212 ++
   1.213 +     if (Gestalt(gestaltSystemVersion, &_cairo_quartz_osx_version) != noErr) {
   1.214 +         // assume 10.5
   1.215 +         _cairo_quartz_osx_version = 0x1050;
   1.216 +     }
   1.217 + 
   1.218 +     _cairo_quartz_symbol_lookup_done = TRUE;
   1.219 + }
   1.220 + 
   1.221 +@@ -605,20 +610,23 @@ static inline void
   1.222 +     dst->d = src->yy;
   1.223 +     dst->tx = src->x0;
   1.224 +     dst->ty = src->y0;
   1.225 + }
   1.226 + 
   1.227 + typedef struct {
   1.228 +     bool isClipping;
   1.229 +     CGGlyph *cg_glyphs;
   1.230 +-    CGSize *cg_advances;
   1.231 ++    union {
   1.232 ++      CGSize *cg_advances;
   1.233 ++      CGPoint *cg_positions;
   1.234 ++    } u;
   1.235 +     size_t nglyphs;
   1.236 +     CGAffineTransform textTransform;
   1.237 +-    CGFontRef font;
   1.238 ++    cairo_scaled_font_t *scaled_font;
   1.239 +     CGPoint origin;
   1.240 + } unbounded_show_glyphs_t;
   1.241 + 
   1.242 + typedef struct {
   1.243 +     CGPathRef cgPath;
   1.244 +     cairo_fill_rule_t fill_rule;
   1.245 + } unbounded_stroke_fill_t;
   1.246 + 
   1.247 +@@ -686,36 +694,43 @@ static void
   1.248 + 	CGContextBeginPath (cgc);
   1.249 + 	CGContextAddPath (cgc, op->u.stroke_fill.cgPath);
   1.250 + 
   1.251 + 	if (op->u.stroke_fill.fill_rule == CAIRO_FILL_RULE_WINDING)
   1.252 + 	    CGContextFillPath (cgc);
   1.253 + 	else
   1.254 + 	    CGContextEOFillPath (cgc);
   1.255 +     } else if (op->op == UNBOUNDED_SHOW_GLYPHS) {
   1.256 +-	CGContextSetFont (cgc, op->u.show_glyphs.font);
   1.257 +-	CGContextSetFontSize (cgc, 1.0);
   1.258 +-	CGContextSetTextMatrix (cgc, CGAffineTransformIdentity);
   1.259 +-	CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y);
   1.260 +-	CGContextConcatCTM (cgc, op->u.show_glyphs.textTransform);
   1.261 +-
   1.262 + 	if (op->u.show_glyphs.isClipping) {
   1.263 + 	    /* Note that the comment in show_glyphs about kCGTextClip
   1.264 + 	     * and the text transform still applies here; however, the
   1.265 + 	     * cg_advances we have were already transformed, so we
   1.266 + 	     * don't have to do anything. */
   1.267 + 	    CGContextSetTextDrawingMode (cgc, kCGTextClip);
   1.268 + 	    CGContextSaveGState (cgc);
   1.269 + 	}
   1.270 +-
   1.271 +-	CGContextShowGlyphsWithAdvances (cgc,
   1.272 +-					 op->u.show_glyphs.cg_glyphs,
   1.273 +-					 op->u.show_glyphs.cg_advances,
   1.274 +-					 op->u.show_glyphs.nglyphs);
   1.275 +-
   1.276 ++        CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y);
   1.277 ++        CGContextConcatCTM (cgc, op->u.show_glyphs.textTransform);
   1.278 ++        if (CTFontDrawGlyphsPtr) {
   1.279 ++            CTFontDrawGlyphsPtr (_cairo_quartz_scaled_font_get_ct_font_ref (op->u.show_glyphs.scaled_font),
   1.280 ++                                 op->u.show_glyphs.cg_glyphs,
   1.281 ++                                 op->u.show_glyphs.u.cg_positions,
   1.282 ++                                 op->u.show_glyphs.nglyphs,
   1.283 ++                                 cgc);
   1.284 ++        } else {
   1.285 ++	    CGContextSetFont (cgc, _cairo_quartz_scaled_font_get_cg_font_ref (op->u.show_glyphs.scaled_font));
   1.286 ++	    CGContextSetFontSize (cgc, 1.0);
   1.287 ++	    CGContextSetTextMatrix (cgc, CGAffineTransformIdentity);
   1.288 ++
   1.289 ++	    CGContextShowGlyphsWithAdvances (cgc,
   1.290 ++					     op->u.show_glyphs.cg_glyphs,
   1.291 ++					     op->u.show_glyphs.u.cg_advances,
   1.292 ++					     op->u.show_glyphs.nglyphs);
   1.293 ++
   1.294 ++        }
   1.295 + 	if (op->u.show_glyphs.isClipping) {
   1.296 + 	    CGContextClearRect (cgc, clipBoxRound);
   1.297 + 	    CGContextRestoreGState (cgc);
   1.298 + 	}
   1.299 +     } else if (op->op == UNBOUNDED_MASK) {
   1.300 + 	CGAffineTransform ctm = CGContextGetCTM (cgc);
   1.301 + 	CGContextSaveGState (cgc);
   1.302 + 	CGContextConcatCTM (cgc, op->u.mask.maskTransform);
   1.303 +@@ -2684,16 +2699,19 @@ static cairo_int_status_t
   1.304 + 				      cairo_clip_t *clip,
   1.305 + 				      int *remaining_glyphs)
   1.306 + {
   1.307 +     CGAffineTransform textTransform, ctm, invTextTransform;
   1.308 + #define STATIC_BUF_SIZE 64
   1.309 +     CGGlyph glyphs_static[STATIC_BUF_SIZE];
   1.310 +     CGSize cg_advances_static[STATIC_BUF_SIZE];
   1.311 +     CGGlyph *cg_glyphs = &glyphs_static[0];
   1.312 ++    /* We'll use the cg_advances array for either advances or positions,
   1.313 ++       depending which API we're using to actually draw. The types involved
   1.314 ++       have the same size, so this is safe. */
   1.315 +     CGSize *cg_advances = &cg_advances_static[0];
   1.316 + 
   1.317 +     cairo_rectangle_int_t glyph_extents;
   1.318 +     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
   1.319 +     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
   1.320 +     cairo_quartz_drawing_state_t state;
   1.321 +     cairo_quartz_float_t xprev, yprev;
   1.322 +     int i;
   1.323 +@@ -2796,41 +2814,62 @@ static cairo_int_status_t
   1.324 +     invTextTransform = CGAffineTransformMake (scaled_font->scale_inverse.xx,
   1.325 + 					      -scaled_font->scale_inverse.yx,
   1.326 + 					      scaled_font->scale_inverse.xy,
   1.327 + 					      -scaled_font->scale_inverse.yy,
   1.328 + 					      0.0, 0.0);
   1.329 + 
   1.330 +     CGContextSetTextMatrix (state.context, CGAffineTransformIdentity);
   1.331 + 
   1.332 +-    /* Convert our glyph positions to glyph advances.  We need n-1 advances,
   1.333 +-     * since the advance at index 0 is applied after glyph 0. */
   1.334 +-    xprev = glyphs[0].x;
   1.335 +-    yprev = glyphs[0].y;
   1.336 +-
   1.337 +-    cg_glyphs[0] = glyphs[0].index;
   1.338 +-
   1.339 +-    for (i = 1; i < num_glyphs; i++) {
   1.340 +-	cairo_quartz_float_t xf = glyphs[i].x;
   1.341 +-	cairo_quartz_float_t yf = glyphs[i].y;
   1.342 +-	cg_glyphs[i] = glyphs[i].index;
   1.343 +-	cg_advances[i - 1] = CGSizeApplyAffineTransform(CGSizeMake (xf - xprev, yf - yprev), invTextTransform);
   1.344 +-	xprev = xf;
   1.345 +-	yprev = yf;
   1.346 +-    }
   1.347 +-
   1.348 +     /* Translate to the first glyph's position before drawing */
   1.349 +     ctm = CGContextGetCTM (state.context);
   1.350 +     CGContextTranslateCTM (state.context, glyphs[0].x, glyphs[0].y);
   1.351 +     CGContextConcatCTM (state.context, textTransform);
   1.352 + 
   1.353 +-    CGContextShowGlyphsWithAdvances (state.context,
   1.354 +-				     cg_glyphs,
   1.355 +-				     cg_advances,
   1.356 +-				     num_glyphs);
   1.357 ++    if (CTFontDrawGlyphsPtr) {
   1.358 ++        /* If CTFontDrawGlyphs is available (i.e. OS X 10.7 or later), we want to use
   1.359 ++         * that in preference to CGContextShowGlyphsWithAdvances so that colored-bitmap
   1.360 ++         * fonts like Apple Color Emoji will render properly.
   1.361 ++         * For this, we need to convert our glyph positions to Core Graphics's CGPoint.
   1.362 ++         * We borrow the cg_advances array, as CGPoint and CGSize are the same size. */
   1.363 ++
   1.364 ++        CGPoint *cg_positions = (CGPoint*) cg_advances;
   1.365 ++        cairo_quartz_float_t origin_x = glyphs[0].x;
   1.366 ++        cairo_quartz_float_t origin_y = glyphs[0].y;
   1.367 ++
   1.368 ++        for (i = 0; i < num_glyphs; i++) {
   1.369 ++            CGPoint pt = CGPointMake (glyphs[i].x - origin_x, glyphs[i].y - origin_y);
   1.370 ++            cg_positions[i] = CGPointApplyAffineTransform (pt, invTextTransform);
   1.371 ++            cg_glyphs[i] = glyphs[i].index;
   1.372 ++        }
   1.373 ++
   1.374 ++        CTFontDrawGlyphsPtr (_cairo_quartz_scaled_font_get_ct_font_ref (scaled_font),
   1.375 ++                             cg_glyphs, cg_positions, num_glyphs, state.context);
   1.376 ++    } else {
   1.377 ++        /* Convert our glyph positions to glyph advances.  We need n-1 advances,
   1.378 ++         * since the advance at index 0 is applied after glyph 0. */
   1.379 ++        xprev = glyphs[0].x;
   1.380 ++        yprev = glyphs[0].y;
   1.381 ++
   1.382 ++        cg_glyphs[0] = glyphs[0].index;
   1.383 ++
   1.384 ++        for (i = 1; i < num_glyphs; i++) {
   1.385 ++	    cairo_quartz_float_t xf = glyphs[i].x;
   1.386 ++	    cairo_quartz_float_t yf = glyphs[i].y;
   1.387 ++	    cg_glyphs[i] = glyphs[i].index;
   1.388 ++	    cg_advances[i - 1] = CGSizeApplyAffineTransform(CGSizeMake (xf - xprev, yf - yprev), invTextTransform);
   1.389 ++	    xprev = xf;
   1.390 ++	    yprev = yf;
   1.391 ++        }
   1.392 ++
   1.393 ++        CGContextShowGlyphsWithAdvances (state.context,
   1.394 ++				         cg_glyphs,
   1.395 ++				         cg_advances,
   1.396 ++				         num_glyphs);
   1.397 ++    }
   1.398 + 
   1.399 +     CGContextSetCTM (state.context, ctm);
   1.400 + 
   1.401 +     if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
   1.402 +         state.action == DO_LAYER) {
   1.403 + 	_cairo_quartz_draw_image (&state, op);
   1.404 +     } else if (state.action == DO_SHADING) {
   1.405 + 	CGContextConcatCTM (state.context, state.transform);
   1.406 +@@ -2847,20 +2886,27 @@ BAIL:
   1.407 + 	cgfref &&
   1.408 + 	!_cairo_operator_bounded_by_mask (op))
   1.409 +     {
   1.410 + 	unbounded_op_data_t ub;
   1.411 + 	ub.op = UNBOUNDED_SHOW_GLYPHS;
   1.412 + 
   1.413 + 	ub.u.show_glyphs.isClipping = isClipping;
   1.414 + 	ub.u.show_glyphs.cg_glyphs = cg_glyphs;
   1.415 +-	ub.u.show_glyphs.cg_advances = cg_advances;
   1.416 ++	if (CTFontDrawGlyphsPtr) {
   1.417 ++	    /* we're using Core Text API: the cg_advances array was
   1.418 ++	       reused (above) for glyph positions */
   1.419 ++            CGPoint *cg_positions = (CGPoint*) cg_advances;
   1.420 ++	    ub.u.show_glyphs.u.cg_positions = cg_positions;
   1.421 ++	} else {
   1.422 ++	    ub.u.show_glyphs.u.cg_advances = cg_advances;
   1.423 ++	}
   1.424 + 	ub.u.show_glyphs.nglyphs = num_glyphs;
   1.425 + 	ub.u.show_glyphs.textTransform = textTransform;
   1.426 +-	ub.u.show_glyphs.font = cgfref;
   1.427 ++	ub.u.show_glyphs.scaled_font = scaled_font;
   1.428 + 	ub.u.show_glyphs.origin = CGPointMake (glyphs[0].x, glyphs[0].y);
   1.429 + 
   1.430 + 	_cairo_quartz_fixup_unbounded_operation (surface, &ub, scaled_font->options.antialias);
   1.431 +     }
   1.432 + 
   1.433 + 
   1.434 +     if (cg_advances != &cg_advances_static[0]) {
   1.435 + 	free (cg_advances);

mercurial