[cairo-commit] 8 commits - configure.ac meson.build src/cairo-quartz-font.c src/cairo-quartz-private.h src/cairo-quartz-surface.c test/Makefile.am test/Makefile.sources test/meson.build test/quartz-color-font.c test/reference

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 27 00:04:46 UTC 2022


 configure.ac                                            |    7 
 meson.build                                             |   20 
 src/cairo-quartz-font.c                                 |  520 +++++++---------
 src/cairo-quartz-private.h                              |    6 
 src/cairo-quartz-surface.c                              |  259 +------
 test/Makefile.am                                        |    2 
 test/Makefile.sources                                   |    2 
 test/meson.build                                        |    1 
 test/quartz-color-font.c                                |   54 +
 test/reference/inverse-text.quartz.ref.png              |binary
 test/reference/overlapping-glyphs.quartz.argb32.ref.png |binary
 test/reference/overlapping-glyphs.quartz.rgb24.ref.png  |binary
 test/reference/pdf-operators-text.quartz.ref.png        |binary
 test/reference/quartz-color-font.quartz.rgb24.ref.png   |binary
 test/reference/quartz-color-font.ref.png                |binary
 test/reference/select-font-face.quartz.ref.png          |binary
 16 files changed, 359 insertions(+), 512 deletions(-)

New commits:
commit 455a4cca5472a309d036b6393f1db0dc4403d303
Merge: f07d539c0 cfb3835f5
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed Apr 27 00:04:43 2022 +0000

    Merge branch 'quartz-core-text' into 'master'
    
    quartz: support rendering colored bitmap fonts
    
    See merge request cairo/cairo!289

commit cfb3835f57abd05b5d862904dd1d4300ae990a8a
Author: John Ralls <jralls at ceridwen.us>
Date:   Tue Apr 26 12:44:54 2022 -0700

    [quartz] Add wiggle test for quartz emoji.

diff --git a/test/Makefile.am b/test/Makefile.am
index 8e271fe9b..a74d71a7c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,7 +27,7 @@ endif
 
 # Need to add quartz-surface-source
 if CAIRO_HAS_QUARTZ_SURFACE
-test_sources += $(quartz_surface_test_sources)
+test_sources += "$(quartz_surface_test_sources) $(quartz_color_font_test_sources)"
 endif
 
 if CAIRO_HAS_PDF_SURFACE
diff --git a/test/Makefile.sources b/test/Makefile.sources
index c180289ab..330aa9da1 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -434,6 +434,8 @@ egl_surface_test_sources = \
 
 quartz_surface_test_sources = quartz-surface-source.c
 
+quartz_color_font_test_sources = quartz-color-font.c
+
 pdf_surface_test_sources = \
 	pdf-features.c \
 	pdf-mime-data.c \
diff --git a/test/meson.build b/test/meson.build
index c0be0e086..21a0588e7 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -438,6 +438,7 @@ test_egl_sources = [
 
 test_quartz_sources = [
   'quartz-surface-source.c',
+  'quartz-color-font.c',
 ]
 
 test_pdf_sources = [
diff --git a/test/quartz-color-font.c b/test/quartz-color-font.c
new file mode 100644
index 000000000..7dae214f6
--- /dev/null
+++ b/test/quartz-color-font.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2022 John Ralls <jralls at ceridwen.us>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "cairo-test.h"
+#include <cairo-quartz.h>
+
+#define WIDTH  100
+#define HEIGHT 50
+
+#define FONT "Apple Color Emoji"
+
+static const char smiley_face_utf8[] = { 0xf0, 0x9f, 0x99, 0x82, 0x00 }; /* U+1F642 */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_select_font_face(cr, FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+    cairo_set_font_size (cr, HEIGHT/2);
+    cairo_move_to (cr, width/5, 2*height/3);
+
+    cairo_show_text(cr, smiley_face_utf8);
+    cairo_show_text(cr, smiley_face_utf8);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (quartz_color_font,
+	    "Test color font",
+	    "quartz, font", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, draw)
diff --git a/test/reference/quartz-color-font.quartz.rgb24.ref.png b/test/reference/quartz-color-font.quartz.rgb24.ref.png
new file mode 100644
index 000000000..00a0c4499
Binary files /dev/null and b/test/reference/quartz-color-font.quartz.rgb24.ref.png differ
diff --git a/test/reference/quartz-color-font.ref.png b/test/reference/quartz-color-font.ref.png
new file mode 100644
index 000000000..e52674ba0
Binary files /dev/null and b/test/reference/quartz-color-font.ref.png differ
commit 2784159d0e57b409477cfcb25ddcce3227379a6f
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Apr 23 14:36:15 2022 -0700

    [quartz] Adjust x_extents metric.
    
    CoreText uses different advances depending on the font size, with very
    small point sizes sometimes getting advances that are smaller than the
    glyph's width. This is manifested in the Apple Color Emoji font with the
    Emoji glyphs having a width of 1.25 and an advance width of 1.0. That
    results in overlapping emoji when they're in a string.
    
    The small spacing difference also affects 3 tests so updated reference
    images are included in this commit.
    
     # Please enter the commit message for your changes. Lines starting

diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 000a0e237..641a2dfc7 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -412,7 +412,12 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
     extents.y_bearing = - ymax;
     extents.width = xmax - xmin;
     extents.height = ymax - ymin;
-    extents.x_advance = advance.width;
+/* At the necessary 1.0pt ctFont size some glyphs get a reduced
+ * advance that causes overlaps when scaled up. We can avoid that by
+ * using the width instead if it's wider. Since cairo doesn't support
+ * vertical font layout we don't do the same for y_advance.
+ */
+    extents.x_advance = MAX(extents.width, advance.width);
     extents.y_advance = advance.height;
 
 #ifdef DEBUG
diff --git a/test/reference/inverse-text.quartz.ref.png b/test/reference/inverse-text.quartz.ref.png
index df0ea57ea..f57f45035 100644
Binary files a/test/reference/inverse-text.quartz.ref.png and b/test/reference/inverse-text.quartz.ref.png differ
diff --git a/test/reference/pdf-operators-text.quartz.ref.png b/test/reference/pdf-operators-text.quartz.ref.png
new file mode 100644
index 000000000..ecfa7cc5d
Binary files /dev/null and b/test/reference/pdf-operators-text.quartz.ref.png differ
diff --git a/test/reference/select-font-face.quartz.ref.png b/test/reference/select-font-face.quartz.ref.png
index 69fd2e239..1100fe28c 100644
Binary files a/test/reference/select-font-face.quartz.ref.png and b/test/reference/select-font-face.quartz.ref.png differ
commit c755e48c2e5da7f10956de1c3560180510e84d1f
Author: John Ralls <jralls at ceridwen.us>
Date:   Tue Apr 12 16:44:05 2022 -0700

    [quartz] Implement color font support.

diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 9e667e0d6..000a0e237 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -76,8 +76,10 @@ static const CGFloat font_scale = 1.0;
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
 #define FONT_ORIENTATION_HORIZONTAL kCTFontHorizontalOrientation
+#define FONT_COLOR_GLYPHS kCTFontTraitColorGlyphs
 #else
 #define FONT_ORIENTATION_HORIZONTAL kCTFontOrientationHorizontal
+#define FONT_COLOR_GLYPHS kCTFontColorGlyphsTrait
 #endif
 
 static void
@@ -410,7 +412,6 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
     extents.y_bearing = - ymax;
     extents.width = xmax - xmin;
     extents.height = ymax - ymin;
-
     extents.x_advance = advance.width;
     extents.y_advance = advance.height;
 
@@ -522,9 +523,19 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_bool_t
+_cairo_quartz_font_has_color_glyphs (void *abstract_font)
+{
+    cairo_quartz_scaled_font_t *face = (cairo_quartz_scaled_font_t*)abstract_font;
+    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits (face->ctFont);
+    return traits & FONT_COLOR_GLYPHS;
+}
+
 static cairo_int_status_t
 _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
-				  cairo_scaled_glyph_t *scaled_glyph)
+				  cairo_scaled_glyph_t *scaled_glyph,
+				  cairo_scaled_glyph_info_t info,
+				 const cairo_color_t *fg_color)
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_image_surface_t *surface = NULL;
@@ -538,6 +549,8 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
     CGAffineTransform textMatrix;
     CGRect glyphRect, glyphRectInt;
     CGPoint glyphOrigin;
+    cairo_bool_t is_color = info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
+    cairo_format_t format =  is_color ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_A8;
 
 #ifdef DEBUG
     fprintf (stderr, "[0x%04x] bearing: %f %f width %f height %f advances %f %f\n",
@@ -562,6 +575,19 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 	return CAIRO_STATUS_SUCCESS;
     }
 
+/* Note: Certain opentype color fonts have the ability to provide a
+ * mixture of color and not-color glyphs. The Core Text API doesn't
+ * expose a way to query individual glyphs and at the level that that
+ * API is written it's not supposed to matter. The following code will
+ * cheerfully render any glyph requested onto the image surface. If
+ * the font is capable of color and
+ * COLOR_SCALED_GLYPH_INFO_COLOR_SURFACE is set then you get back a
+ * CAIRO_FORMAT_ARGB32 surface. If a foreground color is provided then
+ * the glyph will be drawn in that color, otherwise it will be black.
+ */
+    if (unlikely (is_color && ! _cairo_quartz_font_has_color_glyphs (font)))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     /* scale(1,-1) * font->base.scale * scale(1,-1) */
     textMatrix = CGAffineTransformMake (font->base.scale.xx,
 					-font->base.scale.yx,
@@ -587,37 +613,47 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
     width = glyphRectInt.size.width;
     height = glyphRectInt.size.height;
 
-    surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+    surface = (cairo_image_surface_t*) cairo_image_surface_create (format, width, height);
     if (surface->base.status)
 	return surface->base.status;
 
     if (surface->width != 0 && surface->height != 0) {
+	CGColorSpaceRef colorspace = is_color ? CGColorSpaceCreateDeviceRGB () : NULL;
+	CGBitmapInfo bitinfo = is_color ? kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst : kCGImageAlphaOnly;
+
 	CGContextRef cgContext = CGBitmapContextCreate (surface->data,
 							surface->width,
 							surface->height,
 							8,
 							surface->stride,
-							NULL,
-							kCGImageAlphaOnly);
+							colorspace,
+							bitinfo);
 
 	if (cgContext == NULL) {
 	    cairo_surface_destroy (&surface->base);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
+	if (fg_color)
+	    CGContextSetRGBFillColor (cgContext, fg_color->red, fg_color->green, fg_color->blue, fg_color->alpha);
 	_cairo_quartz_set_antialiasing (cgContext, font->base.options.antialias);
 	CGContextSetAlpha (cgContext, 1.0);
 	CGContextTranslateCTM (cgContext, -glyphOrigin.x, -glyphOrigin.y);
 	CGContextConcatCTM (cgContext, textMatrix);
 	CTFontDrawGlyphs (font->ctFont, &glyph, &CGPointZero, 1, cgContext);
 	CGContextRelease (cgContext);
+	CGColorSpaceRelease (colorspace);
     }
 
     cairo_surface_set_device_offset (&surface->base,
 				     - glyphOrigin.x,
 				     height + glyphOrigin.y);
+    cairo_surface_mark_dirty (&surface->base);
 
-    _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
+    if (is_color)
+	_cairo_scaled_glyph_set_color_surface (scaled_glyph, &font->base, surface, fg_color != NULL);
+    else
+	_cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
 
     return status;
 }
@@ -637,8 +673,10 @@ _cairo_quartz_scaled_glyph_init (void *abstract_font,
     if (!status && (info & CAIRO_SCALED_GLYPH_INFO_PATH))
 	status = _cairo_quartz_init_glyph_path (font, scaled_glyph);
 
-    if (!status && (info & CAIRO_SCALED_GLYPH_INFO_SURFACE))
-	status = _cairo_quartz_init_glyph_surface (font, scaled_glyph);
+    if (!status && (info & (CAIRO_SCALED_GLYPH_INFO_SURFACE |
+			    CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE )))
+	status = _cairo_quartz_init_glyph_surface (font, scaled_glyph,
+						   info, foreground_color);
 
     return status;
 }
@@ -694,8 +732,11 @@ static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = {
     _cairo_quartz_ucs4_to_index,
     _cairo_quartz_load_truetype_table,
     NULL, /*index_to_ucs4*/
-}; /* is_synthetic, index_to_glyph_name, load_type1_data, has_color_glyphs */
-
+    NULL, /* is_synthetic */
+    NULL, /* index_to_glyph_name */
+    NULL, /* load_type1_data */
+    _cairo_quartz_font_has_color_glyphs
+};
 /*
  * private methods that the quartz surface uses
  */
