From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- gfx/cairo/quartz-support-color-emoji-font.patch | 432 ++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 gfx/cairo/quartz-support-color-emoji-font.patch (limited to 'gfx/cairo/quartz-support-color-emoji-font.patch') diff --git a/gfx/cairo/quartz-support-color-emoji-font.patch b/gfx/cairo/quartz-support-color-emoji-font.patch new file mode 100644 index 000000000..5fb88b271 --- /dev/null +++ b/gfx/cairo/quartz-support-color-emoji-font.patch @@ -0,0 +1,432 @@ +From: Jonathan Kew +bug 715798 pt 1 - support Apple Color Emoji font in cairo-quartz backend. r=jrmuizel + +diff --git a/gfx/cairo/cairo/src/cairo-quartz-font.c b/gfx/cairo/cairo/src/cairo-quartz-font.c +--- a/gfx/cairo/cairo/src/cairo-quartz-font.c ++++ b/gfx/cairo/cairo/src/cairo-quartz-font.c +@@ -85,16 +85,20 @@ typedef struct { + int descent; + int leading; + } quartz_CGFontMetrics; + static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL; + static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL; + static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL; + static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL; + ++/* CTFontCreateWithGraphicsFont is not public until 10.5. */ ++typedef const struct __CTFontDescriptor *CTFontDescriptorRef; ++static CTFontRef (*CTFontCreateWithGraphicsFontPtr) (CGFontRef, CGFloat, const CGAffineTransform *, CTFontDescriptorRef) = NULL; ++ + static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE; + static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE; + + static void + quartz_font_ensure_symbols(void) + { + if (_cairo_quartz_font_symbol_lookup_done) + return; +@@ -122,16 +126,18 @@ quartz_font_ensure_symbols(void) + CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics"); + CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent"); + CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent"); + CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading"); + + CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing"); + CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing"); + ++ CTFontCreateWithGraphicsFontPtr = dlsym(RTLD_DEFAULT, "CTFontCreateWithGraphicsFont"); ++ + if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) && + CGFontGetGlyphBBoxesPtr && + CGFontGetGlyphsForUnicharsPtr && + CGFontGetUnitsPerEmPtr && + CGFontGetGlyphAdvancesPtr && + CGFontGetGlyphPathPtr && + (CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr))) + _cairo_quartz_font_symbols_present = TRUE; +@@ -145,16 +151,17 @@ typedef struct _cairo_quartz_scaled_font + struct _cairo_quartz_scaled_font { + cairo_scaled_font_t base; + }; + + struct _cairo_quartz_font_face { + cairo_font_face_t base; + + CGFontRef cgFont; ++ CTFontRef ctFont; + }; + + /* + * font face backend + */ + + static cairo_status_t + _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, +@@ -229,16 +236,20 @@ static cairo_status_t + return CAIRO_STATUS_SUCCESS; + } + + static void + _cairo_quartz_font_face_destroy (void *abstract_face) + { + cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face; + ++ if (font_face->ctFont) { ++ CFRelease (font_face->ctFont); ++ } ++ + CGFontRelease (font_face->cgFont); + } + + static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend; + + static cairo_status_t + _cairo_quartz_font_face_scaled_font_create (void *abstract_face, + const cairo_matrix_t *font_matrix, +@@ -353,16 +364,22 @@ cairo_quartz_font_face_create_for_cgfont + if (!font_face) { + cairo_status_t ignore_status; + ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_font_face_t *)&_cairo_font_face_nil; + } + + font_face->cgFont = CGFontRetain (font); + ++ if (CTFontCreateWithGraphicsFontPtr) { ++ font_face->ctFont = CTFontCreateWithGraphicsFontPtr (font, 1.0, NULL, NULL); ++ } else { ++ font_face->ctFont = NULL; ++ } ++ + _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend); + + return &font_face->base; + } + + /* + * scaled font backend + */ +@@ -772,16 +789,24 @@ static const cairo_scaled_font_backend_t + CGFontRef + _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font) + { + cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font); + + return ffont->cgFont; + } + ++CTFontRef ++_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *abstract_font) ++{ ++ cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font); ++ ++ return ffont->ctFont; ++} ++ + #ifndef __LP64__ + /* + * compat with old ATSUI backend + */ + + /** + * cairo_quartz_font_face_create_for_atsu_font_id + * @font_id: an ATSUFontID for the font. +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 +@@ -45,16 +45,19 @@ + #include "cairo-surface-clipper-private.h" + + #ifdef CGFLOAT_DEFINED + typedef CGFloat cairo_quartz_float_t; + #else + typedef float cairo_quartz_float_t; + #endif + ++/* define CTFontRef for pre-10.5 SDKs */ ++typedef const struct __CTFont *CTFontRef; ++ + typedef struct cairo_quartz_surface { + cairo_surface_t base; + + CGContextRef cgContext; + CGAffineTransform cgContextBaseCTM; + + void *imageData; + cairo_surface_t *imageSurfaceEquiv; +@@ -99,15 +102,18 @@ CGImageRef + cairo_bool_t interpolate, + CGColorSpaceRef colorSpaceOverride, + CGDataProviderReleaseDataCallback releaseCallback, + void *releaseInfo); + + CGFontRef + _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont); + ++CTFontRef ++_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *sfont); ++ + #else + + # error Cairo was not compiled with support for the quartz backend + + #endif /* CAIRO_HAS_QUARTZ_SURFACE */ + + #endif /* CAIRO_QUARTZ_PRIVATE_H */ +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 +@@ -130,16 +130,19 @@ static void (*CGContextClipToMaskPtr) (C + static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL; + static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL; + static void (*CGContextSetShouldAntialiasFontsPtr) (CGContextRef, bool) = NULL; + static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL; + static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL; + static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL; + static CGFloat (*CGContextGetAlphaPtr) (CGContextRef) = NULL; + ++/* CTFontDrawGlyphs is not available until 10.7 */ ++static void (*CTFontDrawGlyphsPtr) (CTFontRef, const CGGlyph[], const CGPoint[], size_t, CGContextRef) = NULL; ++ + static SInt32 _cairo_quartz_osx_version = 0x0; + + static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE; + + /* + * Utility functions + */ + +@@ -167,16 +170,18 @@ static void quartz_ensure_symbols(void) + CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage"); + CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetType"); + CGContextSetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldAntialiasFonts"); + CGContextCopyPathPtr = dlsym(RTLD_DEFAULT, "CGContextCopyPath"); + CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing"); + CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing"); + CGContextGetAlphaPtr = dlsym(RTLD_DEFAULT, "CGContextGetAlpha"); + ++ CTFontDrawGlyphsPtr = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs"); ++ + if (Gestalt(gestaltSystemVersion, &_cairo_quartz_osx_version) != noErr) { + // assume 10.5 + _cairo_quartz_osx_version = 0x1050; + } + + _cairo_quartz_symbol_lookup_done = TRUE; + } + +@@ -605,20 +610,23 @@ static inline void + dst->d = src->yy; + dst->tx = src->x0; + dst->ty = src->y0; + } + + typedef struct { + bool isClipping; + CGGlyph *cg_glyphs; +- CGSize *cg_advances; ++ union { ++ CGSize *cg_advances; ++ CGPoint *cg_positions; ++ } u; + size_t nglyphs; + CGAffineTransform textTransform; +- CGFontRef font; ++ cairo_scaled_font_t *scaled_font; + CGPoint origin; + } unbounded_show_glyphs_t; + + typedef struct { + CGPathRef cgPath; + cairo_fill_rule_t fill_rule; + } unbounded_stroke_fill_t; + +@@ -686,36 +694,43 @@ static void + CGContextBeginPath (cgc); + CGContextAddPath (cgc, op->u.stroke_fill.cgPath); + + if (op->u.stroke_fill.fill_rule == CAIRO_FILL_RULE_WINDING) + CGContextFillPath (cgc); + else + CGContextEOFillPath (cgc); + } else if (op->op == UNBOUNDED_SHOW_GLYPHS) { +- CGContextSetFont (cgc, op->u.show_glyphs.font); +- CGContextSetFontSize (cgc, 1.0); +- CGContextSetTextMatrix (cgc, CGAffineTransformIdentity); +- CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y); +- CGContextConcatCTM (cgc, op->u.show_glyphs.textTransform); +- + if (op->u.show_glyphs.isClipping) { + /* Note that the comment in show_glyphs about kCGTextClip + * and the text transform still applies here; however, the + * cg_advances we have were already transformed, so we + * don't have to do anything. */ + CGContextSetTextDrawingMode (cgc, kCGTextClip); + CGContextSaveGState (cgc); + } +- +- CGContextShowGlyphsWithAdvances (cgc, +- op->u.show_glyphs.cg_glyphs, +- op->u.show_glyphs.cg_advances, +- op->u.show_glyphs.nglyphs); +- ++ CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y); ++ CGContextConcatCTM (cgc, op->u.show_glyphs.textTransform); ++ if (CTFontDrawGlyphsPtr) { ++ CTFontDrawGlyphsPtr (_cairo_quartz_scaled_font_get_ct_font_ref (op->u.show_glyphs.scaled_font), ++ op->u.show_glyphs.cg_glyphs, ++ op->u.show_glyphs.u.cg_positions, ++ op->u.show_glyphs.nglyphs, ++ cgc); ++ } else { ++ CGContextSetFont (cgc, _cairo_quartz_scaled_font_get_cg_font_ref (op->u.show_glyphs.scaled_font)); ++ CGContextSetFontSize (cgc, 1.0); ++ CGContextSetTextMatrix (cgc, CGAffineTransformIdentity); ++ ++ CGContextShowGlyphsWithAdvances (cgc, ++ op->u.show_glyphs.cg_glyphs, ++ op->u.show_glyphs.u.cg_advances, ++ op->u.show_glyphs.nglyphs); ++ ++ } + if (op->u.show_glyphs.isClipping) { + CGContextClearRect (cgc, clipBoxRound); + CGContextRestoreGState (cgc); + } + } else if (op->op == UNBOUNDED_MASK) { + CGAffineTransform ctm = CGContextGetCTM (cgc); + CGContextSaveGState (cgc); + CGContextConcatCTM (cgc, op->u.mask.maskTransform); +@@ -2684,16 +2699,19 @@ static cairo_int_status_t + cairo_clip_t *clip, + int *remaining_glyphs) + { + CGAffineTransform textTransform, ctm, invTextTransform; + #define STATIC_BUF_SIZE 64 + CGGlyph glyphs_static[STATIC_BUF_SIZE]; + CGSize cg_advances_static[STATIC_BUF_SIZE]; + CGGlyph *cg_glyphs = &glyphs_static[0]; ++ /* We'll use the cg_advances array for either advances or positions, ++ depending which API we're using to actually draw. The types involved ++ have the same size, so this is safe. */ + CGSize *cg_advances = &cg_advances_static[0]; + + cairo_rectangle_int_t glyph_extents; + cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; + cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; + cairo_quartz_drawing_state_t state; + cairo_quartz_float_t xprev, yprev; + int i; +@@ -2796,41 +2814,62 @@ static cairo_int_status_t + invTextTransform = CGAffineTransformMake (scaled_font->scale_inverse.xx, + -scaled_font->scale_inverse.yx, + scaled_font->scale_inverse.xy, + -scaled_font->scale_inverse.yy, + 0.0, 0.0); + + CGContextSetTextMatrix (state.context, CGAffineTransformIdentity); + +- /* Convert our glyph positions to glyph advances. We need n-1 advances, +- * since the advance at index 0 is applied after glyph 0. */ +- xprev = glyphs[0].x; +- yprev = glyphs[0].y; +- +- cg_glyphs[0] = glyphs[0].index; +- +- for (i = 1; i < num_glyphs; i++) { +- cairo_quartz_float_t xf = glyphs[i].x; +- cairo_quartz_float_t yf = glyphs[i].y; +- cg_glyphs[i] = glyphs[i].index; +- cg_advances[i - 1] = CGSizeApplyAffineTransform(CGSizeMake (xf - xprev, yf - yprev), invTextTransform); +- xprev = xf; +- yprev = yf; +- } +- + /* Translate to the first glyph's position before drawing */ + ctm = CGContextGetCTM (state.context); + CGContextTranslateCTM (state.context, glyphs[0].x, glyphs[0].y); + CGContextConcatCTM (state.context, textTransform); + +- CGContextShowGlyphsWithAdvances (state.context, +- cg_glyphs, +- cg_advances, +- num_glyphs); ++ if (CTFontDrawGlyphsPtr) { ++ /* If CTFontDrawGlyphs is available (i.e. OS X 10.7 or later), we want to use ++ * that in preference to CGContextShowGlyphsWithAdvances so that colored-bitmap ++ * fonts like Apple Color Emoji will render properly. ++ * For this, we need to convert our glyph positions to Core Graphics's CGPoint. ++ * We borrow the cg_advances array, as CGPoint and CGSize are the same size. */ ++ ++ CGPoint *cg_positions = (CGPoint*) cg_advances; ++ cairo_quartz_float_t origin_x = glyphs[0].x; ++ cairo_quartz_float_t origin_y = glyphs[0].y; ++ ++ for (i = 0; i < num_glyphs; i++) { ++ CGPoint pt = CGPointMake (glyphs[i].x - origin_x, glyphs[i].y - origin_y); ++ cg_positions[i] = CGPointApplyAffineTransform (pt, invTextTransform); ++ cg_glyphs[i] = glyphs[i].index; ++ } ++ ++ CTFontDrawGlyphsPtr (_cairo_quartz_scaled_font_get_ct_font_ref (scaled_font), ++ cg_glyphs, cg_positions, num_glyphs, state.context); ++ } else { ++ /* Convert our glyph positions to glyph advances. We need n-1 advances, ++ * since the advance at index 0 is applied after glyph 0. */ ++ xprev = glyphs[0].x; ++ yprev = glyphs[0].y; ++ ++ cg_glyphs[0] = glyphs[0].index; ++ ++ for (i = 1; i < num_glyphs; i++) { ++ cairo_quartz_float_t xf = glyphs[i].x; ++ cairo_quartz_float_t yf = glyphs[i].y; ++ cg_glyphs[i] = glyphs[i].index; ++ cg_advances[i - 1] = CGSizeApplyAffineTransform(CGSizeMake (xf - xprev, yf - yprev), invTextTransform); ++ xprev = xf; ++ yprev = yf; ++ } ++ ++ CGContextShowGlyphsWithAdvances (state.context, ++ cg_glyphs, ++ cg_advances, ++ num_glyphs); ++ } + + CGContextSetCTM (state.context, ctm); + + 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); +@@ -2847,20 +2886,27 @@ BAIL: + cgfref && + !_cairo_operator_bounded_by_mask (op)) + { + unbounded_op_data_t ub; + ub.op = UNBOUNDED_SHOW_GLYPHS; + + ub.u.show_glyphs.isClipping = isClipping; + ub.u.show_glyphs.cg_glyphs = cg_glyphs; +- ub.u.show_glyphs.cg_advances = cg_advances; ++ if (CTFontDrawGlyphsPtr) { ++ /* we're using Core Text API: the cg_advances array was ++ reused (above) for glyph positions */ ++ CGPoint *cg_positions = (CGPoint*) cg_advances; ++ ub.u.show_glyphs.u.cg_positions = cg_positions; ++ } else { ++ ub.u.show_glyphs.u.cg_advances = cg_advances; ++ } + ub.u.show_glyphs.nglyphs = num_glyphs; + ub.u.show_glyphs.textTransform = textTransform; +- ub.u.show_glyphs.font = cgfref; ++ ub.u.show_glyphs.scaled_font = scaled_font; + ub.u.show_glyphs.origin = CGPointMake (glyphs[0].x, glyphs[0].y); + + _cairo_quartz_fixup_unbounded_operation (surface, &ub, scaled_font->options.antialias); + } + + + if (cg_advances != &cg_advances_static[0]) { + free (cg_advances); -- cgit v1.2.3