Fixes for the 'xamarin' profile.
[mono.git] / bockbuild / MacSDK / patches / cairo-fix-color-bitmap-fonts.patch
1 diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
2 index a9bbbdc..48eb071 100644
3 --- a/src/cairo-quartz-font.c
4 +++ b/src/cairo-quartz-font.c
5 @@ -95,6 +95,10 @@ static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL;
6  static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL;
7  static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL;
8
9 +/* CTFontCreateWithGraphicsFont is not public until 10.5. */
10 +typedef const struct __CTFontDescriptor *CTFontDescriptorRef;
11 +static CTFontRef (*CTFontCreateWithGraphicsFontPtr) (CGFontRef, CGFloat, const CGAffineTransform *, CTFontDescriptorRef) = NULL;
12 +
13  /* Not public anymore in 64-bits nor in 10.7 */
14  static ATSFontRef (*FMGetATSFontRefFromFontPtr) (FMFont iFont) = NULL;
15
16 @@ -137,6 +141,8 @@ quartz_font_ensure_symbols(void)
17      CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
18      CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
19
20 +    CTFontCreateWithGraphicsFontPtr = dlsym(RTLD_DEFAULT, "CTFontCreateWithGraphicsFont");
21 +
22      FMGetATSFontRefFromFontPtr = dlsym(RTLD_DEFAULT, "FMGetATSFontRefFromFont");
23
24      if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
25 @@ -162,6 +168,7 @@ struct _cairo_quartz_font_face {
26      cairo_font_face_t base;
27
28      CGFontRef cgFont;
29 +    CTFontRef ctFont;
30  };
31
32  /*
33 @@ -246,6 +253,10 @@ _cairo_quartz_font_face_destroy (void *abstract_face)
34  {
35      cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
36
37 +    if (font_face->ctFont) {
38 +        CFRelease (font_face->ctFont);
39 +    }
40 +
41      CGFontRelease (font_face->cgFont);
42  }
43
44 @@ -370,6 +381,12 @@ cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
45
46      font_face->cgFont = CGFontRetain (font);
47
48 +    if (CTFontCreateWithGraphicsFontPtr) {
49 +        font_face->ctFont = CTFontCreateWithGraphicsFontPtr (font, 1.0, NULL, NULL);
50 +    } else {
51 +        font_face->ctFont = NULL;
52 +    }
53 +
54      _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
55
56      return &font_face->base;
57 @@ -812,6 +829,14 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
58      return ffont->cgFont;
59  }
60
61 +CTFontRef
62 +_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *abstract_font)
63 +{
64 +    cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
65 +
66 +    return ffont->ctFont;
67 +}
68 +
69  /*
70   * compat with old ATSUI backend
71   */
72 diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
73 index f841a49..3c1e5aa 100644
74 --- a/src/cairo-quartz-private.h
75 +++ b/src/cairo-quartz-private.h
76 @@ -57,6 +57,9 @@ typedef enum {
77      DO_TILED_IMAGE
78  } cairo_quartz_action_t;
79
80 +/* define CTFontRef for pre-10.5 SDKs */
81 +typedef const struct __CTFont *CTFontRef;
82 +
83  typedef struct cairo_quartz_surface {
84      cairo_surface_t base;
85
86 @@ -97,6 +100,9 @@ CairoQuartzCreateCGImage (cairo_format_t format,
87  cairo_private CGFontRef
88  _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
89
90 +CTFontRef
91 +_cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *sfont);
92 +
93  #else
94
95  # error Cairo was not compiled with support for the quartz backend
96 diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
97 index 1e2bbec..417255c 100644
98 --- a/src/cairo-quartz-surface.c
99 +++ b/src/cairo-quartz-surface.c
100 @@ -123,6 +123,9 @@ static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
101  static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
102  static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
103
104 +/* CTFontDrawGlyphs is not available until 10.7 */
105 +static void (*CTFontDrawGlyphsPtr) (CTFontRef, const CGGlyph[], const CGPoint[], size_t, CGContextRef) = NULL;
106 +
107  static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
108
109  /*
110 @@ -155,6 +158,8 @@ static void quartz_ensure_symbols (void)
111      CGContextGetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
112      CGContextSetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
113
114 +    CTFontDrawGlyphsPtr = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs");
115 +
116      _cairo_quartz_symbol_lookup_done = TRUE;
117  }
118
119 @@ -2026,30 +2031,50 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
120      CGContextSetTextPosition (state.cgMaskContext, 0.0, 0.0);
121      CGContextSetTextMatrix (state.cgMaskContext, CGAffineTransformIdentity);
122
123 -    /* Convert our glyph positions to glyph advances.  We need n-1 advances,
124 -     * since the advance at index 0 is applied after glyph 0. */
125 -    xprev = glyphs[0].x;
126 -    yprev = glyphs[0].y;
127 -
128 -    cg_glyphs[0] = glyphs[0].index;
129 -
130 -    for (i = 1; i < num_glyphs; i++) {
131 -       cairo_quartz_float_t xf = glyphs[i].x;
132 -       cairo_quartz_float_t yf = glyphs[i].y;
133 -       cg_glyphs[i] = glyphs[i].index;
134 -       cg_advances[i - 1] = CGSizeApplyAffineTransform (CGSizeMake (xf - xprev, yf - yprev), invTextTransform);
135 -       xprev = xf;
136 -       yprev = yf;
137 -    }
138 -
139      /* Translate to the first glyph's position before drawing */
140      CGContextTranslateCTM (state.cgMaskContext, glyphs[0].x, glyphs[0].y);
141      CGContextConcatCTM (state.cgMaskContext, textTransform);
142
143 -    CGContextShowGlyphsWithAdvances (state.cgMaskContext,
144 -                                    cg_glyphs,
145 -                                    cg_advances,
146 -                                    num_glyphs);
147 +    if (CTFontDrawGlyphsPtr) {
148 +        /* If CTFontDrawGlyphs is available (i.e. OS X 10.7 or later), we want to use
149 +         * that in preference to CGContextShowGlyphsWithAdvances so that colored-bitmap
150 +         * fonts like Apple Color Emoji will render properly.
151 +         * For this, we need to convert our glyph positions to Core Graphics's CGPoint.
152 +         * We borrow the cg_advances array, as CGPoint and CGSize are the same size. */
153 +
154 +        CGPoint *cg_positions = (CGPoint*) cg_advances;
155 +        cairo_quartz_float_t origin_x = glyphs[0].x;
156 +        cairo_quartz_float_t origin_y = glyphs[0].y;
157 +
158 +        for (i = 0; i < num_glyphs; i++) {
159 +            CGPoint pt = CGPointMake (glyphs[i].x - origin_x, glyphs[i].y - origin_y);
160 +            cg_positions[i] = CGPointApplyAffineTransform (pt, invTextTransform);
161 +            cg_glyphs[i] = glyphs[i].index;
162 +        }
163 +
164 +        CTFontDrawGlyphsPtr (_cairo_quartz_scaled_font_get_ct_font_ref (scaled_font),
165 +                             cg_glyphs, cg_positions, num_glyphs, state.cgMaskContext);
166 +    } else {
167 +        /* Convert our glyph positions to glyph advances.  We need n-1 advances,
168 +         * since the advance at index 0 is applied after glyph 0. */
169 +        xprev = glyphs[0].x;
170 +        yprev = glyphs[0].y;
171 +
172 +        cg_glyphs[0] = glyphs[0].index;
173 +
174 +        for (i = 1; i < num_glyphs; i++) {
175 +            cairo_quartz_float_t xf = glyphs[i].x;
176 +            cairo_quartz_float_t yf = glyphs[i].y;
177 +            cg_glyphs[i] = glyphs[i].index;
178 +            cg_advances[i - 1] = CGSizeApplyAffineTransform (CGSizeMake (xf - xprev, yf - yprev), invTextTransform);
179 +            xprev = xf;
180 +            yprev = yf;
181 +        }
182 +        CGContextShowGlyphsWithAdvances (state.cgMaskContext,
183 +                                         cg_glyphs,
184 +                                         cg_advances,
185 +                                         num_glyphs);
186 +    }
187
188      CGContextConcatCTM (state.cgMaskContext, invTextTransform);
189      CGContextTranslateCTM (state.cgMaskContext, -glyphs[0].x, -glyphs[0].y);