commit c6dc5df61264be1bec2e622355b97c6c45d236fc
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Apr 21 17:19:15 2022 -0700

    [quartz] Convert font handling from CGFont to CTFont.

diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 3a702ca0e..9e667e0d6 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -44,6 +44,7 @@
 
 #include "cairo-error-private.h"
 
+//#define DEBUG /* Uncomment this to get debug messages on the console. */
 /**
  * SECTION:cairo-quartz-fonts
  * @Title: Quartz (CGFont) Fonts
@@ -66,11 +67,19 @@ static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
 static ATSFontRef (*FMGetATSFontRefFromFontPtr) (FMFont iFont) = NULL;
 
 static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
+/* Cairo's transformations assume a unit-scaled font. */
+static const CGFloat font_scale = 1.0;
 
 /* Defined in 10.11 */
 #define CGGLYPH_MAX ((CGGlyph) 0xFFFE) /* kCGFontIndexMax */
 #define CGGLYPH_INVALID ((CGGlyph) 0xFFFF) /* kCGFontIndexInvalid */
 
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+#define FONT_ORIENTATION_HORIZONTAL kCTFontHorizontalOrientation
+#else
+#define FONT_ORIENTATION_HORIZONTAL kCTFontOrientationHorizontal
+#endif
+
 static void
 quartz_font_ensure_symbols(void)
 {
@@ -90,14 +99,13 @@ typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
 
 struct _cairo_quartz_scaled_font {
     cairo_scaled_font_t base;
+    CTFontRef ctFont;
 };
 
 struct _cairo_quartz_font_face {
     cairo_font_face_t base;
 
     CGFontRef cgFont;
-    CTFontRef ctFont;
-    double ctFont_scale;
 };
 
 /*
@@ -111,7 +119,7 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
     const char *family;
     char *full_name;
     CFStringRef FontName = NULL;
-    CTFontRef ctFont = NULL;
+    CGFontRef cgFont = NULL;
     int loop;
 
     family = toy_face->family;
@@ -151,20 +159,20 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
 	}
 
 	FontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
-	ctFont = CTFontCreateWithName (FontName, 1.0, NULL);
+	cgFont = CGFontCreateWithFontName (FontName);
 	CFRelease (FontName);
 
-	if (ctFont)
+	if (cgFont)
 	    break;
     }
 
-    if (!ctFont) {
+    if (!cgFont) {
 	/* Give up */
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    *font_face = _cairo_quartz_font_face_create_for_ctfont (ctFont);
-    CFRelease (ctFont);
+    *font_face = cairo_quartz_font_face_create_for_cgfont (cgFont);
+    CFRelease (cgFont);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -175,12 +183,56 @@ _cairo_quartz_font_face_destroy (void *abstract_face)
     cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
 
     CGFontRelease (font_face->cgFont);
-    CFRelease (font_face->ctFont);
     return TRUE;
 }
 
 static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend;
 
+#ifdef DEBUG
+static void
+_cairo_quartz_debug_font_characteristics (cairo_quartz_scaled_font_t *font)
+{
+    CGRect ct_bbox = CTFontGetBoundingBox (font->ctFont);
+    CGFloat ct_ascent = CTFontGetAscent (font->ctFont);
+    CGFloat ct_descent = CTFontGetDescent (font->ctFont);
+    CGFloat ct_leading = CTFontGetLeading (font->ctFont);
+    CGFloat ct_capheight = CTFontGetCapHeight (font->ctFont);
+    CGFloat ct_xheight = CTFontGetXHeight (font->ctFont);
+    char chars[] = "ymMW";
+    CGGlyph glyphs[4];
+    UniChar *utf16 = NULL;
+    CGSize ct_advances[4];
+    CGRect ct_gbbox[4], ct_gobox[4], ct_rbbox, ct_robox;
+    double ct_radvance;
+    int converted;
+    cairo_status_t rv;
+
+    rv = _cairo_utf8_to_utf16 (chars, 4, &utf16, &converted);
+    if (rv) return;
+    CTFontGetGlyphsForCharacters (font->ctFont, utf16, glyphs, 4);
+    free (utf16);
+    ct_rbbox = CTFontGetBoundingRectsForGlyphs (font->ctFont, FONT_ORIENTATION_HORIZONTAL, glyphs, ct_gbbox, 4);
+    ct_robox = CTFontGetOpticalBoundsForGlyphs (font->ctFont, glyphs, ct_gobox, 4, 0);
+    ct_radvance = CTFontGetAdvancesForGlyphs (font->ctFont, FONT_ORIENTATION_HORIZONTAL, glyphs, ct_advances, 4);
+
+    fprintf (stderr, "\nCTFont Bounding Box: %f %f %f %f\nAscent %f Descent %f Leading %f Cap Height %f X-Height %f\n",
+	     ct_bbox.origin.x, ct_bbox.origin.y, ct_bbox.size.width, ct_bbox.size.height, ct_ascent, ct_descent,
+	     ct_leading, ct_capheight, ct_xheight);
+    fprintf (stderr, "CTFont string\n\t bounding box %f %f %f %f advance %f\n\toptical box %f %f %f %f\n\n",
+	     ct_rbbox.origin.x, ct_rbbox.origin.y, ct_rbbox.size.width, ct_rbbox.size.height, ct_radvance,
+	     ct_robox.origin.x, ct_robox.origin.y, ct_robox.size.width, ct_robox.size.height);
+    for (int i = 0; i < 4; ++i)
+    {
+	fprintf (stderr, "Character %c\n", chars[i]);
+	fprintf (stderr, "\tbox %f %f %f %f\n\toptical %f %f %f %f advance %f %f\n",
+		 ct_gbbox[i].origin.x, ct_gbbox[i].origin.y, ct_gbbox[i].size.width, ct_gbbox[i].size.height,
+		 ct_advances[i].width, ct_advances[i].height,
+		 ct_gobox[i].origin.x, ct_gobox[i].origin.y, ct_gobox[i].size.width, ct_gobox[i].size.height);
+    }
+    fprintf (stderr, "\n");
+}
+#endif
+
 static cairo_status_t
 _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
 					    const cairo_matrix_t *font_matrix,
