summaryrefslogtreecommitdiff
path: root/gfx/cairo/quartz-support-color-emoji-font.patch
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/cairo/quartz-support-color-emoji-font.patch
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/cairo/quartz-support-color-emoji-font.patch')
-rw-r--r--gfx/cairo/quartz-support-color-emoji-font.patch432
1 files changed, 432 insertions, 0 deletions
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 0000000000..5fb88b2717
--- /dev/null
+++ b/gfx/cairo/quartz-support-color-emoji-font.patch
@@ -0,0 +1,432 @@
+From: Jonathan Kew <jkew@mozilla.com>
+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);