summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Vukicevic <vladimir@pobox.com>2008-04-01 13:28:03 -0700
committerVladimir Vukicevic <vladimir@h-232.office.mozilla.org>2008-04-01 13:28:03 -0700
commit56800e6ea0f7153e44f0cba14c89c4239067a60e (patch)
treef25a3d8e957de415be89afbe8486a787610fb567
parent8ddae11b544c35057a96ca0bdea34b4f473ee261 (diff)
[quartz] Remove cairo-atsui-font.c
-rw-r--r--src/cairo-atsui-font.c1028
1 files changed, 0 insertions, 1028 deletions
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
deleted file mode 100644
index 42c209b66..000000000
--- 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@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 */
-};
-