@@ -192,7 +244,7 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
     cairo_quartz_scaled_font_t *font = NULL;
     cairo_status_t status;
     cairo_font_extents_t fs_metrics;
-    double ems;
+    CTFontRef ctFont;
     CGRect bbox;
 
     font = _cairo_malloc (sizeof(cairo_quartz_scaled_font_t));
@@ -207,19 +259,29 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
     if (status)
 	goto FINISH;
 
-    ems = CGFontGetUnitsPerEm (font_face->cgFont);
-
+    ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, font_scale, NULL, NULL);
     /* initialize metrics */
-    fs_metrics.ascent = (CGFontGetAscent (font_face->cgFont) / ems);
-    fs_metrics.descent = - (CGFontGetDescent (font_face->cgFont) / ems);
+    fs_metrics.ascent = CTFontGetAscent (ctFont);
+    fs_metrics.descent = CTFontGetDescent (ctFont);
     fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
-	(CGFontGetLeading (font_face->cgFont) / ems);
+	CTFontGetLeading (ctFont);
 
-    bbox = CGFontGetFontBBox (font_face->cgFont);
-    fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
+    bbox = CTFontGetBoundingBox (ctFont);
+    fs_metrics.max_x_advance = CGRectGetMaxX(bbox);
     fs_metrics.max_y_advance = 0.0;
-
+    font->ctFont = CFRetain (ctFont);
     status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics);
+#ifdef DEBUG
+    {
+	CFStringRef fontFullName = CTFontCopyFullName (ctFont);
+	const char* font_full_name = CFStringGetCStringPtr(fontFullName, kCFStringEncodingUTF8);
+
+	fprintf (stderr, "Create scaled font %s with scale %f ascent %f, descent %f, height %f, x-advance %f\n",
+		 font_full_name, fs_metrics.ascent, fs_metrics.descent, fs_metrics.height,
+		 fs_metrics.max_x_advance);
+	_cairo_quartz_debug_font_characteristics (font);
+    }
+#endif
 
 FINISH:
     if (status != CAIRO_STATUS_SUCCESS) {
@@ -272,29 +334,11 @@ cairo_font_face_t *
 cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
 {
     cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
-    double font_scale = 1.0; /* 1.0 produces glyphs of the right size to pass tests. */
 
     if (cairo_font_face_status (&font_face->base))
 	return &font_face->base;
 
     font_face->cgFont = CGFontRetain (font);
-    font_face->ctFont = CTFontCreateWithGraphicsFont (font, font_scale, NULL, NULL);
-    font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
-
-    return &font_face->base;
-}
-
-cairo_font_face_t *
-_cairo_quartz_font_face_create_for_ctfont (CTFontRef font)
-{
-    cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
-
-    if (cairo_font_face_status (&font_face->base))
-	return &font_face->base;
-
-    font_face->ctFont = CFRetain (font);
-    font_face->cgFont = CTFontCopyGraphicsFont (font, NULL);
-    font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
 
     return &font_face->base;
 }
@@ -315,6 +359,8 @@ _cairo_quartz_scaled_to_face (void *abstract_font)
 static void
 _cairo_quartz_scaled_font_fini(void *abstract_font)
 {
+    cairo_quartz_scaled_font_t* font = (cairo_quartz_scaled_font_t*)abstract_font;
+    CFRelease (font->ctFont);
 }
 
 static inline CGGlyph
@@ -329,21 +375,17 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
 
-    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
     cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
-    int advance;
+    CGSize advance;
     CGRect bbox;
-    double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
     double xmin, ymin, xmax, ymax;
 
     if (unlikely (glyph == CGGLYPH_INVALID))
 	goto FAIL;
 
-    if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
-	!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
-	goto FAIL;
-
+    CTFontGetAdvancesForGlyphs (font->ctFont, FONT_ORIENTATION_HORIZONTAL, &glyph, &advance, 1);
+    CTFontGetBoundingRectsForGlyphs (font->ctFont, FONT_ORIENTATION_HORIZONTAL, &glyph, &bbox, 1);
     /* broken fonts like Al Bayan return incorrect bounds for some null characters,
        see https://bugzilla.mozilla.org/show_bug.cgi?id=534260 */
     if (unlikely (bbox.origin.x == -32767 &&
@@ -354,31 +396,9 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
         bbox.size.width = bbox.size.height = 0;
     }
 
-    bbox = CGRectMake (bbox.origin.x / emscale,
-		       bbox.origin.y / emscale,
-		       bbox.size.width / emscale,
-		       bbox.size.height / emscale);
-
-    /* Should we want to always integer-align glyph extents, we can do so in this way */
-#if 0
-    {
-	CGAffineTransform textMatrix;
-	textMatrix = CGAffineTransformMake (font->base.scale.xx,
-					    -font->base.scale.yx,
-					    -font->base.scale.xy,
-					    font->base.scale.yy,
-					    0.0f, 0.0f);
-
-	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
-	bbox = CGRectIntegral (bbox);
-	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
-    }
-#endif
-
-#if 0
-    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
-	     bbox.origin.x / emscale, bbox.origin.y / emscale,
-	     bbox.size.width / emscale, bbox.size.height / emscale);
+#ifdef DEBUG
+    fprintf (stderr, "[0x%04x] bbox: x %f y %f width %f height %f\n", glyph,
+	     bbox.origin.x, bbox.origin.y, bbox.size.width, bbox.size.height);
 #endif
 
     xmin = CGRectGetMinX(bbox);
@@ -391,12 +411,12 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
     extents.width = xmax - xmin;
     extents.height = ymax - ymin;
 
-    extents.x_advance = (double) advance / emscale;
-    extents.y_advance = 0.0;
+    extents.x_advance = advance.width;
+    extents.y_advance = advance.height;
 
-#if 0
-    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
-	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
+#ifdef DEBUG
+    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f %f\n\n", glyph,
+	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance);
 #endif
 
   FAIL:
@@ -452,7 +472,7 @@ _cairo_quartz_path_apply_func (void *info, const CGPathElement *el)
 						 _cairo_fixed_from_double(el->points[1].y),
 						 _cairo_fixed_from_double(el->points[2].x),
 						 _cairo_fixed_from_double(el->points[2].y));
-	    assert(!status);	    
+	    assert(!status);
 	    break;
 	case kCGPathElementCloseSubpath:
 	    status = _cairo_path_fixed_close_path (path);
@@ -465,7 +485,6 @@ static cairo_int_status_t
 _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
 			       cairo_scaled_glyph_t *scaled_glyph)
 {
-    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
     CGAffineTransform textMatrix;
     CGPathRef glyphPath;
@@ -483,7 +502,7 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
 					-font->base.scale.yy,
 					0, 0);
 
-    glyphPath = CTFontCreatePathForGlyph (font_face->ctFont, glyph, &textMatrix);
+    glyphPath = CTFontCreatePathForGlyph (font->ctFont, glyph, &textMatrix);
 
     if (!glyphPath)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -508,25 +527,25 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 				  cairo_scaled_glyph_t *scaled_glyph)
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
-
-    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
-
     cairo_image_surface_t *surface = NULL;
 
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
-
-    int advance;
-    CGRect bbox;
+    cairo_text_extents_t metrics = scaled_glyph->fs_metrics;
+    CGRect bbox = CGRectMake (metrics.x_bearing, -(metrics.y_bearing + metrics.height),
+			      metrics.width, metrics.height);
     double width, height;
-    double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
 
-    CGContextRef cgContext = NULL;
     CGAffineTransform textMatrix;
     CGRect glyphRect, glyphRectInt;
     CGPoint glyphOrigin;
 
-    //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
-
+#ifdef DEBUG
+    fprintf (stderr, "[0x%04x] bearing: %f %f width %f height %f advances %f %f\n",
+	     glyph, metrics.x_bearing, metrics.y_bearing, metrics.width, metrics.height,
+	     metrics.x_advance, metrics.y_advance);
+    fprintf (stderr, "[0x%04x] bounds: origin %f %f, size %f %f\n", glyph, bbox.origin.x,
+	     bbox.origin.y, bbox.size.width, bbox.size.height);
+#endif
     /* Create blank 2x2 image if we don't have this character.
      * Maybe we should draw a better missing-glyph slug or something,
      * but this is ok for now.
@@ -543,27 +562,20 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    CTFontGetBoundingRectsForGlyphs (font_face->ctFont, FONT_ORIENTATION_HORIZONTAL, &glyph, &bbox, 1);
-
     /* scale(1,-1) * font->base.scale * scale(1,-1) */
     textMatrix = CGAffineTransformMake (font->base.scale.xx,
 					-font->base.scale.yx,
 					-font->base.scale.xy,
 					font->base.scale.yy,
-					0, -0);
-    glyphRect = CGRectMake (bbox.origin.x / emscale,
-			    bbox.origin.y / emscale,
-			    bbox.size.width / emscale,
-			    bbox.size.height / emscale);
-
-    glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
+					0, 0);
+    glyphRect = CGRectApplyAffineTransform (bbox, textMatrix);
 
     /* Round the rectangle outwards, so that we don't have to deal
      * with non-integer-pixel origins or dimensions.
      */
     glyphRectInt = CGRectIntegral (glyphRect);
 
