[cairo-commit] 9 commits - configure.in doc/public src/cairo-atsui-font.c src/cairoint.h src/cairo-quartz-font.c src/cairo-quartz.h src/cairo-quartz-private.h src/cairo-quartz-surface.c src/Makefile.am test/clip-operator-quartz-ref.png test/clip-operator-quartz-rgb24-ref.png test/font-matrix-translation-quartz-ref.png test/glyph-cache-pressure-quartz-ref.png test/linear-gradient-reflect-quartz-ref.png test/Makefile.am test/operator-clear-quartz-ref.png test/operator-clear-quartz-rgb24-ref.png test/operator-source-quartz-ref.png test/operator-source-quartz-rgb24-ref.png test/select-font-face-quartz-ref.png test/show-text-current-point-quartz-ref.png test/surface-pattern-scale-down-quartz-ref.png test/text-antialias-gray-quartz-ref.png test/text-antialias-none-quartz-ref.png test/text-antialias-subpixel-quartz-ref.png test/text-pattern-quartz-ref.png test/text-pattern-quartz-rgb24-ref.png test/text-rotate-quartz-ref.png test/unbounded-operator-quartz-ref.png test/unbounded-operator-quartz-rgb24-ref.png
Vladimir Vukicevic
vladimir at kemper.freedesktop.org
Tue Apr 1 13:49:28 PDT 2008
configure.in | 10
doc/public/cairo-docs.xml | 1
doc/public/cairo-sections.txt | 14
doc/public/tmpl/cairo-ft.sgml | 8
doc/public/tmpl/cairo-quartz-fonts.sgml | 48 +
doc/public/tmpl/cairo-quartz.sgml | 25
doc/public/tmpl/cairo-xlib.sgml | 8
src/Makefile.am | 3
src/cairo-atsui-font.c | 1028 -------------------------
src/cairo-quartz-font.c | 726 +++++++++++++++++
src/cairo-quartz-private.h | 5
src/cairo-quartz-surface.c | 93 +-
src/cairo-quartz.h | 5
src/cairoint.h | 4
test/Makefile.am | 3
test/clip-operator-quartz-ref.png |binary
test/clip-operator-quartz-rgb24-ref.png |binary
test/font-matrix-translation-quartz-ref.png |binary
test/glyph-cache-pressure-quartz-ref.png |binary
test/linear-gradient-reflect-quartz-ref.png |binary
test/operator-clear-quartz-ref.png |binary
test/operator-clear-quartz-rgb24-ref.png |binary
test/operator-source-quartz-ref.png |binary
test/operator-source-quartz-rgb24-ref.png |binary
test/select-font-face-quartz-ref.png |binary
test/show-text-current-point-quartz-ref.png |binary
test/surface-pattern-scale-down-quartz-ref.png |binary
test/text-antialias-gray-quartz-ref.png |binary
test/text-antialias-none-quartz-ref.png |binary
test/text-antialias-subpixel-quartz-ref.png |binary
test/text-pattern-quartz-ref.png |binary
test/text-pattern-quartz-rgb24-ref.png |binary
test/text-rotate-quartz-ref.png |binary
test/unbounded-operator-quartz-ref.png |binary
test/unbounded-operator-quartz-rgb24-ref.png |binary
35 files changed, 870 insertions(+), 1111 deletions(-)
New commits:
commit 56800e6ea0f7153e44f0cba14c89c4239067a60e
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Apr 1 13:28:03 2008 -0700
[quartz] Remove cairo-atsui-font.c
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
deleted file mode 100644
index 42c209b..0000000
--- a/src/cairo-atsui-font.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2004 Calum Robinson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Calum Robinson
- *
- * Contributor(s):
- * Calum Robinson <calumr at mac.com>
- */
-
-#include "cairoint.h"
-
-#include "cairo.h"
-#include "cairo-quartz.h"
-#include "cairo-quartz-private.h"
-
-/*
- * FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
- * here so we can use older SDKs.
- */
-#ifndef FixedToFloat
-#define fixed1 ((Fixed) 0x00010000L)
-#define FixedToFloat(a) ((float)(a) / fixed1)
-#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
-#endif
-
-/* If this isn't defined, we must be building on non-intel,
- * hence it will be 0.
- */
-#ifdef __BIG_ENDIAN__
-#define CG_BITMAP_BYTE_ORDER_FLAG 0
-#else /* Little endian. */
-/* x86, and will be a 10.4u SDK; ByteOrder32Host will be defined */
-#define CG_BITMAP_BYTE_ORDER_FLAG kCGBitmapByteOrder32Host
-#endif
-
-/* Public in 10.4, present in 10.3.9 */
-CG_EXTERN CGRect CGRectApplyAffineTransform (CGRect, CGAffineTransform);
-
-/* Error code for path callbacks */
-static OSStatus CAIRO_CG_PATH_ERROR = 1001;
-
-typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
-typedef struct _cairo_atsui_font cairo_atsui_font_t;
-typedef struct _cairo_atsui_scaled_path cairo_atsui_scaled_path_t;
-
-static cairo_status_t _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
- ATSUFontID font_id,
- ATSUStyle style,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font_out);
-
-struct _cairo_atsui_font {
- cairo_scaled_font_t base;
-
- ATSUStyle style;
- ATSUStyle unscaled_style;
- ATSUFontID fontID;
-
- Fixed size;
- CGAffineTransform font_matrix;
- CGFontRef cgfref;
-};
-
-struct _cairo_atsui_font_face {
- cairo_font_face_t base;
- ATSUFontID font_id;
-};
-
-struct _cairo_atsui_scaled_path {
- cairo_path_fixed_t *path;
- cairo_matrix_t *scale;
-};
-
-static void
-_cairo_atsui_font_face_destroy (void *abstract_face)
-{
-}
-
-static cairo_status_t
-_cairo_atsui_font_face_scaled_font_create (void *abstract_face,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font)
-{
- cairo_status_t status;
- cairo_atsui_font_face_t *font_face = abstract_face;
- OSStatus err;
- ATSUAttributeTag styleTags[] = { kATSUFontTag };
- ATSUAttributeValuePtr styleValues[] = { &font_face->font_id };
- ByteCount styleSizes[] = { sizeof(ATSUFontID) };
- ATSUStyle style;
-
- err = ATSUCreateStyle (&style);
- if (err != noErr)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
- styleTags, styleSizes, styleValues);
- if (err != noErr) {
- ATSUDisposeStyle (style);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
-
- status = _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
- font_matrix, ctm, options, font);
- if (status)
- ATSUDisposeStyle (style);
-
- return status;
-}
-
-static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
- CAIRO_FONT_TYPE_QUARTZ,
- _cairo_atsui_font_face_destroy,
- _cairo_atsui_font_face_scaled_font_create
-};
-
-/**
- * cairo_atsui_font_face_create_for_atsu_font_id
- * @font_id: an ATSUFontID for the font.
- *
- * Creates a new font for the Quartz font backend based on an
- * #ATSUFontID. This font can then be used with
- * cairo_set_font_face() or cairo_scaled_font_create().
- *
- * Return value: a newly created #cairo_font_face_t. Free with
- * cairo_font_face_destroy() when you are done using it.
- *
- * Since: 1.6
- **/
-cairo_font_face_t *
-cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
-{
- cairo_atsui_font_face_t *font_face;
-
- font_face = malloc (sizeof (cairo_atsui_font_face_t));
- if (!font_face) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return (cairo_font_face_t *)&_cairo_font_face_nil;
- }
-
- font_face->font_id = font_id;
-
- _cairo_font_face_init (&font_face->base, &_cairo_atsui_font_face_backend);
-
- return &font_face->base;
-}
-
-/* This is the old name for the above function, exported for compat purposes */
-cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
-
-cairo_font_face_t *
-cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
-{
- return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
-}
-
-static OSStatus
-CreateSizedCopyOfStyle(ATSUStyle inStyle,
- const Fixed *theSize,
- const CGAffineTransform *theTransform,
- ATSUStyle *style)
-{
- OSStatus err;
- const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag,
- kATSUFontMatrixTag };
- const ByteCount theFontStyleSizes[] = { sizeof(Fixed),
- sizeof(CGAffineTransform) };
- ATSUAttributeValuePtr theFontStyleValues[] = { (Fixed *)theSize,
- (CGAffineTransform *)theTransform };
-
- err = ATSUCreateAndCopyStyle (inStyle, style);
- if (err != noErr)
- return err;
-
- err = ATSUSetAttributes(*style,
- sizeof(theFontStyleTags) /
- sizeof(ATSUAttributeTag), theFontStyleTags,
- theFontStyleSizes, theFontStyleValues);
- if (err != noErr)
- ATSUDisposeStyle (*style);
-
- return err;
-}
-
-
-static cairo_status_t
-_cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
-{
- cairo_status_t status;
- ATSFontRef atsFont;
- ATSFontMetrics metrics;
- OSStatus err;
-
- atsFont = FMGetATSFontRefFromFont(font->fontID);
-
- if (atsFont) {
- err = ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault, &metrics);
-
- if (err == noErr) {
- cairo_font_extents_t extents;
-
- extents.ascent = metrics.ascent;
- extents.descent = -metrics.descent;
- extents.height = extents.ascent + extents.descent + metrics.leading;
- extents.max_x_advance = metrics.maxAdvanceWidth;
-
- /* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
- extents.max_y_advance = 0.0;
-
- status = _cairo_scaled_font_set_metrics (&font->base, &extents);
-
- return status;
- }
- }
-
- return _cairo_error (CAIRO_STATUS_NULL_POINTER);
-}
-
-static cairo_status_t
-_cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
- ATSUFontID font_id,
- ATSUStyle style,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font_out)
-{
- cairo_atsui_font_t *font = NULL;
- OSStatus err;
- cairo_status_t status;
- double xscale = 1.0;
- double yscale = 1.0;
-
- font = malloc(sizeof(cairo_atsui_font_t));
- if (font == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- memset (font, 0, sizeof(cairo_atsui_font_t));
-
- status = _cairo_scaled_font_init (&font->base,
- font_face, font_matrix, ctm, options,
- &cairo_atsui_scaled_font_backend);
- if (status) {
- free (font);
- return status;
- }
-
- status = _cairo_matrix_compute_scale_factors (&font->base.scale,
- &xscale, &yscale, 1);
- if (status)
- goto FAIL;
-
- /* ATS can't handle 0-sized bits; we end up in an odd infinite loop
- * if we send down a size of 0. */
- if (xscale == 0.0) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto FAIL;
- }
-
- font->font_matrix = CGAffineTransformMake (1., 0.,
- 0., yscale/xscale,
- 0., 0.);
- font->size = FloatToFixed (xscale);
- font->style = NULL;
-
- err = CreateSizedCopyOfStyle (style, &font->size, &font->font_matrix, &font->style);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto FAIL;
- }
-
- {
- Fixed theSize = FloatToFixed(1.0);
- const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
- const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
- ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
-
- err = ATSUSetAttributes(style,
- sizeof(theFontStyleTags) /
- sizeof(ATSUAttributeTag), theFontStyleTags,
- theFontStyleSizes, theFontStyleValues);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto FAIL;
- }
- }
-
- font->unscaled_style = style;
- font->fontID = font_id;
-
- *font_out = &font->base;
-
- status = _cairo_atsui_font_set_metrics (font);
-
- font->cgfref = 0;
- FAIL:
- if (status) {
- if (font) {
- if (font->style)
- ATSUDisposeStyle(font->style);
- _cairo_scaled_font_fini(&font->base);
- free (font);
- }
-
- return status;
- }
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font_out)
-{
- cairo_status_t status;
- ATSUStyle style;
- ATSUFontID fontID;
- OSStatus err;
- Boolean isItalic, isBold;
- const char *family = toy_face->family;
- const char *full_name;
-
- err = ATSUCreateStyle(&style);
- if (err != noErr) {
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
-
- switch (toy_face->weight) {
- case CAIRO_FONT_WEIGHT_BOLD:
- isBold = true;
- break;
- case CAIRO_FONT_WEIGHT_NORMAL:
- default:
- isBold = false;
- break;
- }
-
- switch (toy_face->slant) {
- case CAIRO_FONT_SLANT_ITALIC:
- isItalic = true;
- break;
- case CAIRO_FONT_SLANT_OBLIQUE:
- isItalic = false;
- break;
- case CAIRO_FONT_SLANT_NORMAL:
- default:
- isItalic = false;
- break;
- }
-
- /* The APIs for resolving a font family to a regular
- * font face are all broken or deprecated in 10.4, so
- * just try our best to find a sensible font.
- *
- * First we try to map the CSS generic font families
- * to fonts that should always be available.
- * If the family isn't a CSS family, guess that the
- * font family name is the same as the full name of the
- * regular font instance, which works in many cases.
- * 'Times' is one common exception to this rule, so it's
- * handled specially.
- */
- if (!strcmp(family, "serif") || !strcmp(family, "Times"))
- full_name = "Times Roman";
- else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
- full_name = "Helvetica";
- else if (!strcmp(family, "cursive"))
- full_name = "Apple Chancery";
- else if (!strcmp(family, "fantasy"))
- full_name = "American Typewriter";
- else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
- full_name = "Courier";
- else
- full_name = family;
-
- err = ATSUFindFontFromName(family, strlen(family),
- kFontFullName,
- kFontNoPlatformCode,
- kFontRomanScript,
- kFontNoLanguageCode, &fontID);
-
- if (err != noErr) {
- /* Look for any font instance in the family. This may
- * succeed, but select the bold or italic face. It only
- * selects the first loaded font instance in the family.
- */
- err = ATSUFindFontFromName(family, strlen(family),
- kFontFamilyName,
- kFontNoPlatformCode,
- kFontRomanScript,
- kFontNoLanguageCode, &fontID);
- if (err != noErr) {
- /* Last chance - try Courier. */
- full_name = "Courier";
- err = ATSUFindFontFromName(full_name, strlen(full_name),
- kFontFullName,
- kFontNoPlatformCode,
- kFontRomanScript,
- kFontNoLanguageCode, &fontID);
- if (err != noErr) {
- ATSUDisposeStyle (style);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
- }
- }
-
- {
- ATSUAttributeTag styleTags[] =
- { kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
- ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
- ByteCount styleSizes[] =
- { sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
-
- err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
- styleTags, styleSizes, styleValues);
- if (err != noErr) {
- ATSUDisposeStyle (style);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
- }
-
- status = _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
- font_matrix, ctm, options, font_out);
- if (status)
- ATSUDisposeStyle (style);
-
- return status;
-}
-
-static void
-_cairo_atsui_font_fini(void *abstract_font)
-{
- cairo_atsui_font_t *font = abstract_font;
-
- if (font == NULL)
- return;
-
- if (font->style)
- ATSUDisposeStyle(font->style);
- if (font->unscaled_style)
- ATSUDisposeStyle(font->unscaled_style);
- if (font->cgfref)
- CGFontRelease(font->cgfref);
-
-}
-
-static GlyphID
-_cairo_atsui_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
- unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
- if (index > 0xffff)
- return kATSDeletedGlyphcode;
- return index;
-}
-
-static cairo_status_t
-_cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
- cairo_scaled_glyph_t *scaled_glyph)
-{
- cairo_status_t status;
- cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
- OSStatus err;
- ATSGlyphScreenMetrics metricsH;
- GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
- double xscale, yscale;
-
- if (theGlyph == kATSDeletedGlyphcode) {
- _cairo_scaled_glyph_set_metrics (scaled_glyph,
- &scaled_font->base,
- &extents);
- return CAIRO_STATUS_SUCCESS;
- }
-
- /* We calculate the advance from the screen metrics. We
- * could probably take this from the glyph path.
- */
- err = ATSUGlyphGetScreenMetrics (scaled_font->style,
- 1, &theGlyph, 0, false,
- false, &metricsH);
- if (err != noErr)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- /* Scale down to font units.*/
- status = _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
- &xscale, &yscale, 1);
- if (status)
- return status;
-
- xscale = 1.0/xscale;
- yscale = 1.0/yscale;
-
- extents.x_advance = metricsH.deviceAdvance.x * xscale;
- extents.y_advance = 0;
-
- extents.x_bearing = metricsH.topLeft.x * xscale;
- extents.y_bearing = -metricsH.topLeft.y * yscale;
- extents.width = metricsH.width * xscale;
- extents.height = metricsH.height * yscale;
-
- _cairo_scaled_glyph_set_metrics (scaled_glyph,
- &scaled_font->base,
- &extents);
- return CAIRO_STATUS_SUCCESS;
-}
-
-static OSStatus
-_move_to (const Float32Point *point,
- void *callback_data)
-{
- cairo_status_t status;
- cairo_atsui_scaled_path_t *scaled_path = callback_data;
- double x = point->x;
- double y = point->y;
-
- cairo_matrix_transform_point (scaled_path->scale, &x, &y);
- status = _cairo_path_fixed_close_path (scaled_path->path);
- if (status)
- return CAIRO_CG_PATH_ERROR;
-
- status = _cairo_path_fixed_move_to (scaled_path->path,
- _cairo_fixed_from_double (x),
- _cairo_fixed_from_double (y));
- if (status)
- return CAIRO_CG_PATH_ERROR;
-
- return noErr;
-}
-
-static OSStatus
-_line_to (const Float32Point *point,
- void *callback_data)
-{
- cairo_status_t status;
- cairo_atsui_scaled_path_t *scaled_path = callback_data;
- double x = point->x;
- double y = point->y;
-
- cairo_matrix_transform_point (scaled_path->scale, &x, &y);
-
- status = _cairo_path_fixed_line_to (scaled_path->path,
- _cairo_fixed_from_double (x),
- _cairo_fixed_from_double (y));
- if (status)
- return CAIRO_CG_PATH_ERROR;
-
- return noErr;
-}
-
-static OSStatus
-_curve_to (const Float32Point *point1,
- const Float32Point *point2,
- const Float32Point *point3,
- void *callback_data)
-{
- cairo_status_t status;
- cairo_atsui_scaled_path_t *scaled_path = callback_data;
- double x1 = point1->x;
- double y1 = point1->y;
- double x2 = point2->x;
- double y2 = point2->y;
- double x3 = point3->x;
- double y3 = point3->y;
-
- cairo_matrix_transform_point (scaled_path->scale, &x1, &y1);
- cairo_matrix_transform_point (scaled_path->scale, &x2, &y2);
- cairo_matrix_transform_point (scaled_path->scale, &x3, &y3);
-
- status = _cairo_path_fixed_curve_to (scaled_path->path,
- _cairo_fixed_from_double (x1),
- _cairo_fixed_from_double (y1),
- _cairo_fixed_from_double (x2),
- _cairo_fixed_from_double (y2),
- _cairo_fixed_from_double (x3),
- _cairo_fixed_from_double (y3));
- if (status)
- return CAIRO_CG_PATH_ERROR;
-
- return noErr;
-}
-
-static OSStatus
-_close_path (void *callback_data)
-
-{
- cairo_status_t status;
- cairo_atsui_scaled_path_t *scaled_path = callback_data;
-
- status = _cairo_path_fixed_close_path (scaled_path->path);
- if (status)
- return CAIRO_CG_PATH_ERROR;
-
- return noErr;
-}
-
-static cairo_status_t
-_cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
- cairo_scaled_glyph_t *scaled_glyph)
-{
- cairo_status_t status;
- static ATSCubicMoveToUPP moveProc = NULL;
- static ATSCubicLineToUPP lineProc = NULL;
- static ATSCubicCurveToUPP curveProc = NULL;
- static ATSCubicClosePathUPP closePathProc = NULL;
- GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
- OSStatus err;
- cairo_atsui_scaled_path_t scaled_path;
- cairo_matrix_t *font_to_device = &scaled_font->base.scale;
- cairo_matrix_t unscaled_font_to_device;
- double xscale;
- double yscale;
-
- scaled_path.path = _cairo_path_fixed_create ();
- if (!scaled_path.path)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- if (theGlyph == kATSDeletedGlyphcode) {
- _cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base,
- scaled_path.path);
-
- return CAIRO_STATUS_SUCCESS;
- }
-
- /* extract the rotation/shear component of the scale matrix. */
- status = _cairo_matrix_compute_scale_factors (font_to_device, &xscale, &yscale, 1);
- if (status)
- goto FAIL;
-
- cairo_matrix_init (&unscaled_font_to_device,
- font_to_device->xx,
- font_to_device->yx,
- font_to_device->xy,
- font_to_device->yy, 0., 0.);
- cairo_matrix_scale (&unscaled_font_to_device, 1.0/xscale, 1.0/yscale);
-
- scaled_path.scale = &unscaled_font_to_device;
-
- if (moveProc == NULL) {
- moveProc = NewATSCubicMoveToUPP(_move_to);
- lineProc = NewATSCubicLineToUPP(_line_to);
- curveProc = NewATSCubicCurveToUPP(_curve_to);
- closePathProc = NewATSCubicClosePathUPP(_close_path);
- }
-
- err = ATSUGlyphGetCubicPaths(scaled_font->style,
- theGlyph,
- moveProc,
- lineProc,
- curveProc,
- closePathProc, (void *)&scaled_path, &err);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto FAIL;
- }
-
- _cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base,
- scaled_path.path);
-
- return CAIRO_STATUS_SUCCESS;
-
- FAIL:
- _cairo_path_fixed_destroy (scaled_path.path);
- return status;
-}
-
-static cairo_status_t
-_cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
- cairo_scaled_glyph_t *scaled_glyph)
-{
- OSStatus err;
- CGContextRef drawingContext;
- cairo_image_surface_t *surface;
- cairo_format_t format;
- cairo_status_t status;
-
- ATSFontRef atsFont;
- CGFontRef cgFont;
- cairo_scaled_font_t base = scaled_font->base;
- cairo_font_extents_t extents = base.extents;
-
- GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
- ATSGlyphScreenMetrics metricsH;
- double left, bottom, width, height;
- double xscale, yscale;
- CGRect bbox;
- CGAffineTransform transform;
-
- if (theGlyph == kATSDeletedGlyphcode) {
- surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
- status = cairo_surface_status ((cairo_surface_t *)surface);
- if (status)
- return status;
-
- _cairo_scaled_glyph_set_surface (scaled_glyph,
- &base,
- surface);
- return CAIRO_STATUS_SUCCESS;
- }
-
- /* Compute a box to contain the glyph mask. The vertical
- * sizes come from the font extents; extra pixels are
- * added to account for fractional sizes.
- */
- height = extents.ascent + extents.descent + 2.0;
- bottom = -extents.descent - 1.0;
-
- status = _cairo_matrix_compute_scale_factors (&base.scale,
- &xscale, &yscale, 1);
- if (status)
- return status;
-
- bbox = CGRectApplyAffineTransform (CGRectMake (1.0, bottom, 1.0, height), CGAffineTransformMakeScale(xscale, yscale));
- bottom = CGRectGetMinY (bbox);
- height = bbox.size.height;
-
- /* Horizontal sizes come from the glyph typographic metrics.
- * It is possible that this might result in clipped text
- * in fonts where the typographic bounds don't cover the ink.
- * The width is recalculated, since metricsH.width is rounded.
- */
- err = ATSUGlyphGetScreenMetrics (scaled_font->style,
- 1, &theGlyph, 0, false,
- false, &metricsH);
- if (err != noErr) {
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
-
- left = metricsH.sideBearing.x - 1.0;
- width = metricsH.deviceAdvance.x
- - metricsH.sideBearing.x
- + metricsH.otherSideBearing.x + 2.0;
-
- /* The xy and yx components are negated because the y-axis
- * is flipped into the cairo system then flipped back, ie:
- * [1 0][xx yx][1 0]
- * [0 -1][xy yy][0 -1]
- */
- transform = CGAffineTransformMake (base.scale.xx,
- -base.scale.yx,
- -base.scale.xy,
- base.scale.yy,
- 0., 0.);
- status = _cairo_matrix_compute_scale_factors (&base.scale,
- &xscale, &yscale, 1);
- if (status)
- return status;
-
- transform = CGAffineTransformScale (transform, 1.0/xscale, 1.0/yscale);
-
- /* Rotate the bounding box. This computes the smallest CGRect
- * that would contain the bounding box after rotation.
- */
- bbox = CGRectApplyAffineTransform (CGRectMake (left, bottom,
- width, height), transform);
- /* Compute the smallest CGRect with integer coordinates
- * that contains the bounding box.
- */
- bbox = CGRectIntegral (bbox);
-
- left = CGRectGetMinX (bbox);
- bottom = CGRectGetMinY (bbox);
-
- /* XXX should we select format based on antialiasing flags, as ft does? */
- format = CAIRO_FORMAT_A8;
-
- /* create the glyph mask surface */
- surface = (cairo_image_surface_t *)cairo_image_surface_create (format, bbox.size.width, bbox.size.height);
- status = cairo_surface_status ((cairo_surface_t *)surface);
- if (status)
- return status;
-
- /* Create a CGBitmapContext for the dest surface for drawing into */
- {
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray ();
-
- drawingContext = CGBitmapContextCreate (surface->data,
- surface->width,
- surface->height,
- 8,
- surface->stride,
- colorSpace,
- kCGImageAlphaNone);
- CGColorSpaceRelease (colorSpace);
- }
-
- if (!drawingContext) {
- cairo_surface_destroy ((cairo_surface_t *)surface);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
-
- atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
- cgFont = CGFontCreateWithPlatformFont (&atsFont);
-
- CGContextSetFont (drawingContext, cgFont);
-
- if (base.options.antialias == CAIRO_ANTIALIAS_NONE) {
- CGContextSetShouldAntialias (drawingContext, false);
- }
-
- /* solid white */
- CGContextSetRGBFillColor (drawingContext, 1.0, 1.0, 1.0, 1.0);
-
- CGContextSetFontSize (drawingContext, 1.0);
- CGContextTranslateCTM (drawingContext, -left, -bottom);
- CGContextScaleCTM (drawingContext, xscale, yscale);
- CGContextSetTextMatrix (drawingContext, transform);
- CGContextShowGlyphsAtPoint (drawingContext, 0, 0,
- &theGlyph, 1);
-
- CGContextRelease (drawingContext);
-
- /* correct for difference between cairo and quartz
- * coordinate systems.
- */
- cairo_surface_set_device_offset ((cairo_surface_t *)surface,
- -left, (bbox.size.height + bottom));
- _cairo_scaled_glyph_set_surface (scaled_glyph,
- &base,
- surface);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_atsui_font_scaled_glyph_init (void *abstract_font,
- cairo_scaled_glyph_t *scaled_glyph,
- cairo_scaled_glyph_info_t info)
-{
- cairo_atsui_font_t *scaled_font = abstract_font;
- cairo_status_t status;
-
- if ((info & CAIRO_SCALED_GLYPH_INFO_METRICS) != 0) {
- status = _cairo_atsui_font_init_glyph_metrics (scaled_font, scaled_glyph);
- if (status)
- return status;
- }
-
- if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {
- status = _cairo_atsui_scaled_font_init_glyph_path (scaled_font, scaled_glyph);
- if (status)
- return status;
- }
-
- if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
- status = _cairo_atsui_scaled_font_init_glyph_surface (scaled_font, scaled_glyph);
- if (status)
- return status;
- }
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_atsui_font_text_to_glyphs (void *abstract_font,
- double x,
- double y,
- const char *utf8,
- cairo_glyph_t **glyphs,
- int *num_glyphs)
-{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- uint16_t *utf16;
- int n16;
- OSStatus err;
- ATSUTextLayout textLayout;
- ATSLayoutRecord *layoutRecords;
- cairo_atsui_font_t *font = abstract_font;
- ItemCount glyphCount;
- int i;
- CGPoint point;
- double xscale, yscale;
- CGAffineTransform device_to_user_scale;
-
- status = _cairo_utf8_to_utf16 ((unsigned char *)utf8, -1, &utf16, &n16);
- if (status)
- goto BAIL3;
-
- err = ATSUCreateTextLayout(&textLayout);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL3;
- }
-
- err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL2;
- }
-
- /* Set the style for all of the text */
- err = ATSUSetRunStyle(textLayout,
- font->style, kATSUFromTextBeginning, kATSUToTextEnd);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL2;
- }
-
- err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout,
- 0,
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- (void *)&layoutRecords,
- &glyphCount);
- if (err != noErr) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL2;
- }
-
- status = _cairo_matrix_compute_scale_factors (&font->base.ctm,
- &xscale, &yscale, 1);
- if (status)
- goto BAIL2;
-
- *num_glyphs = glyphCount - 1;
- *glyphs =
- (cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
- if (*glyphs == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL1;
- }
-
- device_to_user_scale =
- CGAffineTransformInvert (CGAffineTransformMake (xscale, 0,
- 0, yscale,
- 0, 0));
- for (i = 0; i < *num_glyphs; i++) {
- (*glyphs)[i].index = layoutRecords[i].glyphID;
- /* ATSLayoutRecord.realPos is in device units, convert to user units */
- point = CGPointMake (FixedToFloat (layoutRecords[i].realPos), 0);
- point = CGPointApplyAffineTransform (point, device_to_user_scale);
-
- (*glyphs)[i].x = x + point.x;
- (*glyphs)[i].y = y;
- }
-
- BAIL1:
- /* TODO ignored return value. Is there anything we should do? */
- ATSUDirectReleaseLayoutDataArrayPtr(NULL,
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- (void *) &layoutRecords);
- BAIL2:
- ATSUDisposeTextLayout(textLayout);
- BAIL3:
- free (utf16);
-
- return status;
-}
-
-CGFontRef
-_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont)
-{
- cairo_atsui_font_t *afont = (cairo_atsui_font_t *) sfont;
-
- if (!afont->cgfref) {
- ATSFontRef atsfref = FMGetATSFontRefFromFont (afont->fontID);
- afont->cgfref = CGFontCreateWithPlatformFont (&atsfref);
- }
- return afont->cgfref;
-}
-
-
-static cairo_int_status_t
-_cairo_atsui_load_truetype_table (void *abstract_font,
- unsigned long tag,
- long offset,
- unsigned char *buffer,
- unsigned long *length)
-{
- cairo_atsui_font_t *scaled_font = abstract_font;
- ATSFontRef atsFont;
- OSStatus err;
-
- atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
- err = ATSFontGetTable ( atsFont, tag,
- (ByteOffset) offset,
- (ByteCount) *length,
- buffer,
- length);
- if (err != noErr) {
- return CAIRO_INT_STATUS_UNSUPPORTED;
- }
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
- CAIRO_FONT_TYPE_QUARTZ,
- _cairo_atsui_font_create_toy,
- _cairo_atsui_font_fini,
- _cairo_atsui_font_scaled_glyph_init,
- _cairo_atsui_font_text_to_glyphs,
- NULL, /* ucs4_to_index */
- NULL, /* show_glyphs */
- _cairo_atsui_load_truetype_table,
- NULL, /* map_glyphs_to_unicode */
-};
-
commit 8ddae11b544c35057a96ca0bdea34b4f473ee261
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Apr 1 13:26:00 2008 -0700
[quartz] Update documentation
diff --git a/doc/public/tmpl/cairo-ft.sgml b/doc/public/tmpl/cairo-ft.sgml
index 68a3fd4..8414c86 100644
--- a/doc/public/tmpl/cairo-ft.sgml
+++ b/doc/public/tmpl/cairo-ft.sgml
@@ -20,14 +20,6 @@ systems, but can be used on other platforms too.
<!-- ##### SECTION Stability_Level ##### -->
-<!-- ##### MACRO CAIRO_HAS_FT_FONT ##### -->
-<para>
-Defined if the FreeType font backend is available.
-This macro can be used to conditionally compile backend-specific code.
-</para>
-
-
-
<!-- ##### FUNCTION cairo_ft_font_face_create_for_ft_face ##### -->
<para>
diff --git a/doc/public/tmpl/cairo-quartz-fonts.sgml b/doc/public/tmpl/cairo-quartz-fonts.sgml
index 28facca..3e7cd4d 100644
--- a/doc/public/tmpl/cairo-quartz-fonts.sgml
+++ b/doc/public/tmpl/cairo-quartz-fonts.sgml
@@ -21,3 +21,28 @@ implementation of the font backend methods.
<!-- ##### SECTION Stability_Level ##### -->
+<!-- ##### MACRO CAIRO_HAS_QUARTZ_FONT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION cairo_quartz_font_face_create_for_cgfont ##### -->
+<para>
+
+</para>
+
+ at font:
+ at Returns:
+
+
+<!-- ##### FUNCTION cairo_quartz_font_face_create_for_atsu_font_id ##### -->
+<para>
+
+</para>
+
+ at font_id:
+ at Returns:
+
+
diff --git a/doc/public/tmpl/cairo-quartz.sgml b/doc/public/tmpl/cairo-quartz.sgml
index 56f4c8b..78fe8de 100644
--- a/doc/public/tmpl/cairo-quartz.sgml
+++ b/doc/public/tmpl/cairo-quartz.sgml
@@ -20,6 +20,13 @@ Apple OS X Quartz rendering system.
<!-- ##### SECTION Stability_Level ##### -->
+<!-- ##### MACRO CAIRO_HAS_QUARTZ_SURFACE ##### -->
+<para>
+
+</para>
+
+
+
<!-- ##### FUNCTION cairo_quartz_surface_create ##### -->
<para>
@@ -51,21 +58,3 @@ Apple OS X Quartz rendering system.
@Returns:
-<!-- ##### FUNCTION cairo_quartz_image_surface_create ##### -->
-<para>
-
-</para>
-
- at image_surface:
- at Returns:
-
-
-<!-- ##### FUNCTION cairo_quartz_image_surface_get_image ##### -->
-<para>
-
-</para>
-
- at surface:
- at Returns:
-
-
diff --git a/doc/public/tmpl/cairo-xlib.sgml b/doc/public/tmpl/cairo-xlib.sgml
index df6977c..e0927d0 100644
--- a/doc/public/tmpl/cairo-xlib.sgml
+++ b/doc/public/tmpl/cairo-xlib.sgml
@@ -24,14 +24,6 @@ if it is available.
<!-- ##### SECTION Stability_Level ##### -->
-<!-- ##### MACRO CAIRO_HAS_XLIB_SURFACE ##### -->
-<para>
-Defined if the XLib surface backend is available.
-This macro can be used to conditionally compile backend-specific code.
-</para>
-
-
-
<!-- ##### FUNCTION cairo_xlib_surface_create ##### -->
<para>
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index ae39f2b..52a5498 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -156,7 +156,16 @@ static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
/**
* cairo_quartz_font_face_create_for_cgfont
- * @font: a CGFontRef obtained through other means
+ * @font: a #CGFontRef obtained through a method external to cairo.
+ *
+ * Creates a new font for the Quartz font backend based on a
+ * #CGFontRef. This font can then be used with
+ * cairo_set_font_face() or cairo_scaled_font_create().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ * cairo_font_face_destroy() when you are done using it.
+ *
+ * Since: 1.6
*/
cairo_font_face_t *
cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
@@ -684,8 +693,9 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
/*
* compat with old ATSUI backend
*/
+
/**
- * cairo_atsui_font_face_create_for_atsu_font_id
+ * cairo_quartz_font_face_create_for_atsu_font_id
* @font_id: an ATSUFontID for the font.
*
* Creates a new font for the Quartz font backend based on an
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 576e641..7d90fba 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -2373,22 +2373,20 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
* @height: height of the surface, in pixels
*
* Creates a Quartz surface that wraps the given CGContext. The
- * CGContext is assumed to be in the QuickDraw coordinate space (that
- * is, with the origin at the upper left and the Y axis increasing
- * downward.) If the CGContext is in the Quartz coordinate space (with
- * the origin at the bottom left), then it should be flipped before
- * this function is called:
+ * CGContext is assumed to be in the standard Cairo coordinate space
+ * (that is, with the origin at the upper left and the Y axis
+ * increasing downward). If the CGContext is in the Quartz coordinate
+ * space (with the origin at the bottom left), then it should be
+ * flipped before this function is called. The flip can be accomplished
+ * using a translate and a scale; for example:
*
* <informalexample><programlisting>
* CGContextTranslateCTM (cgContext, 0.0, height);
* CGContextScaleCTM (cgContext, 1.0, -1.0);
* </programlisting></informalexample>
*
- * A very small number of Cairo operations cannot be translated to
- * Quartz operations; those operations will fail on this surface.
- * If all Cairo operations are required to succeed, consider rendering
- * to a surface created by cairo_quartz_surface_create() and then copying
- * the result to the CGContext.
+ * All Cairo operations are implemented in terms of Quartz operations,
+ * as long as Quartz-compatible elements are used (such as Quartz fonts).
*
* Return value: the newly created Cairo surface.
*
commit 9a7162cfdf48f47bb8ee0a7c24c55c061e4fbc90
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Apr 1 13:17:14 2008 -0700
[doc] Add some Quartz/CGFont documentation templates
diff --git a/doc/public/cairo-docs.xml b/doc/public/cairo-docs.xml
index 9eb9b32..73eeeda 100644
--- a/doc/public/cairo-docs.xml
+++ b/doc/public/cairo-docs.xml
@@ -24,6 +24,7 @@
<xi:include href="xml/cairo-font-options.xml"/>
<xi:include href="xml/cairo-ft.xml"/>
<xi:include href="xml/cairo-win32-fonts.xml"/>
+ <xi:include href="xml/cairo-quartz-fonts.xml"/>
</chapter>
<chapter id="Surfaces">
<title>Surfaces</title>
diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt
index 8abd2c6..98cc974 100644
--- a/doc/public/cairo-sections.txt
+++ b/doc/public/cairo-sections.txt
@@ -24,6 +24,14 @@ cairo_win32_scaled_font_get_device_to_logical
</SECTION>
<SECTION>
+<FILE>cairo-quartz-fonts</FILE>
+<TITLE>Quartz Fonts</TITLE>
+CAIRO_HAS_QUARTZ_FONT
+cairo_quartz_font_face_create_for_cgfont
+cairo_quartz_font_face_create_for_atsu_font_id
+</SECTION>
+
+<SECTION>
<FILE>cairo-image</FILE>
<TITLE>Image Surfaces</TITLE>
cairo_format_t
@@ -95,6 +103,12 @@ CAIRO_HAS_QUARTZ_SURFACE
cairo_quartz_surface_create
cairo_quartz_surface_create_for_cg_context
cairo_quartz_surface_get_cg_context
+</SECTION>
+
+<SECTION>
+<FILE>cairo-quartz-image</FILE>
+<TITLE>Quartz Image Surfaces</TITLE>
+CAIRO_HAS_QUARTZ_IMAGE_SURFACE
cairo_quartz_image_surface_create
cairo_quartz_image_surface_get_image
</SECTION>
diff --git a/doc/public/tmpl/cairo-quartz-fonts.sgml b/doc/public/tmpl/cairo-quartz-fonts.sgml
new file mode 100644
index 0000000..28facca
--- /dev/null
+++ b/doc/public/tmpl/cairo-quartz-fonts.sgml
@@ -0,0 +1,23 @@
+<!-- ##### SECTION Title ##### -->
+Quartz (CGFont) Fonts
+
+<!-- ##### SECTION Short_Description ##### -->
+Font support via CGFont on OS X
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+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.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+<itemizedlist>
+<listitem>#cairo_font_face_t</listitem>
+</itemizedlist>
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
commit 56cabc352e44ee7cb2989dd81688f6c37c33fc21
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Apr 1 13:01:41 2008 -0700
[quartz] Update Quartz test reference images
diff --git a/test/Makefile.am b/test/Makefile.am
index 86b6de5..b1498bf 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -416,6 +416,7 @@ REFERENCE_IMAGES = \
linear-gradient-reflect-pdf-argb32-ref.png \
linear-gradient-reflect-pdf-rgb24-ref.png \
linear-gradient-reflect-ps-ref.png \
+ linear-gradient-reflect-quartz-ref.png \
linear-gradient-pdf-ref.png \
linear-gradient-ps-ref.png \
linear-gradient-quartz-ref.png \
@@ -587,6 +588,7 @@ REFERENCE_IMAGES = \
surface-pattern-scale-down-pdf-argb32-ref.png \
surface-pattern-scale-down-ps-argb32-ref.png \
surface-pattern-scale-down-ref.png \
+ surface-pattern-scale-down-quartz-ref.png \
surface-pattern-scale-up-pdf-argb32-ref.png \
surface-pattern-scale-up-ps-argb32-ref.png \
surface-pattern-scale-up-ref.png \
@@ -608,6 +610,7 @@ REFERENCE_IMAGES = \
text-pattern-svg-rgb24-ref.png \
text-pattern-pdf-argb32-ref.png \
text-pattern-pdf-rgb24-ref.png \
+ text-pattern-quartz-ref.png \
text-pattern-quartz-rgb24-ref.png \
text-rotate-ref.png \
text-rotate-ps-ref.png \
diff --git a/test/clip-operator-quartz-ref.png b/test/clip-operator-quartz-ref.png
index 329f684..1726944 100644
Binary files a/test/clip-operator-quartz-ref.png and b/test/clip-operator-quartz-ref.png differ
diff --git a/test/clip-operator-quartz-rgb24-ref.png b/test/clip-operator-quartz-rgb24-ref.png
index f539baf..a18c6f2 100644
Binary files a/test/clip-operator-quartz-rgb24-ref.png and b/test/clip-operator-quartz-rgb24-ref.png differ
diff --git a/test/font-matrix-translation-quartz-ref.png b/test/font-matrix-translation-quartz-ref.png
index c0fbc16..90fd962 100644
Binary files a/test/font-matrix-translation-quartz-ref.png and b/test/font-matrix-translation-quartz-ref.png differ
diff --git a/test/glyph-cache-pressure-quartz-ref.png b/test/glyph-cache-pressure-quartz-ref.png
index b067e92..88d3db6 100644
Binary files a/test/glyph-cache-pressure-quartz-ref.png and b/test/glyph-cache-pressure-quartz-ref.png differ
diff --git a/test/linear-gradient-reflect-quartz-ref.png b/test/linear-gradient-reflect-quartz-ref.png
new file mode 100644
index 0000000..a0067ac
Binary files /dev/null and b/test/linear-gradient-reflect-quartz-ref.png differ
diff --git a/test/operator-clear-quartz-ref.png b/test/operator-clear-quartz-ref.png
index d0034a7..095f182 100644
Binary files a/test/operator-clear-quartz-ref.png and b/test/operator-clear-quartz-ref.png differ
diff --git a/test/operator-clear-quartz-rgb24-ref.png b/test/operator-clear-quartz-rgb24-ref.png
index 6f3fc2c..f978967 100644
Binary files a/test/operator-clear-quartz-rgb24-ref.png and b/test/operator-clear-quartz-rgb24-ref.png differ
diff --git a/test/operator-source-quartz-ref.png b/test/operator-source-quartz-ref.png
index d02f513..31fc441 100644
Binary files a/test/operator-source-quartz-ref.png and b/test/operator-source-quartz-ref.png differ
diff --git a/test/operator-source-quartz-rgb24-ref.png b/test/operator-source-quartz-rgb24-ref.png
index 7dc8d80..358e951 100644
Binary files a/test/operator-source-quartz-rgb24-ref.png and b/test/operator-source-quartz-rgb24-ref.png differ
diff --git a/test/select-font-face-quartz-ref.png b/test/select-font-face-quartz-ref.png
index 228b227..8f285b8 100644
Binary files a/test/select-font-face-quartz-ref.png and b/test/select-font-face-quartz-ref.png differ
diff --git a/test/show-text-current-point-quartz-ref.png b/test/show-text-current-point-quartz-ref.png
index d96b305..538b0d1 100644
Binary files a/test/show-text-current-point-quartz-ref.png and b/test/show-text-current-point-quartz-ref.png differ
diff --git a/test/surface-pattern-scale-down-quartz-ref.png b/test/surface-pattern-scale-down-quartz-ref.png
new file mode 100644
index 0000000..93a34da
Binary files /dev/null and b/test/surface-pattern-scale-down-quartz-ref.png differ
diff --git a/test/text-antialias-gray-quartz-ref.png b/test/text-antialias-gray-quartz-ref.png
index afe9928..573848d 100644
Binary files a/test/text-antialias-gray-quartz-ref.png and b/test/text-antialias-gray-quartz-ref.png differ
diff --git a/test/text-antialias-none-quartz-ref.png b/test/text-antialias-none-quartz-ref.png
index 32537fc..bcee5da 100644
Binary files a/test/text-antialias-none-quartz-ref.png and b/test/text-antialias-none-quartz-ref.png differ
diff --git a/test/text-antialias-subpixel-quartz-ref.png b/test/text-antialias-subpixel-quartz-ref.png
index bab8a72..ffd487f 100644
Binary files a/test/text-antialias-subpixel-quartz-ref.png and b/test/text-antialias-subpixel-quartz-ref.png differ
diff --git a/test/text-pattern-quartz-ref.png b/test/text-pattern-quartz-ref.png
new file mode 100644
index 0000000..5cb5874
Binary files /dev/null and b/test/text-pattern-quartz-ref.png differ
diff --git a/test/text-pattern-quartz-rgb24-ref.png b/test/text-pattern-quartz-rgb24-ref.png
index 9f4da3a..7eae4c8 100644
Binary files a/test/text-pattern-quartz-rgb24-ref.png and b/test/text-pattern-quartz-rgb24-ref.png differ
diff --git a/test/text-rotate-quartz-ref.png b/test/text-rotate-quartz-ref.png
index 9e2c59f..6fb7f3d 100644
Binary files a/test/text-rotate-quartz-ref.png and b/test/text-rotate-quartz-ref.png differ
diff --git a/test/unbounded-operator-quartz-ref.png b/test/unbounded-operator-quartz-ref.png
index 69c0d5e..b0501db 100644
Binary files a/test/unbounded-operator-quartz-ref.png and b/test/unbounded-operator-quartz-ref.png differ
diff --git a/test/unbounded-operator-quartz-rgb24-ref.png b/test/unbounded-operator-quartz-rgb24-ref.png
index a7a0b0e..f8dae18 100644
Binary files a/test/unbounded-operator-quartz-rgb24-ref.png and b/test/unbounded-operator-quartz-rgb24-ref.png differ
commit 94b67d13f38d860f1a768f9a088e3b6f5d188f7b
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Apr 1 12:44:32 2008 -0700
[quartz] Handle further 10.4 vs. 10.5 differences; fix text AA handling
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 5b6cecb..576e641 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -101,13 +101,14 @@ CG_EXTERN void CGContextReplacePathWithStrokedPath (CGContextRef);
CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
#endif
-/* Only present in 10.4+ */
+/* Some of these are present in earlier versions of the OS than where
+ * they are public; others are not public at all (CGContextCopyPath,
+ * CGContextReplacePathWithClipPath, many of the getters, etc.)
+ */
static void (*CGContextClipToMaskPtr) (CGContextRef, CGRect, CGImageRef) = NULL;
-/* Only present in 10.5+ */
static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
static void (*CGContextSetShouldAntialiasFontsPtr) (CGContextRef, bool) = NULL;
-static void (*CGContextSetShouldSmoothFontsPtr) (CGContextRef, bool) = NULL;
static bool (*CGContextGetShouldAntialiasFontsPtr) (CGContextRef) = NULL;
static bool (*CGContextGetShouldSmoothFontsPtr) (CGContextRef) = NULL;
static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
@@ -115,6 +116,8 @@ static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL;
static void (*CGContextReplacePathWithClipPathPtr) (CGContextRef) = NULL;
+static SInt32 _cairo_quartz_osx_version = 0x0;
+
static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
/*
@@ -142,7 +145,6 @@ static void quartz_ensure_symbols(void)
CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetType");
CGContextSetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldAntialiasFonts");
- CGContextSetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldSmoothFonts");
CGContextGetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldAntialiasFonts");
CGContextGetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldSmoothFonts");
CGContextCopyPathPtr = dlsym(RTLD_DEFAULT, "CGContextCopyPath");
@@ -150,6 +152,11 @@ static void quartz_ensure_symbols(void)
CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
+ if (Gestalt(gestaltSystemVersion, &_cairo_quartz_osx_version) != noErr) {
+ // assume 10.4
+ _cairo_quartz_osx_version = 0x1040;
+ }
+
_cairo_quartz_symbol_lookup_done = TRUE;
}
@@ -478,6 +485,10 @@ _cairo_quartz_fixup_unbounded_operation (cairo_quartz_surface_t *surface,
CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y);
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);
}
@@ -1916,29 +1927,27 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
CGContextSetFont (surface->cgContext, cgfref);
CGContextSetFontSize (surface->cgContext, 1.0);
- if (CGContextSetShouldAntialiasFontsPtr) {
- switch (scaled_font->options.antialias) {
- case CAIRO_ANTIALIAS_SUBPIXEL:
- CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
- CGContextSetShouldSmoothFontsPtr (surface->cgContext, TRUE);
- if (CGContextSetAllowsFontSmoothingPtr &&
- !CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
- {
- didForceFontSmoothing = TRUE;
- CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
- }
- break;
- case CAIRO_ANTIALIAS_NONE:
- CGContextSetShouldAntialiasFontsPtr (surface->cgContext, FALSE);
- break;
- case CAIRO_ANTIALIAS_GRAY:
- CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
- CGContextSetShouldSmoothFontsPtr (surface->cgContext, FALSE);
- break;
- case CAIRO_ANTIALIAS_DEFAULT:
- /* Don't do anything */
- break;
- }
+ switch (scaled_font->options.antialias) {
+ case CAIRO_ANTIALIAS_SUBPIXEL:
+ CGContextSetShouldAntialias (surface->cgContext, TRUE);
+ CGContextSetShouldSmoothFonts (surface->cgContext, TRUE);
+ if (CGContextSetAllowsFontSmoothingPtr &&
+ !CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
+ {
+ didForceFontSmoothing = TRUE;
+ CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
+ }
+ break;
+ case CAIRO_ANTIALIAS_NONE:
+ CGContextSetShouldAntialias (surface->cgContext, FALSE);
+ break;
+ case CAIRO_ANTIALIAS_GRAY:
+ CGContextSetShouldAntialias (surface->cgContext, TRUE);
+ CGContextSetShouldSmoothFonts (surface->cgContext, FALSE);
+ break;
+ case CAIRO_ANTIALIAS_DEFAULT:
+ /* Don't do anything */
+ break;
}
if (num_glyphs > STATIC_BUF_SIZE) {
@@ -1987,10 +1996,13 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
yprev = yf;
}
- if (isClipping) {
- /* If we're clipping, we get multiplied by the inverse of our text matrix; no,
- * I don't understand why this is any different. So pre-apply our textTransform.
- * Note that the new CGContextShowGlyphsAtPositions has a similar problem. */
+ if (_cairo_quartz_osx_version >= 0x1050 && isClipping) {
+ /* If we're clipping, OSX 10.5 (at least as of 10.5.2) has a
+ * bug (apple bug ID #5834794) where the glyph
+ * advances/positions are not transformed by the text matrix
+ * if kCGTextClip is being used. So, we pre-transform here.
+ * 10.4 does not have this problem (as of 10.4.11).
+ */
for (i = 0; i < num_glyphs - 1; i++)
cg_advances[i] = CGSizeApplyAffineTransform(cg_advances[i], textTransform);
}
commit a1d1be4234f7787c078ff096b4101e300494e7d1
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Thu Mar 27 23:46:53 2008 -0700
[cgfont] Round surface rectangle outwards to ensure whole-pixel dimensions
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 3cd83fe..ae39f2b 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -335,31 +335,57 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
+ CGAffineTransform textMatrix;
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
int advance;
CGRect bbox;
double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+ double xscale, yscale;
double xmin, ymin, xmax, ymax;
if (glyph == INVALID_GLYPH)
goto FAIL;
- if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance))
+ if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
+ !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
goto FAIL;
- if (!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
+ status = _cairo_matrix_compute_scale_factors (&font->base.scale,
+ &xscale, &yscale, 1);
+ if (status)
goto FAIL;
+ 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);
#endif
- xmin = CGRectGetMinX(bbox) / emscale;
- ymin = CGRectGetMinY(bbox) / emscale;
- xmax = CGRectGetMaxX(bbox) / emscale;
- ymax = CGRectGetMaxY(bbox) / emscale;
+ xmin = CGRectGetMinX(bbox);
+ ymin = CGRectGetMinY(bbox);
+ xmax = CGRectGetMaxX(bbox);
+ ymax = CGRectGetMaxY(bbox);
extents.x_bearing = xmin;
extents.y_bearing = - ymax;
@@ -494,7 +520,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
CGColorSpaceRef gray;
CGContextRef cgContext = NULL;
CGAffineTransform textMatrix;
- CGRect glyphRect;
+ CGRect glyphRect, glyphRectInt;
CGPoint glyphOrigin;
//fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
@@ -536,16 +562,26 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
bbox.size.width / emscale,
bbox.size.height / emscale);
- //fprintf (stderr, "glyphRect[o]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
-
glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
- glyphOrigin = glyphRect.origin;
+ /* Round the rectangle outwards, so that we don't have to deal
+ * with non-integer-pixel origins or dimensions.
+ */
+ glyphRectInt = CGRectIntegral (glyphRect);
+
+#if 0
+ 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",
+ glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
+#endif
+
+ glyphOrigin = glyphRectInt.origin;
//textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
- width = ceil(glyphRect.size.width);
- height = ceil(glyphRect.size.height);
+ 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);
commit c064ad1b56d11950786a3fd0363e543f5aec1761
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Thu Mar 27 11:42:53 2008 -0700
[cgfont] Fix whitespace errors
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 2d05a62..3cd83fe 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -548,7 +548,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
height = ceil(glyphRect.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;
@@ -570,7 +570,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));
if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
- CGContextSetShouldAntialias (cgContext, false);
+ CGContextSetShouldAntialias (cgContext, false);
CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
commit 2be3e67db24ac34f772b5fc1182dfb9b730dce11
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Tue Mar 25 22:44:39 2008 -0700
[cgfont] Add CGFont backend to replace deprecated ATSUI backend
Create a new font backend that uses the CGFont API on MacOS X
10.4 and beyond.
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 7c714aa..2d05a62 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -41,12 +41,59 @@
#include "cairo-quartz.h"
#include "cairo-quartz-private.h"
+/* 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;
+
/* Not public, but present */
-extern void CGFontGetGlyphsForUnichars (CGFontRef, const UniChar[], const CGGlyph[], size_t);
+static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL;
/* Not public in the least bit */
static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = 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;
+
+ /* 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");
+
+ /* 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");
+ CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
+
+ if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
+ CGFontGetGlyphBBoxesPtr &&
+ CGFontGetGlyphsForUnicharsPtr &&
+ CGFontGetUnitsPerEmPtr &&
+ CGFontGetGlyphAdvancesPtr &&
+ CGFontGetGlyphPathPtr)
+ _cairo_quartz_font_symbols_present = TRUE;
+
+ _cairo_quartz_font_symbol_lookup_done = TRUE;
+}
+
typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t;
typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
@@ -83,6 +130,10 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
cairo_quartz_scaled_font_t *font;
cairo_status_t status;
+ quartz_font_ensure_symbols();
+ if (!_cairo_quartz_font_symbols_present)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
font = malloc(sizeof(cairo_quartz_scaled_font_t));
if (font == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -112,6 +163,8 @@ cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
{
cairo_quartz_font_face_t *font_face;
+ quartz_font_ensure_symbols();
+
font_face = malloc (sizeof (cairo_quartz_font_face_t));
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -157,6 +210,10 @@ _cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
cairo_font_face_t *face;
cairo_scaled_font_t *scaled_font;
+ quartz_font_ensure_symbols();
+ if (!_cairo_quartz_font_symbols_present)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
/* handle CSS-ish faces */
if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
family = "Times";
@@ -191,9 +248,13 @@ _cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
strcat (full_name, " Oblique");
}
- cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
- cgFont = CGFontCreateWithFontName (cgFontName);
- CFRelease (cgFontName);
+ if (CGFontCreateWithFontNamePtr) {
+ cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
+ cgFont = CGFontCreateWithFontNamePtr (cgFontName);
+ CFRelease (cgFontName);
+ } else {
+ cgFont = CGFontCreateWithNamePtr (full_name);
+ }
if (cgFont)
break;
@@ -277,16 +338,16 @@ _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 = CGFontGetUnitsPerEm (font_face->cgFont);
+ double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
double xmin, ymin, xmax, ymax;
if (glyph == INVALID_GLYPH)
goto FAIL;
- if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance))
+ if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance))
goto FAIL;
- if (!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
+ if (!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
goto FAIL;
#if 0
@@ -379,12 +440,6 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
CGPathRef glyphPath;
cairo_path_fixed_t *path;
- if (CGFontGetGlyphPathPtr == NULL)
- CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
-
- if (!CGFontGetGlyphPathPtr)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
if (glyph == INVALID_GLYPH) {
_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
return CAIRO_STATUS_SUCCESS;
@@ -434,7 +489,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
CGRect bbox;
double width, height;
double xscale, yscale;
- double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
+ double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
CGColorSpaceRef gray;
CGContextRef cgContext = NULL;
@@ -460,8 +515,8 @@ _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))
+ if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
+ !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -560,7 +615,7 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
UniChar u = (UniChar) ucs4;
CGGlyph glyph;
- CGFontGetGlyphsForUnichars (ffont->cgFont, &u, &glyph, 1);
+ CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1);
return glyph;
}
@@ -588,3 +643,38 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
return ffont->cgFont;
}
+
+
+/*
+ * compat with old ATSUI backend
+ */
+/**
+ * cairo_atsui_font_face_create_for_atsu_font_id
+ * @font_id: an ATSUFontID for the font.
+ *
+ * Creates a new font for the Quartz font backend based on an
+ * #ATSUFontID. This font can then be used with
+ * cairo_set_font_face() or cairo_scaled_font_create().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ * cairo_font_face_destroy() when you are done using it.
+ *
+ * Since: 1.6
+ **/
+cairo_font_face_t *
+cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
+{
+ ATSFontRef atsFont = FMGetATSFontRefFromFont (font_id);
+ CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont);
+
+ return cairo_quartz_font_face_create_for_cgfont (cgFont);
+}
+
+/* This is the old name for the above function, exported for compat purposes */
+cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
+
+cairo_font_face_t *
+cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
+{
+ return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
+}
commit 30f7fae6475c36549badf1fcc11ae39d1d79b532
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Thu Mar 20 13:24:48 2008 -0700
[cgfont] Add start of CGFont font backend to replace ATSUI
diff --git a/configure.in b/configure.in
index 62aafcf..65080bd 100644
--- a/configure.in
+++ b/configure.in
@@ -357,8 +357,14 @@ dnl ===========================================================================
CAIRO_BACKEND_ENABLE(quartz, Quartz, quartz, QUARTZ_SURFACE, no, [
dnl There is no pkgconfig for quartz; lets do a header check
- AC_CHECK_HEADER(Carbon/Carbon.h, , [use_quartz="no (Carbon headers not found)"])
- quartz_LIBS="-Xlinker -framework -Xlinker Carbon"
+ AC_CHECK_HEADER(ApplicationServices/ApplicationServices.h, , [use_quartz="no (ApplicationServices framework not found)"])
+ if test "x$use_quartz" != "xyes" ; then
+ dnl check for CoreGraphics as a separate framework
+ AC_CHECK_HEADER(CoreGraphics/CoreGraphics.h, , [use_quartz="no (CoreGraphics framework not found)"])
+ quartz_LIBS="-Xlinker -framework -Xlinker CoreGraphics"
+ else
+ quartz_LIBS="-Xlinker -framework -Xlinker ApplicationServices"
+ fi
])
CAIRO_BACKEND_ENABLE(quartz_font, Quartz font, quartz-font, QUARTZ_FONT, auto, [
diff --git a/src/Makefile.am b/src/Makefile.am
index 32b2df2..dfdcf1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -191,11 +191,10 @@ cairo_headers += cairo-quartz-image.h
backend_pkgconfigs += cairo-quartz-image.pc
endif
-quartz_font_sources = cairo-atsui-font.c
+quartz_font_sources = cairo-quartz-font.c
cairo_all_sources += $(quartz_font_sources)
if CAIRO_HAS_QUARTZ_FONT
cairo_sources += $(quartz_font_sources)
-backend_pkgconfigs += cairo-quartz-font.pc
endif
os_win32_sources = cairo-win32.c
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 6866bb5..42c209b 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -641,7 +641,7 @@ _cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
cairo_matrix_t unscaled_font_to_device;
double xscale;
double yscale;
-
+
scaled_path.path = _cairo_path_fixed_create ();
if (!scaled_path.path)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
new file mode 100644
index 0000000..7c714aa
--- /dev/null
+++ b/src/cairo-quartz-font.c
@@ -0,0 +1,590 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright � 2008 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir at mozilla.com>
+ */
+
+#include <dlfcn.h>
+
+#include "cairoint.h"
+
+#include "cairo-quartz.h"
+#include "cairo-quartz-private.h"
+
+/* Not public, but present */
+extern void CGFontGetGlyphsForUnichars (CGFontRef, const UniChar[], const CGGlyph[], size_t);
+
+/* Not public in the least bit */
+static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
+
+typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t;
+typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
+
+struct _cairo_quartz_scaled_font {
+ cairo_scaled_font_t base;
+};
+
+struct _cairo_quartz_font_face {
+ cairo_font_face_t base;
+
+ CGFontRef cgFont;
+};
+
+/**
+ ** font face backend
+ **/
+
+static void
+_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);
+}
+
+static cairo_status_t
+_cairo_quartz_font_face_scaled_font_create (void *abstract_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **font_out)
+{
+ cairo_quartz_font_face_t *font_face = abstract_face;
+ cairo_quartz_scaled_font_t *font;
+ cairo_status_t status;
+
+ font = malloc(sizeof(cairo_quartz_scaled_font_t));
+ if (font == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ memset (font, 0, sizeof(cairo_quartz_scaled_font_t));
+
+ status = _cairo_scaled_font_init (&font->base,
+ &font_face->base, font_matrix, ctm, options,
+ &cairo_quartz_scaled_font_backend);
+
+ *font_out = (cairo_scaled_font_t*) font;
+ return status;
+}
+
+static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
+ CAIRO_FONT_TYPE_QUARTZ,
+ _cairo_quartz_font_face_destroy,
+ _cairo_quartz_font_face_scaled_font_create
+};
+
+/**
+ * cairo_quartz_font_face_create_for_cgfont
+ * @font: a CGFontRef obtained through other means
+ */
+cairo_font_face_t *
+cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
+{
+ cairo_quartz_font_face_t *font_face;
+
+ font_face = malloc (sizeof (cairo_quartz_font_face_t));
+ if (!font_face) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
+
+ font_face->cgFont = CGFontRetain (font);
+
+ _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
+
+ return &font_face->base;
+}
+
+/**
+ ** scaled font backend
+ **/
+
+static cairo_quartz_font_face_t *
+_cairo_quartz_scaled_to_face (void *abstract_font)
+{
+ cairo_quartz_scaled_font_t *sfont = (cairo_quartz_scaled_font_t*) abstract_font;
+ cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (&sfont->base);
+ if (!font_face || font_face->backend->type != CAIRO_FONT_TYPE_QUARTZ)
+ return NULL;
+
+ return (cairo_quartz_font_face_t*) font_face;
+}
+
+static cairo_status_t
+_cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **font_out)
+{
+ const char *family = toy_face->family;
+ char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
+ CFStringRef cgFontName = NULL;
+ CGFontRef cgFont = NULL;
+ int loop;
+
+ cairo_status_t status;
+ cairo_font_face_t *face;
+ cairo_scaled_font_t *scaled_font;
+
+ /* handle CSS-ish faces */
+ if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
+ family = "Times";
+ else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
+ family = "Helvetica";
+ else if (!strcmp(family, "cursive"))
+ family = "Apple Chancery";
+ else if (!strcmp(family, "fantasy"))
+ family = "Papyrus";
+ else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
+ family = "Courier";
+
+ /* Try to build up the full name, e.g. "Helvetica Bold Oblique" first,
+ * then drop the bold, then drop the slant, then drop both.. finally
+ * just use "Helvetica". And if Helvetica doesn't exist, give up.
+ */
+ for (loop = 0; loop < 5; loop++) {
+ if (loop == 4)
+ family = "Helvetica";
+
+ strcpy (full_name, family);
+
+ if (loop < 3 && (loop & 1) == 0) {
+ if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
+ strcat (full_name, " Bold");
+ }
+
+ if (loop < 3 && (loop & 2) == 0) {
+ if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
+ strcat (full_name, " Italic");
+ else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
+ strcat (full_name, " Oblique");
+ }
+
+ cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
+ cgFont = CGFontCreateWithFontName (cgFontName);
+ CFRelease (cgFontName);
+
+ if (cgFont)
+ break;
+ }
+
+ if (!cgFont) {
+ /* Give up */
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ face = cairo_quartz_font_face_create_for_cgfont (cgFont);
+ if (face->status)
+ return face->status;
+
+ status = _cairo_quartz_font_face_scaled_font_create (face,
+ font_matrix, ctm,
+ options,
+ &scaled_font);
+ cairo_font_face_destroy (face);
+ if (status)
+ return status;
+
+ *font_out = scaled_font;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_quartz_font_fini(void *abstract_font)
+{
+}
+
+#define INVALID_GLYPH 0x00
+
+static inline CGGlyph
+_cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
+ unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
+ if (index > 0xffff)
+ return INVALID_GLYPH;
+ return (CGGlyph) index;
+}
+
+static inline cairo_status_t
+_cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform *txout,
+ double *xout, double *yout)
+{
+ CGAffineTransform transform;
+ double xscale, yscale;
+ cairo_status_t status;
+
+ status = _cairo_matrix_compute_scale_factors (m, &xscale, &yscale, 1);
+ if (status)
+ return status;
+
+ transform = CGAffineTransformMake (m->xx, - m->yx,
+ - m->xy, m->yy,
+ 0.0f, 0.0f);
+ if (xout)
+ *xout = xscale;
+ if (yout)
+ *yout = yscale;
+
+ if (xscale)
+ xscale = 1.0 / xscale;
+ if (yscale)
+ yscale = 1.0 / yscale;
+
+ *txout = CGAffineTransformScale (transform, xscale, yscale);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_quartz_init_glyph_metrics (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_text_extents_t extents = {0, 0, 0, 0, 0, 0};
+ CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
+ int advance;
+ CGRect bbox;
+ double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
+ double xmin, ymin, xmax, ymax;
+
+ if (glyph == INVALID_GLYPH)
+ goto FAIL;
+
+ if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance))
+ goto FAIL;
+
+ if (!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
+ goto FAIL;
+
+#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);
+#endif
+
+ xmin = CGRectGetMinX(bbox) / emscale;
+ ymin = CGRectGetMinY(bbox) / emscale;
+ xmax = CGRectGetMaxX(bbox) / emscale;
+ ymax = CGRectGetMaxY(bbox) / emscale;
+
+ extents.x_bearing = xmin;
+ extents.y_bearing = - ymax;
+ extents.width = xmax - xmin;
+ extents.height = ymax - ymin;
+
+ extents.x_advance = (double) advance / emscale;
+ extents.y_advance = 0.0;
+
+#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);
+#endif
+
+ FAIL:
+ _cairo_scaled_glyph_set_metrics (scaled_glyph,
+ &font->base,
+ &extents);
+
+ return status;
+}
+
+static void
+_cairo_quartz_path_apply_func (void *info, const CGPathElement *el)
+{
+ cairo_path_fixed_t *path = (cairo_path_fixed_t *) info;
+
+ switch (el->type) {
+ case kCGPathElementMoveToPoint:
+ _cairo_path_fixed_move_to (path,
+ _cairo_fixed_from_double(el->points[0].x),
+ _cairo_fixed_from_double(el->points[0].y));
+ break;
+ case kCGPathElementAddLineToPoint:
+ _cairo_path_fixed_line_to (path,
+ _cairo_fixed_from_double(el->points[0].x),
+ _cairo_fixed_from_double(el->points[0].y));
+ break;
+ case kCGPathElementAddQuadCurveToPoint: {
+ cairo_fixed_t fx, fy;
+ double x, y;
+ if (!_cairo_path_fixed_get_current_point (path, &fx, &fy))
+ fx = fy = 0;
+ x = _cairo_fixed_to_double (fx);
+ y = _cairo_fixed_to_double (fy);
+
+ _cairo_path_fixed_curve_to (path,
+ _cairo_fixed_from_double((x + el->points[0].x * 2.0) / 3.0),
+ _cairo_fixed_from_double((y + el->points[0].y * 2.0) / 3.0),
+ _cairo_fixed_from_double((el->points[0].x * 2.0 + el->points[1].x) / 3.0),
+ _cairo_fixed_from_double((el->points[0].y * 2.0 + el->points[1].y) / 3.0),
+ _cairo_fixed_from_double(el->points[1].x),
+ _cairo_fixed_from_double(el->points[1].y));
+ }
+ break;
+ case kCGPathElementAddCurveToPoint:
+ _cairo_path_fixed_curve_to (path,
+ _cairo_fixed_from_double(el->points[0].x),
+ _cairo_fixed_from_double(el->points[0].y),
+ _cairo_fixed_from_double(el->points[1].x),
+ _cairo_fixed_from_double(el->points[1].y),
+ _cairo_fixed_from_double(el->points[2].x),
+ _cairo_fixed_from_double(el->points[2].y));
+ break;
+ case kCGPathElementCloseSubpath:
+ _cairo_path_fixed_close_path (path);
+ break;
+ }
+}
+
+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;
+ cairo_path_fixed_t *path;
+
+ if (CGFontGetGlyphPathPtr == NULL)
+ CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
+
+ if (!CGFontGetGlyphPathPtr)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (glyph == INVALID_GLYPH) {
+ _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ textMatrix = CGAffineTransformMake (font->base.scale.xx,
+ -font->base.scale.yx,
+ -font->base.scale.xy,
+ font->base.scale.yy,
+ font->base.scale.x0,
+ font->base.scale.y0);
+
+ textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
+
+ glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
+ if (!glyphPath)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ path = _cairo_path_fixed_create ();
+ if (!path) {
+ CGPathRelease (glyphPath);
+ return _cairo_error(CAIRO_STATUS_NO_MEMORY);
+ }
+
+ CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);
+
+ CGPathRelease (glyphPath);
+
+ _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_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;
+ double width, height;
+ double xscale, yscale;
+ double emscale = CGFontGetUnitsPerEm (font_face->cgFont);
+
+ CGColorSpaceRef gray;
+ CGContextRef cgContext = NULL;
+ CGAffineTransform textMatrix;
+ CGRect glyphRect;
+ CGPoint glyphOrigin;
+
+ //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
+
+ /* 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.
+ */
+ if (glyph == INVALID_GLYPH) {
+ surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
+ status = cairo_surface_status ((cairo_surface_t *) surface);
+ if (status)
+ return status;
+
+ _cairo_scaled_glyph_set_surface (scaled_glyph,
+ &font->base,
+ surface);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
+ !CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
+ {
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ status = _cairo_matrix_compute_scale_factors (&font->base.scale,
+ &xscale, &yscale, 1);
+ if (status)
+ return status;
+
+ textMatrix = CGAffineTransformMake (font->base.scale.xx,
+ -font->base.scale.yx,
+ -font->base.scale.xy,
+ font->base.scale.yy,
+ 0.0f, 0.0f);
+ glyphRect = CGRectMake (bbox.origin.x / emscale,
+ bbox.origin.y / emscale,
+ bbox.size.width / emscale,
+ bbox.size.height / emscale);
+
+ //fprintf (stderr, "glyphRect[o]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
+
+ glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
+
+ glyphOrigin = glyphRect.origin;
+
+ //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
+
+ width = ceil(glyphRect.size.width);
+ height = ceil(glyphRect.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;
+
+ gray = CGColorSpaceCreateDeviceGray ();
+ cgContext = CGBitmapContextCreate (surface->data,
+ surface->width,
+ surface->height,
+ 8,
+ surface->stride,
+ gray,
+ kCGImageAlphaNone);
+ CGColorSpaceRelease (gray);
+
+ CGContextSetFont (cgContext, font_face->cgFont);
+ CGContextSetFontSize (cgContext, 1.0);
+ CGContextSetTextMatrix (cgContext, textMatrix);
+
+ CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));
+
+ if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
+ CGContextSetShouldAntialias (cgContext, false);
+
+ CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
+ CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
+
+ CGContextRelease (cgContext);
+
+ cairo_surface_set_device_offset (&surface->base,
+ - glyphOrigin.x,
+ height + glyphOrigin.y);
+
+ _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
+
+ return status;
+}
+
+static cairo_int_status_t
+_cairo_quartz_font_scaled_glyph_init (void *abstract_font,
+ cairo_scaled_glyph_t *scaled_glyph,
+ cairo_scaled_glyph_info_t info)
+{
+ cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+ if (!status && (info & CAIRO_SCALED_GLYPH_INFO_METRICS))
+ status = _cairo_quartz_init_glyph_metrics (font, scaled_glyph);
+
+ 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);
+
+ return status;
+}
+
+static unsigned long
+_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);
+ UniChar u = (UniChar) ucs4;
+ CGGlyph glyph;
+
+ CGFontGetGlyphsForUnichars (ffont->cgFont, &u, &glyph, 1);
+
+ return glyph;
+}
+
+const cairo_scaled_font_backend_t cairo_quartz_scaled_font_backend = {
+ CAIRO_FONT_TYPE_QUARTZ,
+ _cairo_quartz_font_create_toy,
+ _cairo_quartz_font_fini,
+ _cairo_quartz_font_scaled_glyph_init,
+ NULL, /* text_to_glyphs */
+ _cairo_quartz_ucs4_to_index,
+ NULL, /* show_glyphs */
+ NULL, /* load_truetype_table */
+ NULL, /* map_glyphs_to_unicode */
+};
+
+/*
+ * private methods that the quartz surface uses
+ */
+
+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;
+}
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index 0ab9bc0..07d5a8e 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -97,4 +97,9 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
+#if CAIRO_HAS_CGFONT_FONT
+CGFontRef
+_cairo_cgfont_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
+#endif /* CAIRO_HAS_CGFONT_FONT */
+
#endif /* CAIRO_QUARTZ_PRIVATE_H */
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 5296eb5..5b6cecb 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -48,7 +48,6 @@
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
#endif
-#include <Carbon/Carbon.h>
#include <limits.h>
#undef QUARTZ_DEBUG
diff --git a/src/cairo-quartz.h b/src/cairo-quartz.h
index b5c20e6..7982fbb 100644
--- a/src/cairo-quartz.h
+++ b/src/cairo-quartz.h
@@ -40,7 +40,7 @@
#if CAIRO_HAS_QUARTZ_SURFACE
-#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
CAIRO_BEGIN_DECLS
@@ -64,6 +64,9 @@ cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
#ifdef CAIRO_HAS_QUARTZ_FONT
cairo_public cairo_font_face_t *
+cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
+
+cairo_public cairo_font_face_t *
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
#endif /* CAIRO_HAS_QUARTZ_FONT */
diff --git a/src/cairoint.h b/src/cairoint.h
index 41d9182..6a89d71 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -455,7 +455,7 @@ extern const cairo_private struct _cairo_scaled_font_backend cairo_win32_scaled_
#if CAIRO_HAS_QUARTZ_FONT
-extern const cairo_private struct _cairo_scaled_font_backend cairo_atsui_scaled_font_backend;
+extern const cairo_private struct _cairo_scaled_font_backend cairo_quartz_scaled_font_backend;
#endif
@@ -873,7 +873,7 @@ typedef struct _cairo_traps {
#elif CAIRO_HAS_QUARTZ_FONT
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_QUARTZ_FONT_FAMILY_DEFAULT
-#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_atsui_scaled_font_backend
+#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_quartz_scaled_font_backend
#elif CAIRO_HAS_FT_FONT
More information about the cairo-commit
mailing list