-#if 0
+#ifdef DEBUG
     fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
 	     glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
     fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
@@ -572,63 +584,32 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 
     glyphOrigin = glyphRectInt.origin;
 
-    //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
-
     width = glyphRectInt.size.width;
     height = glyphRectInt.size.height;
 
-    //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
-
     surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
     if (surface->base.status)
 	return surface->base.status;
 
     if (surface->width != 0 && surface->height != 0) {
-	cgContext = CGBitmapContextCreate (surface->data,
-					   surface->width,
-					   surface->height,
-					   8,
-					   surface->stride,
-					   NULL,
-					   kCGImageAlphaOnly);
+	CGContextRef cgContext = CGBitmapContextCreate (surface->data,
+							surface->width,
+							surface->height,
+							8,
+							surface->stride,
+							NULL,
+							kCGImageAlphaOnly);
 
 	if (cgContext == NULL) {
 	    cairo_surface_destroy (&surface->base);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
-	CGContextSetFont (cgContext, font_face->cgFont);
-	CGContextSetFontSize (cgContext, 1.0);
-	CGContextSetTextMatrix (cgContext, textMatrix);
-
-	switch (font->base.options.antialias) {
-	case CAIRO_ANTIALIAS_SUBPIXEL:
-	case CAIRO_ANTIALIAS_BEST:
-	    CGContextSetShouldAntialias (cgContext, TRUE);
-	    CGContextSetShouldSmoothFonts (cgContext, TRUE);
-	    quartz_font_ensure_symbols ();
-	    if (CGContextGetAllowsFontSmoothingPtr &&
-		!CGContextGetAllowsFontSmoothingPtr (cgContext))
-		CGContextSetAllowsFontSmoothing (cgContext, TRUE);
-	    break;
-	case CAIRO_ANTIALIAS_NONE:
-	    CGContextSetShouldAntialias (cgContext, FALSE);
-	    break;
-	case CAIRO_ANTIALIAS_GRAY:
-	case CAIRO_ANTIALIAS_GOOD:
-	case CAIRO_ANTIALIAS_FAST:
-	    CGContextSetShouldAntialias (cgContext, TRUE);
-	    CGContextSetShouldSmoothFonts (cgContext, FALSE);
-	    break;
-	case CAIRO_ANTIALIAS_DEFAULT:
-	default:
-	    /* Don't do anything */
-	    break;
-	}
-
+	_cairo_quartz_set_antialiasing (cgContext, font->base.options.antialias);
 	CGContextSetAlpha (cgContext, 1.0);
-	CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
-
+	CGContextTranslateCTM (cgContext, -glyphOrigin.x, -glyphOrigin.y);
+	CGContextConcatCTM (cgContext, textMatrix);
+	CTFontDrawGlyphs (font->ctFont, &glyph, &CGPointZero, 1, cgContext);
 	CGContextRelease (cgContext);
     }
 
@@ -667,12 +648,11 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
 			     uint32_t ucs4)
 {
     cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
-    cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
     CGGlyph glyph[2];
     UniChar utf16[2];
 
     int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
-    CTFontGetGlyphsForCharacters (ffont->ctFont, utf16, glyph, len);
+    CTFontGetGlyphsForCharacters (font->ctFont, utf16, glyph, len);
     return glyph[0];
 }
 
@@ -683,8 +663,8 @@ _cairo_quartz_load_truetype_table (void	            *abstract_font,
 				   unsigned char    *buffer,
 				   unsigned long    *length)
 {
-    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face (abstract_font);
-    CFDataRef data = CGFontCopyTableForTag (font_face->cgFont, tag);
+    cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
+    CFDataRef data = CTFontCopyTable (font->ctFont, tag, kCTFontTableOptionNoOptions);
 
     if (!data)
         return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -728,6 +708,43 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
     return ffont->cgFont;
 }
 
+CTFontRef
+_cairo_quartz_scaled_font_get_ct_font (cairo_scaled_font_t *abstract_font)
+{
+    cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
+
+    return font->ctFont;
+}
+
+ void
+ _cairo_quartz_set_antialiasing (CGContextRef cgContext, cairo_antialias_t antialias)
+{
+	switch (antialias) {
+	case CAIRO_ANTIALIAS_SUBPIXEL:
+	case CAIRO_ANTIALIAS_BEST:
+	    CGContextSetShouldAntialias (cgContext, TRUE);
+	    CGContextSetShouldSmoothFonts (cgContext, TRUE);
+	    quartz_font_ensure_symbols ();
+	    if (CGContextGetAllowsFontSmoothingPtr &&
+		!CGContextGetAllowsFontSmoothingPtr (cgContext))
+		CGContextSetAllowsFontSmoothing (cgContext, TRUE);
+	    break;
+	case CAIRO_ANTIALIAS_NONE:
+	    CGContextSetShouldAntialias (cgContext, FALSE);
+	    break;
+	case CAIRO_ANTIALIAS_GRAY:
+	case CAIRO_ANTIALIAS_GOOD:
+	case CAIRO_ANTIALIAS_FAST:
+	    CGContextSetShouldAntialias (cgContext, TRUE);
+	    CGContextSetShouldSmoothFonts (cgContext, FALSE);
+	    break;
+	case CAIRO_ANTIALIAS_DEFAULT:
+	default:
+	    /* Don't do anything */
+	    break;
+	}
+
+}
 /*
  * compat with old ATSUI backend
  */
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index e3600d5fc..f142f8471 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -109,6 +109,8 @@ cairo_private CTFontRef
 _cairo_quartz_scaled_font_get_ct_font (cairo_scaled_font_t *sfont);
 cairo_private cairo_font_face_t*
 _cairo_quartz_font_face_create_for_ctfont (CTFontRef ctFont);
+cairo_private void
+_cairo_quartz_set_antialiasing (CGContextRef context, cairo_antialias_t antialias);
 
 #else
 
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index bc6968c06..ae6546029 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -65,6 +65,12 @@
 #endif
 
 #define IS_EMPTY(s) ((s)->extents.width == 0 || (s)->extents.height == 0)
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+#define FONT_ORIENTATION_HORIZONTAL kCTFontHorizontalOrientation
+#else
+#define FONT_ORIENTATION_HORIZONTAL kCTFontOrientationHorizontal
+#endif
+
 
 /**
  * SECTION:cairo-quartz
@@ -1894,17 +1900,15 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
 			 cairo_bool_t overlap)
 {
     CGAffineTransform textTransform, invTextTransform;
-    CGGlyph glyphs_static[CAIRO_STACK_ARRAY_LENGTH (CGSize)];
-    CGSize cg_advances_static[CAIRO_STACK_ARRAY_LENGTH (CGSize)];
+    CGGlyph glyphs_static[CAIRO_STACK_ARRAY_LENGTH (CGGlyph)];
+    CGPoint cg_positions_static[CAIRO_STACK_ARRAY_LENGTH (CGPoint)];
     CGGlyph *cg_glyphs = &glyphs_static[0];
-    CGSize *cg_advances = &cg_advances_static[0];
-    COMPILE_TIME_ASSERT (sizeof (CGGlyph) <= sizeof (CGSize));
+    CGPoint *cg_positions = &cg_positions_static[0];
 
     cairo_quartz_drawing_state_t state;
     cairo_int_status_t rv = CAIRO_INT_STATUS_UNSUPPORTED;
-    cairo_quartz_float_t xprev, yprev;
-    int i;
-    CGFontRef cgfref = NULL;
+    CGPoint origin;
+    CTFontRef ctFont = NULL;
 
     cairo_bool_t didForceFontSmoothing = FALSE;
 
@@ -1923,45 +1927,17 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
     }
 
     /* this doesn't addref */
-    cgfref = _cairo_quartz_scaled_font_get_cg_font_ref (scaled_font);
-    CGContextSetFont (state.cgMaskContext, cgfref);
-    CGContextSetFontSize (state.cgMaskContext, 1.0);
-
-    switch (scaled_font->options.antialias) {
-	case CAIRO_ANTIALIAS_SUBPIXEL:
-	case CAIRO_ANTIALIAS_BEST:
-	    CGContextSetShouldAntialias (state.cgMaskContext, TRUE);
-	    CGContextSetShouldSmoothFonts (state.cgMaskContext, TRUE);
-	    quartz_ensure_symbols();
-	    if (CGContextGetAllowsFontSmoothingPtr &&
-		!CGContextGetAllowsFontSmoothingPtr (state.cgMaskContext))
-	    {
-		didForceFontSmoothing = TRUE;
-		CGContextSetAllowsFontSmoothing (state.cgMaskContext, TRUE);
-	    }
-	    break;
-	case CAIRO_ANTIALIAS_NONE:
-	    CGContextSetShouldAntialias (state.cgMaskContext, FALSE);
-	    break;
-	case CAIRO_ANTIALIAS_GRAY:
-	case CAIRO_ANTIALIAS_GOOD:
-	case CAIRO_ANTIALIAS_FAST:
-	    CGContextSetShouldAntialias (state.cgMaskContext, TRUE);
-	    CGContextSetShouldSmoothFonts (state.cgMaskContext, FALSE);
-	    break;
-	case CAIRO_ANTIALIAS_DEFAULT:
-	    /* Don't do anything */
-	    break;
-    }
+    ctFont = _cairo_quartz_scaled_font_get_ct_font (scaled_font);
+    _cairo_quartz_set_antialiasing (state.cgMaskContext, scaled_font->options.antialias);
 
     if (num_glyphs > ARRAY_LENGTH (glyphs_static)) {
-	cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof (CGGlyph) + sizeof (CGSize));
+	cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof (CGGlyph) + sizeof (CGPoint));
 	if (unlikely (cg_glyphs == NULL)) {
 	    rv = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL;
 	}
 
-	cg_advances = (CGSize*) (cg_glyphs + num_glyphs);
+	cg_positions = (CGPoint*) (cg_glyphs + num_glyphs);
     }
 
     /* scale(1,-1) * scaled_font->scale */
@@ -1978,36 +1954,23 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
 					      -scaled_font->scale_inverse.yy,
 					      0.0, 0.0);
 
-    CGContextSetTextPosition (state.cgMaskContext, 0.0, 0.0);
-    CGContextSetTextMatrix (state.cgMaskContext, 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;
+    origin = CGPointMake (glyphs[0].x, glyphs[0].y);
+    for (int i = 0; i < num_glyphs; ++i)
+    {
 	cg_glyphs[i] = glyphs[i].index;
-	cg_advances[i - 1] = CGSizeApplyAffineTransform (CGSizeMake (xf - xprev, yf - yprev), invTextTransform);
-	xprev = xf;
-	yprev = yf;
+	cg_positions[i] = CGPointMake (glyphs[i].x - origin.x, glyphs[i].y - origin.y);
+	cg_positions[i] = CGPointApplyAffineTransform (cg_positions[i], invTextTransform);
     }
 
     /* Translate to the first glyph's position before drawing */
-    CGContextTranslateCTM (state.cgMaskContext, glyphs[0].x, glyphs[0].y);
+    CGContextTranslateCTM (state.cgMaskContext, origin.x, origin.y);
     CGContextConcatCTM (state.cgMaskContext, textTransform);
 
-    CGContextShowGlyphsWithAdvances (state.cgMaskContext,
-				     cg_glyphs,
-				     cg_advances,
-				     num_glyphs);
+    CTFontDrawGlyphs (ctFont, cg_glyphs, cg_positions, num_glyphs, state.cgMaskContext);
 
     CGContextConcatCTM (state.cgMaskContext, invTextTransform);
-    CGContextTranslateCTM (state.cgMaskContext, -glyphs[0].x, -glyphs[0].y);
+    CGContextTranslateCTM (state.cgMaskContext, -origin.x, -origin.y);
 
     if (state.action != DO_DIRECT)
 	_cairo_quartz_draw_source (&state, extents->op);
diff --git a/test/reference/overlapping-glyphs.quartz.argb32.ref.png b/test/reference/overlapping-glyphs.quartz.argb32.ref.png
index 2bbbb3944..44200d59e 100644
Binary files a/test/reference/overlapping-glyphs.quartz.argb32.ref.png and b/test/reference/overlapping-glyphs.quartz.argb32.ref.png differ
diff --git a/test/reference/overlapping-glyphs.quartz.rgb24.ref.png b/test/reference/overlapping-glyphs.quartz.rgb24.ref.png
index a3961f8bf..d236e19a5 100644
Binary files a/test/reference/overlapping-glyphs.quartz.rgb24.ref.png and b/test/reference/overlapping-glyphs.quartz.rgb24.ref.png differ
commit cf351a8a0a5c0be291061f58db9853a95b9044d3
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Apr 9 11:16:11 2022 -0700

    Reimplement cairo-quartz-font with Core Text.

diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index a9480a736..3a702ca0e 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -47,12 +47,9 @@
 /**
  * SECTION:cairo-quartz-fonts
  * @Title: Quartz (CGFont) Fonts
- * @Short_Description: Font support via CGFont on OS X
+ * @Short_Description: Font support via Core Text on Apple operating systems.
  * @See_Also: #cairo_font_face_t
  *
- * The Quartz font backend is primarily used to render text on Apple
- * MacOS X systems.  The CGFont API is used for the internal
- * implementation of the font backend methods.
  **/
 
 /**
@@ -99,6 +96,8 @@ struct _cairo_quartz_font_face {
     cairo_font_face_t base;
 
     CGFontRef cgFont;
+    CTFontRef ctFont;
+    double ctFont_scale;
 };
 
 /*
@@ -111,8 +110,8 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
 {
     const char *family;
     char *full_name;
-    CFStringRef cgFontName = NULL;
-    CGFontRef cgFont = NULL;
+    CFStringRef FontName = NULL;
+    CTFontRef ctFont = NULL;
     int loop;
 
     family = toy_face->family;
@@ -141,31 +140,31 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
 
 	if (loop < 3 && (loop & 1) == 0) {
 	    if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
-		strcat (full_name, " Bold");
+		strcat (full_name, "-Bold");
 	}
 
 	if (loop < 3 && (loop & 2) == 0) {
 	    if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
-		strcat (full_name, " Italic");
+		strcat (full_name, "-Italic");
 	    else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
-		strcat (full_name, " Oblique");
+		strcat (full_name, "-Oblique");
 	}
 
-	cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
-	cgFont = CGFontCreateWithFontName (cgFontName);
-	CFRelease (cgFontName);
+	FontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
+	ctFont = CTFontCreateWithName (FontName, 1.0, NULL);
+	CFRelease (FontName);
 
-	if (cgFont)
+	if (ctFont)
 	    break;
     }
 
-    if (!cgFont) {
+    if (!ctFont) {
 	/* Give up */
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    *font_face = cairo_quartz_font_face_create_for_cgfont (cgFont);
-    CGFontRelease (cgFont);
+    *font_face = _cairo_quartz_font_face_create_for_ctfont (ctFont);
+    CFRelease (ctFont);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -176,6 +175,7 @@ _cairo_quartz_font_face_destroy (void *abstract_face)
     cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
 
     CGFontRelease (font_face->cgFont);
+    CFRelease (font_face->ctFont);
     return TRUE;
 }
 
@@ -238,6 +238,23 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
     _cairo_quartz_font_face_scaled_font_create
 };
 
+static inline cairo_quartz_font_face_t*
+_cairo_quartz_font_face_create ()
+{
+    cairo_quartz_font_face_t *font_face =
+	_cairo_malloc (sizeof (cairo_quartz_font_face_t));
+
+    if (!font_face) {
+	cairo_status_t ignore_status;
+	ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_quartz_font_face_t *)&_cairo_font_face_nil;
+    }
+
+    _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
+
+    return font_face;
+}
+
 /**
  * cairo_quartz_font_face_create_for_cgfont:
  * @font: a #CGFontRef obtained through a method external to cairo.
@@ -254,18 +271,30 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
 cairo_font_face_t *
 cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
 {
-    cairo_quartz_font_face_t *font_face =
-	_cairo_malloc (sizeof (cairo_quartz_font_face_t));
+    cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
+    double font_scale = 1.0; /* 1.0 produces glyphs of the right size to pass tests. */
 
-    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;
-    }
+    if (cairo_font_face_status (&font_face->base))
+	return &font_face->base;
 
     font_face->cgFont = CGFontRetain (font);
+    font_face->ctFont = CTFontCreateWithGraphicsFont (font, font_scale, NULL, NULL);
+    font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
 
-    _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
+    return &font_face->base;
+}
+
+cairo_font_face_t *
+_cairo_quartz_font_face_create_for_ctfont (CTFontRef font)
+{
+    cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
+
+    if (cairo_font_face_status (&font_face->base))
+	return &font_face->base;
+
+    font_face->ctFont = CFRetain (font);
+    font_face->cgFont = CTFontCopyGraphicsFont (font, NULL);
+    font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
 
     return &font_face->base;
 }
@@ -439,7 +468,6 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
     cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
     CGAffineTransform textMatrix;
-    CTFontRef ctFont;
     CGPathRef glyphPath;
     cairo_path_fixed_t *path;
 
@@ -455,9 +483,7 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
 					-font->base.scale.yy,
 					0, 0);
 
-    ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL);
-    glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
-    CFRelease (ctFont);
+    glyphPath = CTFontCreatePathForGlyph (font_face->ctFont, glyph, &textMatrix);
 
     if (!glyphPath)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -517,11 +543,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
-	!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
-    {
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    CTFontGetBoundingRectsForGlyphs (font_face->ctFont, FONT_ORIENTATION_HORIZONTAL, &glyph, &bbox, 1);
 
     /* scale(1,-1) * font->base.scale * scale(1,-1) */
     textMatrix = CGAffineTransformMake (font->base.scale.xx,
@@ -646,13 +668,11 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
 {
     cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
     cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
-    CTFontRef ctFont;
     CGGlyph glyph[2];
     UniChar utf16[2];
 
     int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
-    ctFont = CTFontCreateWithGraphicsFont(ffont->cgFont, 10.0, NULL, NULL);
-    CTFontGetGlyphsForCharacters (ctFont, utf16, glyph, len);
+    CTFontGetGlyphsForCharacters (ffont->ctFont, utf16, glyph, len);
     return glyph[0];
 }
 
@@ -693,8 +713,8 @@ static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = {
     NULL, /* text_to_glyphs */
     _cairo_quartz_ucs4_to_index,
     _cairo_quartz_load_truetype_table,
-    NULL, /* map_glyphs_to_unicode */
-};
+    NULL, /*index_to_ucs4*/
+}; /* is_synthetic, index_to_glyph_name, load_type1_data, has_color_glyphs */
 
 /*
  * private methods that the quartz surface uses
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index 609a9052c..e3600d5fc 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -105,6 +105,10 @@ CairoQuartzCreateCGImage (cairo_format_t format,
 
 cairo_private CGFontRef
 _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
+cairo_private CTFontRef
+_cairo_quartz_scaled_font_get_ct_font (cairo_scaled_font_t *sfont);
+cairo_private cairo_font_face_t*
+_cairo_quartz_font_face_create_for_ctfont (CTFontRef ctFont);
 
 #else
 
commit 77a8d0f9e4f730e90af6367b8569de62cc0f3c9e
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Apr 7 16:51:16 2022 -0700

    [quartz] Require at least Mac OS X 10.7 Lion
    
    Allows removal of most conditional compilation and dlsym lookups.

diff --git a/configure.ac b/configure.ac
index 209df4fb8..c75648779 100644
--- a/configure.ac
+++ b/configure.ac
@@ -193,11 +193,8 @@ dnl ===========================================================================
 CAIRO_ENABLE_SURFACE_BACKEND(quartz, Quartz, auto, [
   dnl There is no pkgconfig for quartz; lets do a header check
   AC_CHECK_HEADER(ApplicationServices/ApplicationServices.h, , [use_quartz="no (requires ApplicationServices framework)"])
-  if test "x$use_quartz" != "xyes" ; then
-    dnl check for CoreGraphics as a separate framework
-    AC_CHECK_HEADER(CoreGraphics/CoreGraphics.h, , [use_quartz="no (requires CoreGraphics framework)"])
-    quartz_LIBS="-Xlinker -framework -Xlinker CoreGraphics"
-  else
+  AC_CHECK_FUNC([CTFontDrawGlyphs],,[use_quartz_fonts="no (requires Mac OS X 10.7 or later)"])
+  if test "x$use_quartz" = "xyes" ; then
     quartz_LIBS="-Xlinker -framework -Xlinker ApplicationServices"
   fi
 ])
diff --git a/meson.build b/meson.build
index 8c07f02e9..aa6506332 100644
--- a/meson.build
+++ b/meson.build
@@ -455,7 +455,6 @@ if host_machine.system() == 'darwin' and not get_option('quartz').disabled()
     deps += [quartz_deps]
 
     feature_conf.set('CAIRO_HAS_QUARTZ_SURFACE', 1)
-    feature_conf.set('CAIRO_HAS_QUARTZ_FONT', 1)
     feature_conf.set('CAIRO_HAS_QUARTZ_IMAGE_SURFACE', 1)
 
     built_features += [
@@ -468,13 +467,18 @@ if host_machine.system() == 'darwin' and not get_option('quartz').disabled()
         'name': 'cairo-quartz-image',
         'description': 'Quartz Image surface backend',
         'deps': quartz_deps,
-      },
-      {
-        'name': 'cairo-quartz-font',
-        'description': 'Quartz font backend',
-        'deps': quartz_deps,
-      },
-    ]
+      }]
+    compiler = meson.get_compiler('c')
+    if compiler.has_function('CTFontDrawGlyphs', prefix: '#include <ApplicationServices/ApplicationServices.h>',
+                             dependencies: quartz_deps)
+      built_features += [
+           {
+               'name': 'cairo-quartz-font',
+               'description': 'Quartz font backend',
+               'deps': quartz_deps,
+           }]
+      feature_conf.set('CAIRO_HAS_QUARTZ_FONT', 1)
+    endif
   endif
 endif
 
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 77a9d6a55..a9480a736 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -64,47 +64,11 @@
  * Since: 1.6
  **/
 
-static CFDataRef (*CGFontCopyTableForTagPtr) (CGFontRef font, uint32_t tag) = NULL;
-
-/* CreateWithFontName exists in 10.5, but not in 10.4; CreateWithName isn't public in 10.4 */
-static CGFontRef (*CGFontCreateWithFontNamePtr) (CFStringRef) = NULL;
-static CGFontRef (*CGFontCreateWithNamePtr) (const char *) = NULL;
-
-/* These aren't public before 10.5, and some have different names in 10.4 */
-static int (*CGFontGetUnitsPerEmPtr) (CGFontRef) = NULL;
-static bool (*CGFontGetGlyphAdvancesPtr) (CGFontRef, const CGGlyph[], size_t, int[]) = NULL;
-static bool (*CGFontGetGlyphBBoxesPtr) (CGFontRef, const CGGlyph[], size_t, CGRect[]) = NULL;
-static CGRect (*CGFontGetFontBBoxPtr) (CGFontRef) = NULL;
-
-/* Not public, but present */
-static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL;
-static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
+/* These are private functions */
 static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
-
-/* Not public in the least bit */
-static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
-
-/* CTFontCreateWithGraphicsFont is not available until 10.5 */
-typedef const struct __CTFontDescriptor *CTFontDescriptorRef;
-static CTFontRef (*CTFontCreateWithGraphicsFontPtr) (CGFontRef, CGFloat, const CGAffineTransform*, CTFontDescriptorRef) = NULL;
-static CGPathRef (*CTFontCreatePathForGlyphPtr) (CTFontRef, CGGlyph, CGAffineTransform *) = NULL;
-
-/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
-typedef struct {
-    int ascent;
-    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;
-
-/* Not public anymore in 64-bits nor in 10.7 */
 static ATSFontRef (*FMGetATSFontRefFromFontPtr) (FMFont iFont) = NULL;
 
 static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
-static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
 
 /* Defined in 10.11 */
 #define CGGLYPH_MAX ((CGGlyph) 0xFFFE) /* kCGFontIndexMax */
@@ -116,51 +80,11 @@ quartz_font_ensure_symbols(void)
     if (_cairo_quartz_font_symbol_lookup_done)
 	return;
 
-    CGFontCopyTableForTagPtr = dlsym(RTLD_DEFAULT, "CGFontCopyTableForTag");
-
-    /* Look for the 10.5 versions first */
-    CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBBoxes");
-    if (!CGFontGetGlyphBBoxesPtr)
-	CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBoundingBoxes");
-
-    CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars");
-    if (!CGFontGetGlyphsForUnicharsPtr)
-	CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
-
-    CGFontGetFontBBoxPtr = dlsym(RTLD_DEFAULT, "CGFontGetFontBBox");
-
-    /* We just need one of these two */
-    CGFontCreateWithFontNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithFontName");
-    CGFontCreateWithNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithName");
-
-    /* These have the same name in 10.4 and 10.5 */
-    CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
-    CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
-
-    CTFontCreateWithGraphicsFontPtr = dlsym(RTLD_DEFAULT, "CTFontCreateWithGraphicsFont");
-    CTFontCreatePathForGlyphPtr = dlsym(RTLD_DEFAULT, "CTFontCreatePathForGlyph");
-    if (!CTFontCreateWithGraphicsFontPtr || !CTFontCreatePathForGlyphPtr)
-	CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
-
-    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");
+    CGContextGetAllowsFontSmoothingPtr =
+	dlsym (RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
 
     FMGetATSFontRefFromFontPtr = dlsym(RTLD_DEFAULT, "FMGetATSFontRefFromFont");
 
-    if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
-	CGFontGetGlyphBBoxesPtr &&
-	CGFontGetGlyphsForUnicharsPtr &&
-	CGFontGetUnitsPerEmPtr &&
-	CGFontGetGlyphAdvancesPtr &&
-	((CTFontCreateWithGraphicsFontPtr && CTFontCreatePathForGlyphPtr) || CGFontGetGlyphPathPtr) &&
-	(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
-	_cairo_quartz_font_symbols_present = TRUE;
-
     _cairo_quartz_font_symbol_lookup_done = TRUE;
 }
 
@@ -191,10 +115,6 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
     CGFontRef cgFont = NULL;
     int loop;
 
-    quartz_font_ensure_symbols();
-    if (! _cairo_quartz_font_symbols_present)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
     family = toy_face->family;
     full_name = _cairo_malloc (strlen (family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
     /* handle CSS-ish faces */
@@ -231,13 +151,9 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
 		strcat (full_name, " Oblique");
 	}
 
-	if (CGFontCreateWithFontNamePtr) {
-	    cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
-	    cgFont = CGFontCreateWithFontNamePtr (cgFontName);
-	    CFRelease (cgFontName);
-	} else {
-	    cgFont = CGFontCreateWithNamePtr (full_name);
-	}
+	cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
+	cgFont = CGFontCreateWithFontName (cgFontName);
+	CFRelease (cgFontName);
 
 	if (cgFont)
 	    break;
@@ -279,10 +195,6 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
     double ems;
     CGRect bbox;
 
-    quartz_font_ensure_symbols();
-    if (!_cairo_quartz_font_symbols_present)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
     font = _cairo_malloc (sizeof(cairo_quartz_scaled_font_t));
     if (font == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -295,46 +207,17 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
     if (status)
 	goto FINISH;
 
-    ems = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+    ems = CGFontGetUnitsPerEm (font_face->cgFont);
 
     /* initialize metrics */
-    if (CGFontGetFontBBoxPtr && CGFontGetAscentPtr) {
-	fs_metrics.ascent = (CGFontGetAscentPtr (font_face->cgFont) / ems);
-	fs_metrics.descent = - (CGFontGetDescentPtr (font_face->cgFont) / ems);
-	fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
-	    (CGFontGetLeadingPtr (font_face->cgFont) / ems);
-
-	bbox = CGFontGetFontBBoxPtr (font_face->cgFont);
-	fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
-	fs_metrics.max_y_advance = 0.0;
-    } else {
-	CGGlyph wGlyph;
-	UniChar u;
-
-	quartz_CGFontMetrics *m;
-	m = CGFontGetHMetricsPtr (font_face->cgFont);
-
-	/* On OX 10.4, GetHMetricsPtr sometimes returns NULL for unknown reasons */
-	if (!m) {
-	    status = _cairo_error(CAIRO_STATUS_NULL_POINTER);
-	    goto FINISH;
-	}
+    fs_metrics.ascent = (CGFontGetAscent (font_face->cgFont) / ems);
+    fs_metrics.descent = - (CGFontGetDescent (font_face->cgFont) / ems);
+    fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
+	(CGFontGetLeading (font_face->cgFont) / ems);
 
-	fs_metrics.ascent = (m->ascent / ems);
-	fs_metrics.descent = - (m->descent / ems);
-	fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems);
-
-	/* We kind of have to guess here; W's big, right? */
-	u = (UniChar) 'W';
-	CGFontGetGlyphsForUnicharsPtr (font_face->cgFont, &u, &wGlyph, 1);
-	if (wGlyph && CGFontGetGlyphBBoxesPtr (font_face->cgFont, &wGlyph, 1, &bbox)) {
-	    fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
-	    fs_metrics.max_y_advance = 0.0;
-	} else {
-	    fs_metrics.max_x_advance = 0.0;
-	    fs_metrics.max_y_advance = 0.0;
-	}
-    }
+    bbox = CGFontGetFontBBox (font_face->cgFont);
+    fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
+    fs_metrics.max_y_advance = 0.0;
 
     status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics);
 
@@ -371,11 +254,9 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
 cairo_font_face_t *
 cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
 {
-    cairo_quartz_font_face_t *font_face;
-
-    quartz_font_ensure_symbols();
+    cairo_quartz_font_face_t *font_face =
+	_cairo_malloc (sizeof (cairo_quartz_font_face_t));
 
-    font_face = _cairo_malloc (sizeof (cairo_quartz_font_face_t));
     if (!font_face) {
 	cairo_status_t ignore_status;
 	ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -424,14 +305,14 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
     int advance;
     CGRect bbox;
-    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+    double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
     double xmin, ymin, xmax, ymax;
 
     if (unlikely (glyph == CGGLYPH_INVALID))
 	goto FAIL;
 
-    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
-	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
+    if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
+	!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
 	goto FAIL;
 
     /* broken fonts like Al Bayan return incorrect bounds for some null characters,
@@ -558,6 +439,7 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
     cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
     CGAffineTransform textMatrix;
+    CTFontRef ctFont;
     CGPathRef glyphPath;
     cairo_path_fixed_t *path;
 
@@ -573,13 +455,9 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
 					-font->base.scale.yy,
 					0, 0);
 
-    if (CTFontCreateWithGraphicsFontPtr && CTFontCreatePathForGlyphPtr) {
-	CTFontRef ctFont = CTFontCreateWithGraphicsFontPtr (font_face->cgFont, 1.0, NULL, NULL);
-	glyphPath = CTFontCreatePathForGlyphPtr (ctFont, glyph, &textMatrix);
-	CFRelease (ctFont);
-    } else {
-	glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
-    }
+    ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL);
+    glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
+    CFRelease (ctFont);
 
     if (!glyphPath)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -614,7 +492,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
     int advance;
     CGRect bbox;
     double width, height;
-    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+    double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
 
     CGContextRef cgContext = NULL;
     CGAffineTransform textMatrix;
@@ -639,8 +517,8 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
-	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
+    if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
+	!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
     {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
@@ -706,9 +584,10 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 	case CAIRO_ANTIALIAS_BEST:
 	    CGContextSetShouldAntialias (cgContext, TRUE);
 	    CGContextSetShouldSmoothFonts (cgContext, TRUE);
-	    if (CGContextSetAllowsFontSmoothingPtr &&
+	    quartz_font_ensure_symbols ();
+	    if (CGContextGetAllowsFontSmoothingPtr &&
 		!CGContextGetAllowsFontSmoothingPtr (cgContext))
-		CGContextSetAllowsFontSmoothingPtr (cgContext, TRUE);
+		CGContextSetAllowsFontSmoothing (cgContext, TRUE);
 	    break;
 	case CAIRO_ANTIALIAS_NONE:
 	    CGContextSetShouldAntialias (cgContext, FALSE);
@@ -767,12 +646,13 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
 {
     cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
     cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
+    CTFontRef ctFont;
     CGGlyph glyph[2];
     UniChar utf16[2];
 
     int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
-    CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, utf16, glyph, len);
-
+    ctFont = CTFontCreateWithGraphicsFont(ffont->cgFont, 10.0, NULL, NULL);
+    CTFontGetGlyphsForCharacters (ctFont, utf16, glyph, len);
     return glyph[0];
 }
 
@@ -784,10 +664,7 @@ _cairo_quartz_load_truetype_table (void	            *abstract_font,
 				   unsigned long    *length)
 {
     cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face (abstract_font);
-    CFDataRef data = NULL;
-
-    if (likely (CGFontCopyTableForTagPtr))
-	data = CGFontCopyTableForTagPtr (font_face->cgFont, tag);
+    CFDataRef data = CGFontCopyTableForTag (font_face->cgFont, tag);
 
     if (!data)
         return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 07484efb6..bc6968c06 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -85,46 +85,22 @@
  * Since: 1.6
  **/
 
-#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050
-/* This method is private, but it exists.  Its params are are exposed
- * as args to the NS* method, but not as CG.
- */
-enum PrivateCGCompositeMode {
-    kPrivateCGCompositeClear		= 0,
-    kPrivateCGCompositeCopy		= 1,
-    kPrivateCGCompositeSourceOver	= 2,
-    kPrivateCGCompositeSourceIn		= 3,
-    kPrivateCGCompositeSourceOut	= 4,
-    kPrivateCGCompositeSourceAtop	= 5,
-    kPrivateCGCompositeDestinationOver	= 6,
-    kPrivateCGCompositeDestinationIn	= 7,
-    kPrivateCGCompositeDestinationOut	= 8,
-    kPrivateCGCompositeDestinationAtop	= 9,
-    kPrivateCGCompositeXOR		= 10,
-    kPrivateCGCompositePlusDarker	= 11, // (max (0, (1-d) + (1-s)))
-    kPrivateCGCompositePlusLighter	= 12, // (min (1, s + d))
-};
-typedef enum PrivateCGCompositeMode PrivateCGCompositeMode;
-CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
-#endif
-
-/* Some of these are present in earlier versions of the OS than where
- * they are public; other are not public at all
- */
-
-/* public since 10.6 */
-static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL;
-static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
-
-/* not yet public */
-static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
-static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
-
-static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
-
 /*
- * Utility functions
+ * macOS Private functions
  */
+static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
+static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
+static void
+quartz_ensure_symbols()
+{
+    static cairo_bool_t symbol_lookup_done = FALSE;
+    if (!symbol_lookup_done) {
+	CGContextGetTypePtr = dlsym (RTLD_DEFAULT, "CGContextGetType");
+	CGContextGetAllowsFontSmoothingPtr =
+	    dlsym (RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
+	symbol_lookup_done = TRUE;
+    }
+}
 
 #ifdef QUARTZ_DEBUG
 static void quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest);
@@ -152,20 +128,6 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
 				       unsigned int width,
 				       unsigned int height);
 
-/* Load all extra symbols */
-static void quartz_ensure_symbols (void)
-{
-    if (likely (_cairo_quartz_symbol_lookup_done))
-	return;
-
-    CGContextGetTypePtr = dlsym (RTLD_DEFAULT, "CGContextGetType");
-    CGContextCopyPathPtr = dlsym (RTLD_DEFAULT, "CGContextCopyPath");
-    CGContextGetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
-    CGContextSetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
-
-    _cairo_quartz_symbol_lookup_done = TRUE;
-}
-
 CGImageRef
 CairoQuartzCreateCGImage (cairo_format_t format,
 			  unsigned int width,
@@ -270,6 +232,7 @@ _cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc)
     if (unlikely (cgc == NULL))
 	return FALSE;
 
+    quartz_ensure_symbols ();
     if (likely (CGContextGetTypePtr)) {
 	/* 4 is the type value of a bitmap context */
 	return CGContextGetTypePtr (cgc) == 4;
@@ -377,58 +340,6 @@ _cairo_quartz_cairo_path_to_quartz_context (const cairo_path_fixed_t *path,
  * Misc helpers/callbacks
  */
 
-#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050
-static PrivateCGCompositeMode
-_cairo_quartz_cairo_operator_to_quartz_composite (cairo_operator_t op)
-{
-    switch (op) {
-	case CAIRO_OPERATOR_CLEAR:
-	    return kPrivateCGCompositeClear;
-	case CAIRO_OPERATOR_SOURCE:
-	    return kPrivateCGCompositeCopy;
-	case CAIRO_OPERATOR_OVER:
-	    return kPrivateCGCompositeSourceOver;
-	case CAIRO_OPERATOR_IN:
-	    return kPrivateCGCompositeSourceIn;
-	case CAIRO_OPERATOR_OUT:
-	    return kPrivateCGCompositeSourceOut;
-	case CAIRO_OPERATOR_ATOP:
-	    return kPrivateCGCompositeSourceAtop;
-	case CAIRO_OPERATOR_DEST_OVER:
-	    return kPrivateCGCompositeDestinationOver;
-	case CAIRO_OPERATOR_DEST_IN:
-	    return kPrivateCGCompositeDestinationIn;
-	case CAIRO_OPERATOR_DEST_OUT:
-	    return kPrivateCGCompositeDestinationOut;
-	case CAIRO_OPERATOR_DEST_ATOP:
-	    return kPrivateCGCompositeDestinationAtop;
-	case CAIRO_OPERATOR_XOR:
-	    return kPrivateCGCompositeXOR;
-	case CAIRO_OPERATOR_ADD:
-	    return kPrivateCGCompositePlusLighter;
-
-	case CAIRO_OPERATOR_DEST:
-	case CAIRO_OPERATOR_SATURATE:
-	case CAIRO_OPERATOR_MULTIPLY:
-	case CAIRO_OPERATOR_SCREEN:
-	case CAIRO_OPERATOR_OVERLAY:
-	case CAIRO_OPERATOR_DARKEN:
-	case CAIRO_OPERATOR_LIGHTEN:
-	case CAIRO_OPERATOR_COLOR_DODGE:
-	case CAIRO_OPERATOR_COLOR_BURN:
-	case CAIRO_OPERATOR_HARD_LIGHT:
-	case CAIRO_OPERATOR_SOFT_LIGHT:
-	case CAIRO_OPERATOR_DIFFERENCE:
-	case CAIRO_OPERATOR_EXCLUSION:
-	case CAIRO_OPERATOR_HSL_HUE:
-	case CAIRO_OPERATOR_HSL_SATURATION:
-	case CAIRO_OPERATOR_HSL_COLOR:
-	case CAIRO_OPERATOR_HSL_LUMINOSITY:
-        default:
-	    ASSERT_NOT_REACHED;
-    }
-}
-#endif
 
 static CGBlendMode
 _cairo_quartz_cairo_operator_to_quartz_blend (cairo_operator_t op)
@@ -465,7 +376,6 @@ _cairo_quartz_cairo_operator_to_quartz_blend (cairo_operator_t op)
 	case CAIRO_OPERATOR_HSL_LUMINOSITY:
 	    return kCGBlendModeLuminosity;
 
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
 	case CAIRO_OPERATOR_CLEAR:
 	    return kCGBlendModeClear;
 	case CAIRO_OPERATOR_SOURCE:
@@ -490,21 +400,6 @@ _cairo_quartz_cairo_operator_to_quartz_blend (cairo_operator_t op)
 	    return kCGBlendModeXOR;
 	case CAIRO_OPERATOR_ADD:
 	    return kCGBlendModePlusLighter;
-#else
-	case CAIRO_OPERATOR_CLEAR:
-	case CAIRO_OPERATOR_SOURCE:
-	case CAIRO_OPERATOR_OVER:
-	case CAIRO_OPERATOR_IN:
-	case CAIRO_OPERATOR_OUT:
-	case CAIRO_OPERATOR_ATOP:
-	case CAIRO_OPERATOR_DEST_OVER:
-	case CAIRO_OPERATOR_DEST_IN:
-	case CAIRO_OPERATOR_DEST_OUT:
-	case CAIRO_OPERATOR_DEST_ATOP:
-	case CAIRO_OPERATOR_XOR:
-	case CAIRO_OPERATOR_ADD:
-#endif
-
 	case CAIRO_OPERATOR_DEST:
 	case CAIRO_OPERATOR_SATURATE:
         default:
@@ -534,16 +429,6 @@ _cairo_cgcontext_set_cairo_operator (CGContextRef context, cairo_operator_t op)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050
-    if (op <= CAIRO_OPERATOR_ADD) {
-	PrivateCGCompositeMode compmode;
-
-	compmode = _cairo_quartz_cairo_operator_to_quartz_composite (op);
-	CGContextSetCompositeOperation (context, compmode);
-	return CAIRO_STATUS_SUCCESS;
-    }
-#endif
-
     blendmode = _cairo_quartz_cairo_operator_to_quartz_blend (op);
     CGContextSetBlendMode (context, blendmode);
     return CAIRO_STATUS_SUCCESS;
@@ -1558,13 +1443,6 @@ _cairo_quartz_surface_finish (void *abstract_surface)
 
     surface->cgContext = NULL;
 
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 10600
-    if (surface->imageData) {
-	free (surface->imageData);
-	surface->imageData = NULL;
-    }
-#endif
-
     if (surface->cgLayer)
     {
 	CGLayerRelease (surface->cgLayer);
@@ -2054,11 +1932,12 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
 	case CAIRO_ANTIALIAS_BEST:
 	    CGContextSetShouldAntialias (state.cgMaskContext, TRUE);
 	    CGContextSetShouldSmoothFonts (state.cgMaskContext, TRUE);
-	    if (CGContextSetAllowsFontSmoothingPtr &&
+	    quartz_ensure_symbols();
+	    if (CGContextGetAllowsFontSmoothingPtr &&
 		!CGContextGetAllowsFontSmoothingPtr (state.cgMaskContext))
 	    {
 		didForceFontSmoothing = TRUE;
-		CGContextSetAllowsFontSmoothingPtr (state.cgMaskContext, TRUE);
+		CGContextSetAllowsFontSmoothing (state.cgMaskContext, TRUE);
 	    }
 	    break;
 	case CAIRO_ANTIALIAS_NONE:
@@ -2135,7 +2014,7 @@ _cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor,
 
 BAIL:
     if (didForceFontSmoothing)
-	CGContextSetAllowsFontSmoothingPtr (state.cgMaskContext, FALSE);
+	CGContextSetAllowsFontSmoothing (state.cgMaskContext, FALSE);
 
     _cairo_quartz_teardown_state (&state, extents);
 
@@ -2319,8 +2198,6 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
 {
     cairo_quartz_surface_t *surface;
 
-    quartz_ensure_symbols ();
-
     /* Init the base surface */
     surface = _cairo_malloc (sizeof (cairo_quartz_surface_t));
     if (unlikely (surface == NULL))
@@ -2342,9 +2219,6 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
     surface->extents.width = width;
     surface->extents.height = height;
     surface->virtual_extents = surface->extents;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 10600
-    surface->imageData = NULL;
-#endif
 
     if (IS_EMPTY (surface)) {
 	surface->cgContext = NULL;
@@ -2473,16 +2347,6 @@ cairo_quartz_surface_create (cairo_format_t format,
      * so we don't have to anything special on allocation.
      */
     stride = (stride + 15) & ~15;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 10600
-    imageData = _cairo_malloc_ab (height, stride);
-    if (unlikely (!imageData)) {
-	CGColorSpaceRelease (cgColorspace);
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-    }
-
-    /* zero the memory to match the image surface behavior */
-    memset (imageData, 0, height * stride);
-#endif /* For newer macOS versions let Core Graphics manage the buffer. */
     cgc = CGBitmapContextCreate (imageData,
 				 width,
 				 height,
@@ -2515,9 +2379,6 @@ cairo_quartz_surface_create (cairo_format_t format,
 	return &surf->base;
     }
 
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 10600
-    surf->imageData = imageData;
-#endif
     surf->base.is_clear = TRUE;
 
     return &surf->base;
commit 0048f0f8035549f024a6a8571afba84742cb3dac
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Apr 17 10:47:10 2022 -0700

    [quartz] Fix some compiler warnings.

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 5681918c4..07484efb6 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1472,7 +1472,7 @@ _cairo_quartz_surface_map_to_image (void *abstract_surface,
     cairo_surface_t *return_surface = NULL;
     unsigned int stride, bitinfo, bpp, color_comps;
     CGColorSpaceRef colorspace;
-    void *imageData;
+    unsigned char *imageData;
     cairo_format_t format;
 
     if (IS_EMPTY (surface))
@@ -2632,7 +2632,7 @@ quartz_image_to_png (CGImageRef image, const char *dest)
 
     memset (pathbuf, 0, sizeof (pathbuf));
     dest = dest ? dest : image_name;
-    snprintf (pathbuf, sizeof (pathbuf), "%s/Desktop/%s%d.png",getenv ("HOME"), dest, sctr++, ext);
+    snprintf (pathbuf, sizeof (pathbuf), "%s/Desktop/%s%d.png",getenv ("HOME"), dest, sctr++);
     path = CFStringCreateWithCString (NULL, pathbuf, kCFStringEncodingUTF8);
     url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, FALSE);
     image_dest = CGImageDestinationCreateWithURL (url, png_utti, 1, NULL);
@@ -2647,7 +2647,6 @@ quartz_image_to_png (CGImageRef image, const char *dest)
 void
 quartz_surface_to_png (cairo_quartz_surface_t *nq, const char *dest)
 {
-    static int sctr = 0;
     CGImageRef image;
 
     if (nq->base.type != CAIRO_SURFACE_TYPE_QUARTZ) {


More information about the cairo-commit mailing list