1925 lines
52 KiB
Diff
1925 lines
52 KiB
Diff
--- cairo-0.4.0/configure.in 2005-03-08 19:35:06.000000000 -0600
|
|
+++ cairo/configure.in 2005-03-23 18:36:53.000000000 -0600
|
|
@@ -79,7 +79,7 @@
|
|
|
|
AC_ARG_ENABLE(quartz,
|
|
[ --disable-quartz Disable cairo's quartz backend],
|
|
- [use_quartz=$enableval], [use_quartz="no (temporarily disabled while code is out of sync)"])
|
|
+ [use_quartz=$enableval], [use_quartz=yes])
|
|
|
|
if test "x$use_quartz" = "xyes"; then
|
|
dnl There is no pkgconfig for quartz; lets do a header check
|
|
--- cairo-0.4.0/src/cairo_atsui_font.c 2005-02-22 13:28:48.000000000 -0600
|
|
+++ cairo/src/cairo_atsui_font.c 2005-04-20 13:50:01.191886799 -0500
|
|
@@ -30,778 +30,718 @@
|
|
* The Initial Developer of the Original Code is Calum Robinson
|
|
*
|
|
* Contributor(s):
|
|
- * Calum Robinson <calumr@mac.com>
|
|
+ * Calum Robinson <calumr@mac.com>
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
-
|
|
#include "cairo-atsui.h"
|
|
#include "cairoint.h"
|
|
+#include <iconv.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
|
|
|
|
+typedef struct {
|
|
+ cairo_font_t base;
|
|
|
|
+ cairo_font_scale_t scale;
|
|
+ ATSUStyle style;
|
|
+ ATSUStyle unscaled_style;
|
|
+ ATSUFontID fontID;
|
|
+} cairo_atsui_font_t;
|
|
|
|
+typedef struct cairo_ATSUI_glyph_path_callback_info_t {
|
|
+ cairo_path_t *path;
|
|
+ cairo_matrix_t scale;
|
|
+} cairo_ATSUI_glyph_path_callback_info_t;
|
|
|
|
-#pragma mark Types
|
|
|
|
|
|
+static CGAffineTransform
|
|
+CGAffineTransformMakeWithCairoFontScale(cairo_font_scale_t scale)
|
|
+{
|
|
+ return CGAffineTransformMake(scale.matrix[0][0], scale.matrix[0][1],
|
|
+ scale.matrix[1][0], scale.matrix[1][1],
|
|
+ 0, 0);
|
|
+}
|
|
|
|
|
|
+static ATSUStyle
|
|
+CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_font_scale_t * scale)
|
|
+{
|
|
+ ATSUStyle style;
|
|
+ OSStatus err;
|
|
|
|
-typedef struct {
|
|
- cairo_unscaled_font_t base;
|
|
-
|
|
- ATSUStyle style;
|
|
- ATSUFontID fontID;
|
|
-} cairo_atsui_font_t;
|
|
|
|
+ // Set the style's size
|
|
+ CGAffineTransform theTransform =
|
|
+ CGAffineTransformMakeWithCairoFontScale(*scale);
|
|
+ Fixed theSize =
|
|
+ FloatToFixed(CGSizeApplyAffineTransform
|
|
+ (CGSizeMake(1.0, 1.0), theTransform).height);
|
|
+ const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
|
|
+ const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
|
|
+ ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
|
|
|
|
-typedef struct cairo_ATSUI_glyph_path_callback_info_t {
|
|
- cairo_path_t *path;
|
|
- cairo_matrix_t scale;
|
|
-} cairo_ATSUI_glyph_path_callback_info_t;
|
|
+ err = ATSUCreateAndCopyStyle(inStyle, &style);
|
|
+
|
|
+ err = ATSUSetAttributes(style,
|
|
+ sizeof(theFontStyleTags) /
|
|
+ sizeof(ATSUAttributeTag), theFontStyleTags,
|
|
+ theFontStyleSizes, theFontStyleValues);
|
|
+
|
|
+
|
|
+ return style;
|
|
+}
|
|
+
|
|
+
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_create(const char *family,
|
|
+ cairo_font_slant_t slant,
|
|
+ cairo_font_weight_t weight,
|
|
+ cairo_font_scale_t *scale,
|
|
+ cairo_font_t **font_out)
|
|
+{
|
|
+ cairo_atsui_font_t *font = NULL;
|
|
+ ATSUStyle style;
|
|
+ ATSUFontID fontID;
|
|
+ OSStatus err;
|
|
+ Boolean isItalic, isBold;
|
|
+
|
|
+
|
|
+ err = ATSUCreateStyle(&style);
|
|
+
|
|
+
|
|
+ switch (weight) {
|
|
+ case CAIRO_FONT_WEIGHT_BOLD:
|
|
+ isBold = true;
|
|
+ break;
|
|
+ case CAIRO_FONT_WEIGHT_NORMAL:
|
|
+ default:
|
|
+ isBold = false;
|
|
+ break;
|
|
+ }
|
|
|
|
+ switch (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;
|
|
+ }
|
|
|
|
+ err = ATSUFindFontFromName(family, strlen(family),
|
|
+ kFontFamilyName,
|
|
+ kFontNoPlatformCode,
|
|
+ kFontRomanScript,
|
|
+ kFontNoLanguageCode, &fontID);
|
|
|
|
+ if (err != noErr) {
|
|
+ // couldn't get the font - remap css names and try again
|
|
|
|
+ if (!strcmp(family, "serif"))
|
|
+ family = "Times";
|
|
+ else if (!strcmp(family, "sans-serif"))
|
|
+ family = "Helvetica";
|
|
+ else if (!strcmp(family, "cursive"))
|
|
+ family = "Apple Chancery";
|
|
+ else if (!strcmp(family, "fantasy"))
|
|
+ family = "Gadget";
|
|
+ else if (!strcmp(family, "monospace"))
|
|
+ family = "Courier";
|
|
+ else // anything else - return error instead?
|
|
+ family = "Courier";
|
|
|
|
-#pragma mark Private Functions
|
|
+ err = ATSUFindFontFromName(family, strlen(family),
|
|
+ kFontFamilyName,
|
|
+ kFontNoPlatformCode,
|
|
+ kFontRomanScript,
|
|
+ kFontNoLanguageCode, &fontID);
|
|
+ }
|
|
|
|
|
|
+ ATSUAttributeTag styleTags[] =
|
|
+ { kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
|
|
+ ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
|
|
+ ByteCount styleSizes[] =
|
|
+ { sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
|
|
|
|
|
|
+ err = ATSUSetAttributes(style,
|
|
+ sizeof(styleTags) / sizeof(styleTags[0]),
|
|
+ styleTags, styleSizes, styleValues);
|
|
|
|
-static CGAffineTransform CGAffineTransformMakeWithCairoFontScale(cairo_font_scale_t scale)
|
|
+ font = malloc(sizeof(cairo_atsui_font_t));
|
|
+
|
|
+ _cairo_font_init(&font->base, scale, &cairo_atsui_font_backend);
|
|
+
|
|
+ font->style = CreateSizedCopyOfStyle(style, scale);
|
|
+
|
|
+
|
|
+ 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);
|
|
+
|
|
+ font->unscaled_style = style;
|
|
+
|
|
+ font->fontID = fontID;
|
|
+ font->scale = *scale;
|
|
+
|
|
+ *font_out = (cairo_font_t *)font;
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+_cairo_atsui_font_destroy_font(void *abstract_font)
|
|
{
|
|
- return CGAffineTransformMake( scale.matrix[0][0], scale.matrix[0][1],
|
|
- scale.matrix[1][0], scale.matrix[1][1],
|
|
- 0, 0);
|
|
-}
|
|
-
|
|
-
|
|
-static ATSUStyle CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_font_scale_t *scale)
|
|
-{
|
|
- ATSUStyle style;
|
|
- OSStatus err;
|
|
-
|
|
-
|
|
- // Set the style's size
|
|
- CGAffineTransform theTransform = CGAffineTransformMakeWithCairoFontScale(*scale);
|
|
- Fixed theSize = FloatToFixed(CGSizeApplyAffineTransform(CGSizeMake(1.0, 1.0), theTransform).height);
|
|
- const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
|
|
- const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
|
|
- ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
|
|
-
|
|
- err = ATSUCreateAndCopyStyle(inStyle, &style);
|
|
-
|
|
- err = ATSUSetAttributes( style,
|
|
- sizeof(theFontStyleTags) / sizeof(ATSUAttributeTag),
|
|
- theFontStyleTags, theFontStyleSizes, theFontStyleValues);
|
|
-
|
|
-
|
|
- return style;
|
|
+ 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);
|
|
+
|
|
+ free(font);
|
|
}
|
|
|
|
|
|
+static void
|
|
+_cairo_atsui_font_destroy_unscaled_font(void *abstract_font)
|
|
+{
|
|
+}
|
|
|
|
|
|
+static void
|
|
+_cairo_atsui_font_get_glyph_cache_key(void *abstract_font,
|
|
+ cairo_glyph_cache_key_t *key)
|
|
+{
|
|
+}
|
|
|
|
-#pragma mark Public Functions
|
|
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_text_to_glyphs(void *abstract_font,
|
|
+ const unsigned char *utf8,
|
|
+ cairo_glyph_t ** glyphs, int *nglyphs)
|
|
+{
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ size_t i;
|
|
+ OSStatus err;
|
|
+ ATSUTextLayout textLayout;
|
|
+ ATSLayoutRecord *layoutRecords;
|
|
+ ItemCount glyphCount, charCount;
|
|
+ UniChar *theText;
|
|
+ ATSUStyle style;
|
|
+
|
|
+ err = ATSUCreateTextLayout(&textLayout);
|
|
|
|
+#if 1
|
|
+ charCount = strlen(utf8);
|
|
|
|
+ // Set the text in the text layout object, so we can measure it
|
|
+ theText = (UniChar *) malloc(charCount * sizeof(UniChar));
|
|
|
|
+ for (i = 0; i < charCount; i++) {
|
|
+ theText[i] = utf8[i];
|
|
+ }
|
|
+#endif
|
|
|
|
-static cairo_unscaled_font_t *
|
|
-_cairo_atsui_font_create( const char *family,
|
|
- cairo_font_slant_t slant,
|
|
- cairo_font_weight_t weight)
|
|
-{
|
|
- cairo_atsui_font_t *font = NULL;
|
|
- ATSUStyle style;
|
|
- ATSUFontID fontID;
|
|
- OSStatus err;
|
|
- Boolean isItalic, isBold;
|
|
-
|
|
-
|
|
- err = ATSUCreateStyle(&style);
|
|
-
|
|
-
|
|
- switch (weight)
|
|
- {
|
|
- case CAIRO_FONT_WEIGHT_BOLD:
|
|
- isBold = true;
|
|
- break;
|
|
- case CAIRO_FONT_WEIGHT_NORMAL:
|
|
- default:
|
|
- isBold = false;
|
|
- break;
|
|
- }
|
|
-
|
|
- switch (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;
|
|
- }
|
|
-
|
|
- err = ATSUFindFontFromName( family, strlen(family),
|
|
- kFontFamilyName,
|
|
- kFontNoPlatformCode,
|
|
- kFontRomanScript,
|
|
- kFontNoLanguageCode,
|
|
- &fontID);
|
|
-
|
|
-
|
|
- ATSUAttributeTag styleTags[] = {kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag};
|
|
- ATSUAttributeValuePtr styleValues[] = {&isItalic, &isBold, &fontID};
|
|
- ByteCount styleSizes[] = {sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID)};
|
|
-
|
|
-
|
|
- err = ATSUSetAttributes( style,
|
|
- sizeof(styleTags) / sizeof(styleTags[0]),
|
|
- styleTags,
|
|
- styleSizes,
|
|
- styleValues);
|
|
-
|
|
-
|
|
-
|
|
- font = malloc(sizeof(cairo_atsui_font_t));
|
|
-
|
|
- if (_cairo_unscaled_font_init(&font->base, &cairo_atsui_font_backend) == CAIRO_STATUS_SUCCESS)
|
|
- {
|
|
- font->style = style;
|
|
- font->fontID = fontID;
|
|
-
|
|
-
|
|
- return &font->base;
|
|
- }
|
|
-
|
|
-
|
|
- free(font);
|
|
-
|
|
- return NULL;
|
|
+#if 0
|
|
+ // Set the text in the text layout object, so we can measure it
|
|
+ charCount = strlen(utf8);
|
|
+ theText = (UniChar *) malloc(charCount * sizeof(UniChar));
|
|
+
|
|
+ size_t inBytes = charCount, outBytes = charCount;
|
|
+ iconv_t converter = iconv_open("UTF-8", "UTF-16");
|
|
+ charCount = iconv(converter, utf8, &inBytes, theText, &outBytes);
|
|
+#endif
|
|
+
|
|
+ err = ATSUSetTextPointerLocation(textLayout,
|
|
+ theText, 0, charCount, charCount);
|
|
+
|
|
+
|
|
+ // Set the style for all of the text
|
|
+ err = ATSUSetRunStyle(textLayout,
|
|
+ font->unscaled_style, kATSUFromTextBeginning, kATSUToTextEnd);
|
|
+
|
|
+ // Get the glyphs from the text layout object
|
|
+ err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout,
|
|
+ 0,
|
|
+ kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
|
+ (void *)
|
|
+ &layoutRecords,
|
|
+ &glyphCount);
|
|
+
|
|
+ *nglyphs = glyphCount - 1;
|
|
+
|
|
+
|
|
+ *glyphs =
|
|
+ (cairo_glyph_t *) malloc(*nglyphs * (sizeof(cairo_glyph_t)));
|
|
+ if (*glyphs == NULL) {
|
|
+ return CAIRO_STATUS_NO_MEMORY;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < *nglyphs; i++) {
|
|
+ (*glyphs)[i].index = layoutRecords[i].glyphID;
|
|
+ (*glyphs)[i].x = FixedToFloat(layoutRecords[i].realPos);
|
|
+ (*glyphs)[i].y = 0;
|
|
+ }
|
|
+
|
|
+
|
|
+ free(theText);
|
|
+
|
|
+ ATSUDirectReleaseLayoutDataArrayPtr(NULL,
|
|
+ kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
|
+ (void *) &layoutRecords);
|
|
+
|
|
+ ATSUDisposeTextLayout(textLayout);
|
|
+
|
|
+ ATSUDisposeStyle(style);
|
|
+
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
-static void
|
|
-_cairo_atsui_font_destroy(void *abstract_font)
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_font_extents(void *abstract_font,
|
|
+ cairo_font_extents_t * extents)
|
|
+{
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ ATSFontRef atsFont;
|
|
+ ATSFontMetrics metrics;
|
|
+ OSStatus err;
|
|
+
|
|
+ // TODO - test this
|
|
+
|
|
+ atsFont = FMGetATSFontRefFromFont(font->fontID);
|
|
+
|
|
+ if (atsFont) {
|
|
+ err =
|
|
+ ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault,
|
|
+ &metrics);
|
|
+
|
|
+ if (err == noErr) {
|
|
+ extents->ascent = metrics.ascent;
|
|
+ extents->descent = metrics.descent;
|
|
+ extents->height = metrics.capHeight;
|
|
+ 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;
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ return CAIRO_STATUS_NULL_POINTER;
|
|
+}
|
|
+
|
|
+
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_glyph_extents(void *abstract_font,
|
|
+ cairo_glyph_t * glyphs,
|
|
+ int num_glyphs,
|
|
+ cairo_text_extents_t * extents)
|
|
{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
-
|
|
-
|
|
- if (font == NULL)
|
|
- return;
|
|
-
|
|
- if (font->style)
|
|
- ATSUDisposeStyle(font->style);
|
|
-
|
|
- free(font);
|
|
-}
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_text_to_glyphs( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- const unsigned char *utf8,
|
|
- cairo_glyph_t **glyphs,
|
|
- int *nglyphs)
|
|
-{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- size_t i;
|
|
- OSStatus err;
|
|
- ATSUTextLayout textLayout;
|
|
- ATSLayoutRecord *layoutRecords;
|
|
- ItemCount glyphCount, charCount;
|
|
- UniChar *theText;
|
|
- ATSUStyle style;
|
|
-
|
|
-
|
|
- charCount = strlen(utf8);
|
|
-
|
|
-
|
|
- err = ATSUCreateTextLayout(&textLayout);
|
|
-
|
|
-
|
|
- // Set the text in the text layout object, so we can measure it
|
|
- theText = (UniChar *)malloc(charCount * sizeof(UniChar));
|
|
-
|
|
- for (i = 0; i < charCount; i++)
|
|
- {
|
|
- theText[i] = utf8[i];
|
|
- }
|
|
-
|
|
- err = ATSUSetTextPointerLocation( textLayout,
|
|
- theText,
|
|
- 0,
|
|
- charCount,
|
|
- charCount);
|
|
-
|
|
-
|
|
- style = CreateSizedCopyOfStyle(font->style, sc);
|
|
-
|
|
-
|
|
- // Set the style for all of the text
|
|
- err = ATSUSetRunStyle( textLayout,
|
|
- style,
|
|
- kATSUFromTextBeginning,
|
|
- kATSUToTextEnd);
|
|
-
|
|
-
|
|
-
|
|
- // Get the glyphs from the text layout object
|
|
- err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout( textLayout,
|
|
- 0,
|
|
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
|
- (void *)&layoutRecords,
|
|
- &glyphCount);
|
|
-
|
|
- *nglyphs = glyphCount;
|
|
-
|
|
-
|
|
- *glyphs = (cairo_glyph_t *)malloc(glyphCount * (sizeof(cairo_glyph_t)));
|
|
- if (*glyphs == NULL)
|
|
- {
|
|
- return CAIRO_STATUS_NO_MEMORY;
|
|
- }
|
|
-
|
|
- for (i = 0; i < glyphCount; i++)
|
|
- {
|
|
- (*glyphs)[i].index = layoutRecords[i].glyphID;
|
|
- (*glyphs)[i].x = FixedToFloat(layoutRecords[i].realPos);
|
|
- (*glyphs)[i].y = 0;
|
|
- }
|
|
-
|
|
-
|
|
- free(theText);
|
|
-
|
|
- ATSUDirectReleaseLayoutDataArrayPtr( NULL,
|
|
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
|
- (void *)&layoutRecords);
|
|
-
|
|
- ATSUDisposeTextLayout(textLayout);
|
|
-
|
|
- ATSUDisposeStyle(style);
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
-}
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_font_extents( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- cairo_font_extents_t *extents)
|
|
-{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- ATSFontRef atsFont;
|
|
- ATSFontMetrics metrics;
|
|
- OSStatus err;
|
|
-
|
|
-
|
|
- // TODO - test this
|
|
-
|
|
- atsFont = FMGetATSFontRefFromFont(font->fontID);
|
|
-
|
|
- if (atsFont)
|
|
- {
|
|
- err = ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault, &metrics);
|
|
-
|
|
- if (err == noErr)
|
|
- {
|
|
- extents->ascent = metrics.ascent;
|
|
- extents->descent = metrics.descent;
|
|
- extents->height = metrics.capHeight;
|
|
- 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;
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
- }
|
|
- }
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_NULL_POINTER;
|
|
-}
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_glyph_extents( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- cairo_glyph_t *glyphs,
|
|
- int num_glyphs,
|
|
- cairo_text_extents_t *extents)
|
|
-{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- cairo_point_double_t origin;
|
|
- cairo_point_double_t glyph_min, glyph_max;
|
|
- cairo_point_double_t total_min, total_max;
|
|
- OSStatus err;
|
|
- ATSUStyle style;
|
|
- int i;
|
|
-
|
|
-
|
|
- if (num_glyphs == 0)
|
|
- {
|
|
- extents->x_bearing = 0.0;
|
|
- extents->y_bearing = 0.0;
|
|
- extents->width = 0.0;
|
|
- extents->height = 0.0;
|
|
- extents->x_advance = 0.0;
|
|
- extents->y_advance = 0.0;
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
- }
|
|
-
|
|
- origin.x = glyphs[0].x;
|
|
- origin.y = glyphs[0].y;
|
|
-
|
|
-
|
|
- style = CreateSizedCopyOfStyle(font->style, sc);
|
|
-
|
|
-
|
|
- for (i = 0; i < num_glyphs; i++)
|
|
- {
|
|
- GlyphID theGlyph = glyphs[i].index;
|
|
- double minX, maxX, ascent, descent;
|
|
- ATSGlyphIdealMetrics metricsH, metricsV;
|
|
-
|
|
-
|
|
- err = ATSUGlyphGetIdealMetrics( style,
|
|
- 1,
|
|
- &theGlyph,
|
|
- 0,
|
|
- &metricsH);
|
|
-
|
|
-
|
|
- ATSUVerticalCharacterType verticalType = kATSUStronglyVertical;
|
|
- ATSUAttributeTag theTag = kATSUVerticalCharacterTag;
|
|
- ByteCount theSize = sizeof(ATSUVerticalCharacterType);
|
|
-
|
|
- err = ATSUSetAttributes(style, 1, &theTag, &theSize, (ATSUAttributeValuePtr)&verticalType);
|
|
-
|
|
- err = ATSUGlyphGetIdealMetrics( style,
|
|
- 1,
|
|
- &theGlyph,
|
|
- 0,
|
|
- &metricsV);
|
|
-
|
|
- minX = metricsH.otherSideBearing.x;
|
|
- maxX = metricsH.advance.x;
|
|
-
|
|
- ascent = metricsV.advance.x;
|
|
- descent = metricsV.otherSideBearing.x;
|
|
-
|
|
- glyph_min.x = glyphs[i].x + minX;
|
|
- glyph_min.y = glyphs[i].y + descent;
|
|
- glyph_max.x = glyphs[i].x + maxX;
|
|
- glyph_max.y = glyphs[i].y + ascent;
|
|
-
|
|
- if (i==0)
|
|
- {
|
|
- total_min = glyph_min;
|
|
- total_max = glyph_max;
|
|
- }
|
|
- else
|
|
- {
|
|
- if (glyph_min.x < total_min.x)
|
|
- total_min.x = glyph_min.x;
|
|
- if (glyph_min.y < total_min.y)
|
|
- total_min.y = glyph_min.y;
|
|
-
|
|
- if (glyph_max.x > total_max.x)
|
|
- total_max.x = glyph_max.x;
|
|
- if (glyph_max.y > total_max.y)
|
|
- total_max.y = glyph_max.y;
|
|
- }
|
|
- }
|
|
-
|
|
-
|
|
- extents->x_bearing = total_min.x - origin.x;
|
|
- extents->y_bearing = total_min.y - origin.y;
|
|
- extents->width = total_max.x - total_min.x;
|
|
- extents->height = total_max.y - total_min.y;
|
|
- extents->x_advance = glyphs[i-1].x - origin.x;
|
|
- extents->y_advance = glyphs[i-1].y - origin.y;
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
-}
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_glyph_bbox( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- const cairo_glyph_t *glyphs,
|
|
- int num_glyphs,
|
|
- cairo_box_t *bbox)
|
|
-{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- cairo_fixed_t x1, y1, x2, y2;
|
|
- int i;
|
|
- OSStatus err;
|
|
- ATSUStyle style;
|
|
-
|
|
-
|
|
- bbox->p1.x = bbox->p1.y = CAIRO_MAXSHORT << 16;
|
|
- bbox->p2.x = bbox->p2.y = CAIRO_MINSHORT << 16;
|
|
-
|
|
-
|
|
- style = CreateSizedCopyOfStyle(font->style, sc);
|
|
-
|
|
-
|
|
- for (i = 0; i < num_glyphs; i++)
|
|
- {
|
|
- GlyphID theGlyph = glyphs[i].index;
|
|
- ATSGlyphIdealMetrics metrics;
|
|
-
|
|
-
|
|
- err = ATSUGlyphGetIdealMetrics( style,
|
|
- 1,
|
|
- &theGlyph,
|
|
- 0,
|
|
- &metrics);
|
|
-
|
|
- x1 = _cairo_fixed_from_double(glyphs[i].x);
|
|
- y1 = _cairo_fixed_from_double(glyphs[i].y);
|
|
- x2 = x1 + _cairo_fixed_from_double(metrics.advance.x);
|
|
- y2 = y1 + _cairo_fixed_from_double(metrics.advance.y);
|
|
-
|
|
- if (x1 < bbox->p1.x)
|
|
- bbox->p1.x = x1;
|
|
-
|
|
- if (y1 < bbox->p1.y)
|
|
- bbox->p1.y = y1;
|
|
-
|
|
- if (x2 > bbox->p2.x)
|
|
- bbox->p2.x = x2;
|
|
-
|
|
- if (y2 > bbox->p2.y)
|
|
- bbox->p2.y = y2;
|
|
- }
|
|
-
|
|
-
|
|
- ATSUDisposeStyle(style);
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
-}
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_show_glyphs( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- cairo_operator_t operator,
|
|
- cairo_surface_t *source,
|
|
- cairo_surface_t *surface,
|
|
- int source_x,
|
|
- int source_y,
|
|
- const cairo_glyph_t *glyphs,
|
|
- int num_glyphs)
|
|
-{
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- CGContextRef myBitmapContext;
|
|
- CGColorSpaceRef colorSpace;
|
|
- cairo_image_surface_t *destImageSurface;
|
|
- int i;
|
|
-
|
|
-
|
|
- destImageSurface = _cairo_surface_get_image(surface);
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ OSStatus err;
|
|
+
|
|
+ assert(num_glyphs == 1);
|
|
+
|
|
+ GlyphID theGlyph = glyphs[0].index;
|
|
+
|
|
+ ATSGlyphIdealMetrics metricsH, metricsV;
|
|
+ ATSUStyle style;
|
|
+
|
|
+ ATSUCreateAndCopyStyle(font->unscaled_style, &style);
|
|
+
|
|
+ err = ATSUGlyphGetIdealMetrics(style,
|
|
+ 1, &theGlyph, 0, &metricsH);
|
|
+
|
|
+ ATSUVerticalCharacterType verticalType = kATSUStronglyVertical;
|
|
+ const ATSUAttributeTag theTag[] = { kATSUVerticalCharacterTag };
|
|
+ const ByteCount theSizes[] = { sizeof(verticalType) };
|
|
+ ATSUAttributeValuePtr theValues[] = { &verticalType };
|
|
|
|
-
|
|
- // Create a CGBitmapContext for the dest surface for drawing into
|
|
+ err = ATSUSetAttributes(style, 1, theTag, theSizes, theValues);
|
|
+
|
|
+ err = ATSUGlyphGetIdealMetrics(style,
|
|
+ 1, &theGlyph, 0, &metricsV);
|
|
+
|
|
+ extents->x_bearing = metricsH.sideBearing.x;
|
|
+ extents->y_bearing = metricsV.advance.y;
|
|
+ extents->width =
|
|
+ metricsH.advance.x - metricsH.sideBearing.x - metricsH.otherSideBearing.x;
|
|
+ extents->height =
|
|
+ -metricsV.advance.y - metricsV.sideBearing.y - metricsV.otherSideBearing.y;
|
|
+ extents->x_advance = metricsH.advance.x;
|
|
+ extents->y_advance = 0;
|
|
+
|
|
+ ATSUDisposeStyle(style);
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_glyph_bbox(void *abstract_font,
|
|
+ const cairo_glyph_t *glyphs,
|
|
+ int num_glyphs, cairo_box_t *bbox)
|
|
+{
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ cairo_fixed_t x1, y1, x2, y2;
|
|
+ int i;
|
|
+ OSStatus err;
|
|
+
|
|
+ bbox->p1.x = bbox->p1.y = CAIRO_MAXSHORT << 16;
|
|
+ bbox->p2.x = bbox->p2.y = CAIRO_MINSHORT << 16;
|
|
+
|
|
+
|
|
+ for (i = 0; i < num_glyphs; i++) {
|
|
+ GlyphID theGlyph = glyphs[i].index;
|
|
+
|
|
+ ATSGlyphScreenMetrics metrics;
|
|
+ ATSUGlyphGetScreenMetrics(font->style,
|
|
+ 1, &theGlyph, 0, true, true, &metrics);
|
|
+
|
|
+ x1 = _cairo_fixed_from_double(glyphs[i].x + metrics.topLeft.x);
|
|
+ y1 = _cairo_fixed_from_double(glyphs[i].y - metrics.topLeft.y);
|
|
+ x2 = x1 + _cairo_fixed_from_double(metrics.height);
|
|
+ y2 = y1 + _cairo_fixed_from_double(metrics.width);
|
|
+
|
|
+ if (x1 < bbox->p1.x)
|
|
+ bbox->p1.x = x1;
|
|
+
|
|
+ if (y1 < bbox->p1.y)
|
|
+ bbox->p1.y = y1;
|
|
+
|
|
+ if (x2 > bbox->p2.x)
|
|
+ bbox->p2.x = x2;
|
|
+
|
|
+ if (y2 > bbox->p2.y)
|
|
+ bbox->p2.y = y2;
|
|
+ }
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_show_glyphs(void *abstract_font,
|
|
+ cairo_operator_t operator,
|
|
+ cairo_pattern_t *pattern,
|
|
+ cairo_surface_t *generic_surface,
|
|
+ int source_x,
|
|
+ int source_y,
|
|
+ int dest_x,
|
|
+ int dest_y,
|
|
+ unsigned int width,
|
|
+ unsigned int height,
|
|
+ const cairo_glyph_t *glyphs,
|
|
+ int num_glyphs)
|
|
+{
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ CGContextRef myBitmapContext;
|
|
+ CGColorSpaceRef colorSpace;
|
|
+ cairo_image_surface_t *destImageSurface;
|
|
+ int i;
|
|
+
|
|
+ cairo_rectangle_t rect = {dest_x, dest_y, width, height};
|
|
+ _cairo_surface_acquire_dest_image(generic_surface,
|
|
+ &rect,
|
|
+ &destImageSurface,
|
|
+ &rect,
|
|
+ NULL);
|
|
+
|
|
+ // Create a CGBitmapContext for the dest surface for drawing into
|
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
-
|
|
- myBitmapContext = CGBitmapContextCreate( destImageSurface->data,
|
|
- destImageSurface->width,
|
|
- destImageSurface->height,
|
|
- destImageSurface->depth / 4,
|
|
- destImageSurface->stride,
|
|
- colorSpace,
|
|
- kCGImageAlphaPremultipliedFirst);
|
|
-
|
|
-
|
|
- ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID);
|
|
- CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont);
|
|
-
|
|
- CGContextSetFont(myBitmapContext, cgFont);
|
|
-
|
|
-
|
|
- CGAffineTransform textTransform = CGAffineTransformMakeWithCairoFontScale(*sc);
|
|
- CGSize textSize = CGSizeMake(1.0, 1.0);
|
|
-
|
|
- textSize = CGSizeApplyAffineTransform(textSize, textTransform);
|
|
-
|
|
- CGContextSetFontSize(myBitmapContext, textSize.width);
|
|
-
|
|
-
|
|
- // TODO - bold and italic text
|
|
- //
|
|
- // We could draw the text using ATSUI and get bold, italics
|
|
- // etc. for free, but ATSUI does a lot of text layout work
|
|
- // that we don't really need...
|
|
-
|
|
-
|
|
- for (i = 0; i < num_glyphs; i++)
|
|
- {
|
|
- CGGlyph theGlyph = glyphs[i].index;
|
|
-
|
|
- CGContextShowGlyphsAtPoint(myBitmapContext, source_x + glyphs[i].x, destImageSurface->height - (source_y + glyphs[i].y), &theGlyph, 1);
|
|
- }
|
|
-
|
|
-
|
|
- CGColorSpaceRelease(colorSpace);
|
|
- CGContextRelease(myBitmapContext);
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
+
|
|
+ myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
|
|
+ destImageSurface->width,
|
|
+ destImageSurface->height,
|
|
+ destImageSurface->depth / 4,
|
|
+ destImageSurface->stride,
|
|
+ colorSpace,
|
|
+ kCGImageAlphaPremultipliedFirst);
|
|
+ CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height);
|
|
+ CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f);
|
|
+
|
|
+ ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID);
|
|
+ CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont);
|
|
+
|
|
+ CGContextSetFont(myBitmapContext, cgFont);
|
|
+
|
|
+ CGAffineTransform textTransform =
|
|
+ CGAffineTransformMakeWithCairoFontScale(font->scale);
|
|
+
|
|
+ textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f);
|
|
+
|
|
+ CGContextSetFontSize(myBitmapContext, 1.0);
|
|
+ CGContextSetTextMatrix(myBitmapContext, textTransform);
|
|
+
|
|
+ if (pattern->type == CAIRO_PATTERN_SOLID &&
|
|
+ _cairo_pattern_is_opaque(pattern)) {
|
|
+ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
|
|
+ CGContextSetRGBFillColor(myBitmapContext,
|
|
+ solid->red, solid->green, solid->blue, 1.0f);
|
|
+ } else
|
|
+ CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
+
|
|
+ // TODO - bold and italic text
|
|
+ //
|
|
+ // We could draw the text using ATSUI and get bold, italics
|
|
+ // etc. for free, but ATSUI does a lot of text layout work
|
|
+ // that we don't really need...
|
|
+
|
|
+
|
|
+ for (i = 0; i < num_glyphs; i++) {
|
|
+ CGGlyph theGlyph = glyphs[i].index;
|
|
+
|
|
+ CGContextShowGlyphsAtPoint(myBitmapContext,
|
|
+ glyphs[i].x,
|
|
+ glyphs[i].y,
|
|
+ &theGlyph, 1);
|
|
+ }
|
|
+
|
|
+
|
|
+ CGColorSpaceRelease(colorSpace);
|
|
+ CGContextRelease(myBitmapContext);
|
|
+
|
|
+ _cairo_surface_release_dest_image(generic_surface,
|
|
+ &rect,
|
|
+ destImageSurface,
|
|
+ &rect,
|
|
+ NULL);
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
-#pragma mark -
|
|
-
|
|
-
|
|
-static OSStatus MyATSCubicMoveToCallback(const Float32Point *pt, void *callBackDataPtr)
|
|
-{
|
|
- cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
- double scaledPt[2];
|
|
- cairo_point_t point;
|
|
-
|
|
-
|
|
- scaledPt[0] = pt->x;
|
|
- scaledPt[1] = pt->y;
|
|
-
|
|
- cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
+static OSStatus MyATSCubicMoveToCallback(const Float32Point * pt,
|
|
+ void *callBackDataPtr)
|
|
+{
|
|
+ cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
+ double scaledPt[2];
|
|
+ cairo_point_t point;
|
|
+
|
|
+
|
|
+ scaledPt[0] = pt->x;
|
|
+ scaledPt[1] = pt->y;
|
|
+
|
|
+ cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
|
|
point.x = _cairo_fixed_from_double(scaledPt[0]);
|
|
point.y = _cairo_fixed_from_double(scaledPt[1]);
|
|
|
|
_cairo_path_move_to(info->path, &point);
|
|
-
|
|
-
|
|
+
|
|
+
|
|
return noErr;
|
|
}
|
|
|
|
|
|
-static OSStatus MyATSCubicLineToCallback(const Float32Point *pt, void *callBackDataPtr)
|
|
+static OSStatus MyATSCubicLineToCallback(const Float32Point * pt,
|
|
+ void *callBackDataPtr)
|
|
{
|
|
- cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
- cairo_point_t point;
|
|
- double scaledPt[2];
|
|
-
|
|
-
|
|
- scaledPt[0] = pt->x;
|
|
- scaledPt[1] = pt->y;
|
|
-
|
|
- cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
-
|
|
+ cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
+ cairo_point_t point;
|
|
+ double scaledPt[2];
|
|
+
|
|
+
|
|
+ scaledPt[0] = pt->x;
|
|
+ scaledPt[1] = pt->y;
|
|
+
|
|
+ cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
+
|
|
point.x = _cairo_fixed_from_double(scaledPt[0]);
|
|
point.y = _cairo_fixed_from_double(scaledPt[1]);
|
|
|
|
_cairo_path_line_to(info->path, &point);
|
|
-
|
|
-
|
|
- return noErr;
|
|
+
|
|
+
|
|
+ return noErr;
|
|
}
|
|
|
|
|
|
-static OSStatus MyATSCubicCurveToCallback( const Float32Point *pt1,
|
|
- const Float32Point *pt2,
|
|
- const Float32Point *pt3,
|
|
- void *callBackDataPtr)
|
|
+static OSStatus MyATSCubicCurveToCallback(const Float32Point * pt1,
|
|
+ const Float32Point * pt2,
|
|
+ const Float32Point * pt3,
|
|
+ void *callBackDataPtr)
|
|
{
|
|
- cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
+ cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
cairo_point_t p0, p1, p2;
|
|
- double scaledPt[2];
|
|
-
|
|
-
|
|
- scaledPt[0] = pt1->x;
|
|
- scaledPt[1] = pt1->y;
|
|
-
|
|
- cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
+ double scaledPt[2];
|
|
+
|
|
+
|
|
+ scaledPt[0] = pt1->x;
|
|
+ scaledPt[1] = pt1->y;
|
|
+
|
|
+ cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
|
|
p0.x = _cairo_fixed_from_double(scaledPt[0]);
|
|
p0.y = _cairo_fixed_from_double(scaledPt[1]);
|
|
-
|
|
+
|
|
|
|
scaledPt[0] = pt2->x;
|
|
- scaledPt[1] = pt2->y;
|
|
-
|
|
- cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
+ scaledPt[1] = pt2->y;
|
|
+
|
|
+ cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
|
|
p1.x = _cairo_fixed_from_double(scaledPt[0]);
|
|
p1.y = _cairo_fixed_from_double(scaledPt[1]);
|
|
-
|
|
+
|
|
|
|
scaledPt[0] = pt3->x;
|
|
- scaledPt[1] = pt3->y;
|
|
-
|
|
- cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
+ scaledPt[1] = pt3->y;
|
|
+
|
|
+ cairo_matrix_transform_point(&info->scale, &scaledPt[0], &scaledPt[1]);
|
|
|
|
p2.x = _cairo_fixed_from_double(scaledPt[0]);
|
|
p2.y = _cairo_fixed_from_double(scaledPt[1]);
|
|
-
|
|
+
|
|
|
|
_cairo_path_curve_to(info->path, &p0, &p1, &p2);
|
|
-
|
|
-
|
|
- return noErr;
|
|
+
|
|
+
|
|
+ return noErr;
|
|
}
|
|
|
|
|
|
-static OSStatus MyCubicClosePathProc(void * callBackDataPtr)
|
|
+static OSStatus MyCubicClosePathProc(void *callBackDataPtr)
|
|
{
|
|
- cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
-
|
|
-
|
|
+ cairo_ATSUI_glyph_path_callback_info_t *info = callBackDataPtr;
|
|
+
|
|
+
|
|
_cairo_path_close_path(info->path);
|
|
-
|
|
-
|
|
- return noErr;
|
|
-}
|
|
|
|
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_glyph_path( void *abstract_font,
|
|
- cairo_font_scale_t *sc,
|
|
- cairo_glyph_t *glyphs,
|
|
- int num_glyphs,
|
|
- cairo_path_t *path)
|
|
-{
|
|
- int i;
|
|
- cairo_atsui_font_t *font = abstract_font;
|
|
- OSStatus err;
|
|
- cairo_ATSUI_glyph_path_callback_info_t info;
|
|
- ATSUStyle style;
|
|
-
|
|
-
|
|
- static ATSCubicMoveToUPP moveProc = NULL;
|
|
- static ATSCubicLineToUPP lineProc = NULL;
|
|
- static ATSCubicCurveToUPP curveProc = NULL;
|
|
- static ATSCubicClosePathUPP closePathProc = NULL;
|
|
-
|
|
-
|
|
- if (moveProc == NULL)
|
|
- {
|
|
- moveProc = NewATSCubicMoveToUPP(MyATSCubicMoveToCallback);
|
|
- lineProc = NewATSCubicLineToUPP(MyATSCubicLineToCallback);
|
|
- curveProc = NewATSCubicCurveToUPP(MyATSCubicCurveToCallback);
|
|
- closePathProc = NewATSCubicClosePathUPP(MyCubicClosePathProc);
|
|
- }
|
|
-
|
|
-
|
|
- info.path = path;
|
|
-
|
|
-
|
|
- style = CreateSizedCopyOfStyle(font->style, sc);
|
|
-
|
|
-
|
|
- for (i = 0; i < num_glyphs; i++)
|
|
- {
|
|
- GlyphID theGlyph = glyphs[i].index;
|
|
-
|
|
-
|
|
- cairo_matrix_set_affine( &info.scale,
|
|
- 1.0, 0.0,
|
|
- 0.0, 1.0,
|
|
- glyphs[i].x, glyphs[i].y);
|
|
-
|
|
-
|
|
- err = ATSUGlyphGetCubicPaths( style,
|
|
- theGlyph,
|
|
- moveProc,
|
|
- lineProc,
|
|
- curveProc,
|
|
- closePathProc,
|
|
- (void *)&info,
|
|
- &err);
|
|
- }
|
|
-
|
|
-
|
|
- err = ATSUDisposeStyle(style);
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
-}
|
|
-
|
|
-
|
|
-#pragma mark -
|
|
-
|
|
-
|
|
-static cairo_status_t
|
|
-_cairo_atsui_font_create_glyph(cairo_image_glyph_cache_entry_t *val)
|
|
-{
|
|
- // TODO
|
|
- printf("_cairo_atsui_font_create_glyph is unimplemented\n");
|
|
-
|
|
- // I'm not sure if we need this, given that the ATSUI backend does no caching(?)
|
|
-
|
|
-
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
-}
|
|
-
|
|
-
|
|
-cairo_font_t *
|
|
-cairo_atsui_font_create(ATSUStyle style)
|
|
-{
|
|
- cairo_font_scale_t scale;
|
|
- cairo_font_t *scaled;
|
|
- cairo_atsui_font_t *f = NULL;
|
|
-
|
|
-
|
|
- scaled = malloc(sizeof(cairo_font_t));
|
|
- if (scaled == NULL)
|
|
- return NULL;
|
|
-
|
|
-
|
|
- f = malloc(sizeof(cairo_atsui_font_t));
|
|
- if (f)
|
|
- {
|
|
- if (_cairo_unscaled_font_init(&f->base, &cairo_atsui_font_backend) == CAIRO_STATUS_SUCCESS)
|
|
- {
|
|
- f->style = style;
|
|
-
|
|
- _cairo_font_init(scaled, &scale, &f->base);
|
|
-
|
|
- return scaled;
|
|
- }
|
|
- }
|
|
-
|
|
-
|
|
- free(scaled);
|
|
-
|
|
-
|
|
- return NULL;
|
|
+ return noErr;
|
|
}
|
|
|
|
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_glyph_path(void *abstract_font,
|
|
+ cairo_glyph_t *glyphs, int num_glyphs,
|
|
+ cairo_path_t *path)
|
|
+{
|
|
+ int i;
|
|
+ cairo_atsui_font_t *font = abstract_font;
|
|
+ OSStatus err;
|
|
+ cairo_ATSUI_glyph_path_callback_info_t info;
|
|
+
|
|
+
|
|
+ static ATSCubicMoveToUPP moveProc = NULL;
|
|
+ static ATSCubicLineToUPP lineProc = NULL;
|
|
+ static ATSCubicCurveToUPP curveProc = NULL;
|
|
+ static ATSCubicClosePathUPP closePathProc = NULL;
|
|
+
|
|
+
|
|
+ if (moveProc == NULL) {
|
|
+ moveProc = NewATSCubicMoveToUPP(MyATSCubicMoveToCallback);
|
|
+ lineProc = NewATSCubicLineToUPP(MyATSCubicLineToCallback);
|
|
+ curveProc = NewATSCubicCurveToUPP(MyATSCubicCurveToCallback);
|
|
+ closePathProc = NewATSCubicClosePathUPP(MyCubicClosePathProc);
|
|
+ }
|
|
|
|
|
|
+ info.path = path;
|
|
|
|
-#pragma mark Backend
|
|
|
|
+ for (i = 0; i < num_glyphs; i++) {
|
|
+ GlyphID theGlyph = glyphs[i].index;
|
|
|
|
|
|
+ cairo_matrix_set_affine(&info.scale,
|
|
+ 1.0, 0.0,
|
|
+ 0.0, 1.0, glyphs[i].x, glyphs[i].y);
|
|
+
|
|
+
|
|
+ err = ATSUGlyphGetCubicPaths(font->style,
|
|
+ theGlyph,
|
|
+ moveProc,
|
|
+ lineProc,
|
|
+ curveProc,
|
|
+ closePathProc, (void *) &info, &err);
|
|
+ }
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
+static cairo_status_t
|
|
+_cairo_atsui_font_create_glyph(cairo_image_glyph_cache_entry_t * val)
|
|
+{
|
|
+ return CAIRO_STATUS_NO_MEMORY;
|
|
+}
|
|
|
|
|
|
const cairo_font_backend_t cairo_atsui_font_backend = {
|
|
- _cairo_atsui_font_create,
|
|
- _cairo_atsui_font_destroy,
|
|
- _cairo_atsui_font_font_extents,
|
|
- _cairo_atsui_font_text_to_glyphs,
|
|
- _cairo_atsui_font_glyph_extents,
|
|
- _cairo_atsui_font_glyph_bbox,
|
|
- _cairo_atsui_font_show_glyphs,
|
|
- _cairo_atsui_font_glyph_path,
|
|
- _cairo_atsui_font_create_glyph
|
|
+ _cairo_atsui_font_create,
|
|
+ _cairo_atsui_font_destroy_font,
|
|
+ _cairo_atsui_font_destroy_unscaled_font,
|
|
+ _cairo_atsui_font_font_extents,
|
|
+ _cairo_atsui_font_text_to_glyphs,
|
|
+ _cairo_atsui_font_glyph_extents,
|
|
+ _cairo_atsui_font_glyph_bbox,
|
|
+ _cairo_atsui_font_show_glyphs,
|
|
+ _cairo_atsui_font_glyph_path,
|
|
+ _cairo_atsui_font_get_glyph_cache_key,
|
|
+ _cairo_atsui_font_create_glyph
|
|
};
|
|
+
|
|
+
|
|
+cairo_font_t *cairo_atsui_font_create(ATSUStyle style)
|
|
+{
|
|
+#if 0
|
|
+ cairo_font_scale_t scale;
|
|
+ cairo_font_t *scaled;
|
|
+ cairo_atsui_font_t *f = NULL;
|
|
+
|
|
+
|
|
+ scaled = malloc(sizeof(cairo_font_t));
|
|
+ if (scaled == NULL)
|
|
+ return NULL;
|
|
+
|
|
+
|
|
+ f = malloc(sizeof(cairo_atsui_font_t));
|
|
+ if (f) {
|
|
+ if (_cairo_unscaled_font_init(&f->base, &cairo_atsui_font_backend)
|
|
+ == CAIRO_STATUS_SUCCESS) {
|
|
+ f->style = style;
|
|
+
|
|
+ _cairo_font_init(scaled, &scale, &f->base);
|
|
+
|
|
+ return scaled;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ free(scaled);
|
|
+
|
|
+#endif
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
--- cairo-0.4.0/src/cairo_quartz_surface.c 2005-02-22 13:24:50.000000000 -0600
|
|
+++ cairo/src/cairo_quartz_surface.c 2005-03-24 13:42:53.000000000 -0600
|
|
@@ -36,66 +36,45 @@
|
|
#include "cairoint.h"
|
|
#include "cairo-quartz.h"
|
|
|
|
-#pragma mark Types
|
|
-
|
|
typedef struct cairo_quartz_surface {
|
|
- cairo_surface_t base;
|
|
-
|
|
- CGContextRef context;
|
|
-
|
|
- int width;
|
|
- int height;
|
|
-
|
|
- cairo_image_surface_t *image;
|
|
-
|
|
- CGImageRef cgImage;
|
|
-} cairo_quartz_surface_t;
|
|
-
|
|
-
|
|
+ cairo_surface_t base;
|
|
|
|
+ CGContextRef context;
|
|
|
|
+ int width;
|
|
+ int height;
|
|
|
|
-#pragma mark Private functions
|
|
-
|
|
-
|
|
+ cairo_image_surface_t *image;
|
|
|
|
+ CGImageRef cgImage;
|
|
+} cairo_quartz_surface_t;
|
|
|
|
-void ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
|
+static void
|
|
+ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
|
{
|
|
- if (data != NULL)
|
|
- {
|
|
- free((void *)data);
|
|
+ if (data != NULL) {
|
|
+ free((void *) data);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
-
|
|
-#pragma mark Public functions
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
void
|
|
-cairo_set_target_quartz_context( cairo_t *cr,
|
|
- CGContextRef context,
|
|
- int width,
|
|
- int height)
|
|
+cairo_set_target_quartz_context(cairo_t * cr,
|
|
+ CGContextRef context,
|
|
+ int width, int height)
|
|
{
|
|
cairo_surface_t *surface;
|
|
-
|
|
-
|
|
+
|
|
+
|
|
if (cr->status && cr->status != CAIRO_STATUS_NO_TARGET_SURFACE)
|
|
return;
|
|
-
|
|
+
|
|
surface = cairo_quartz_surface_create(context, width, height);
|
|
- if (surface == NULL)
|
|
- {
|
|
+ if (surface == NULL) {
|
|
cr->status = CAIRO_STATUS_NO_MEMORY;
|
|
return;
|
|
}
|
|
-
|
|
+
|
|
cairo_set_target_surface(cr, surface);
|
|
|
|
/* cairo_set_target_surface takes a reference, so we must destroy ours */
|
|
@@ -103,202 +82,201 @@
|
|
}
|
|
|
|
|
|
-static cairo_surface_t *
|
|
-_cairo_quartz_surface_create_similar( void *abstract_src,
|
|
- cairo_format_t format,
|
|
- int drawable,
|
|
- int width,
|
|
- int height)
|
|
+static cairo_surface_t *_cairo_quartz_surface_create_similar(void
|
|
+ *abstract_src,
|
|
+ cairo_format_t
|
|
+ format,
|
|
+ int drawable,
|
|
+ int width,
|
|
+ int height)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|
|
-static void
|
|
-_cairo_quartz_surface_destroy(void *abstract_surface)
|
|
+static void _cairo_quartz_surface_destroy(void *abstract_surface)
|
|
{
|
|
cairo_quartz_surface_t *surface = abstract_surface;
|
|
-
|
|
-
|
|
+
|
|
+ if (surface->image)
|
|
+ cairo_surface_destroy(surface->image);
|
|
+
|
|
if (surface->cgImage)
|
|
- {
|
|
- CGImageRelease(surface->cgImage);
|
|
- }
|
|
-
|
|
+ CGImageRelease(surface->cgImage);
|
|
|
|
free(surface);
|
|
}
|
|
|
|
|
|
-static double
|
|
-_cairo_quartz_surface_pixels_per_inch(void *abstract_surface)
|
|
+static double _cairo_quartz_surface_pixels_per_inch(void *abstract_surface)
|
|
{
|
|
-
|
|
-
|
|
// TODO - get this from CGDirectDisplay somehow?
|
|
return 96.0;
|
|
}
|
|
|
|
|
|
-static cairo_image_surface_t *
|
|
-_cairo_quartz_surface_get_image(void *abstract_surface)
|
|
+static cairo_status_t
|
|
+_cairo_quartz_surface_acquire_source_image(void *abstract_surface,
|
|
+ cairo_image_surface_t **image_out,
|
|
+ void **image_extra)
|
|
{
|
|
- cairo_quartz_surface_t *surface = abstract_surface;
|
|
- CGColorSpaceRef colorSpace;
|
|
- void *imageData;
|
|
- UInt32 imageDataSize, rowBytes;
|
|
- CGDataProviderRef dataProvider;
|
|
-
|
|
-
|
|
+ cairo_quartz_surface_t *surface = abstract_surface;
|
|
+ CGColorSpaceRef colorSpace;
|
|
+ void *imageData;
|
|
+ UInt32 imageDataSize, rowBytes;
|
|
+ CGDataProviderRef dataProvider;
|
|
+
|
|
// We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
|
|
// struct. If the window is ever drawn to without going through Cairo, then
|
|
// we would need to refetch the pixel data from the window into the cached
|
|
// image surface.
|
|
- if (surface->image)
|
|
- {
|
|
+ if (surface->image) {
|
|
cairo_surface_reference(&surface->image->base);
|
|
|
|
- return surface->image;
|
|
+ *image_out = surface->image;
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
-
|
|
+
|
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
-
|
|
-
|
|
+
|
|
+
|
|
rowBytes = surface->width * 4;
|
|
imageDataSize = rowBytes * surface->height;
|
|
imageData = malloc(imageDataSize);
|
|
-
|
|
- dataProvider = CGDataProviderCreateWithData(NULL, imageData, imageDataSize, ImageDataReleaseFunc);
|
|
-
|
|
- surface->cgImage = CGImageCreate( surface->width,
|
|
- surface->height,
|
|
- 8,
|
|
- 32,
|
|
- rowBytes,
|
|
- colorSpace,
|
|
- kCGImageAlphaPremultipliedFirst,
|
|
- dataProvider,
|
|
- NULL,
|
|
- false,
|
|
- kCGRenderingIntentDefault);
|
|
-
|
|
-
|
|
+
|
|
+ dataProvider =
|
|
+ CGDataProviderCreateWithData(NULL, imageData, imageDataSize,
|
|
+ ImageDataReleaseFunc);
|
|
+
|
|
+ surface->cgImage = CGImageCreate(surface->width,
|
|
+ surface->height,
|
|
+ 8,
|
|
+ 32,
|
|
+ rowBytes,
|
|
+ colorSpace,
|
|
+ kCGImageAlphaPremultipliedFirst,
|
|
+ dataProvider,
|
|
+ NULL,
|
|
+ false, kCGRenderingIntentDefault);
|
|
+
|
|
CGColorSpaceRelease(colorSpace);
|
|
CGDataProviderRelease(dataProvider);
|
|
-
|
|
-
|
|
+
|
|
surface->image = (cairo_image_surface_t *)
|
|
- cairo_image_surface_create_for_data( imageData,
|
|
- CAIRO_FORMAT_ARGB32,
|
|
- surface->width,
|
|
- surface->height,
|
|
- rowBytes);
|
|
-
|
|
-
|
|
+ cairo_image_surface_create_for_data(imageData,
|
|
+ CAIRO_FORMAT_ARGB32,
|
|
+ surface->width,
|
|
+ surface->height, rowBytes);
|
|
+
|
|
+
|
|
// Set the image surface Cairo state to match our own.
|
|
_cairo_image_surface_set_repeat(surface->image, surface->base.repeat);
|
|
- _cairo_image_surface_set_matrix(surface->image, &(surface->base.matrix));
|
|
-
|
|
+ _cairo_image_surface_set_matrix(surface->image,
|
|
+ &(surface->base.matrix));
|
|
+
|
|
+ *image_out = surface->image;
|
|
+ *image_extra = NULL;
|
|
|
|
- return surface->image;
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
-static cairo_status_t
|
|
-_cairo_quartz_surface_set_image( void *abstract_surface,
|
|
- cairo_image_surface_t *image)
|
|
+static void
|
|
+_cairo_quartz_surface_release_source_image(void *abstract_surface,
|
|
+ cairo_image_surface_t * image,
|
|
+ void *image_extra)
|
|
{
|
|
- cairo_quartz_surface_t *surface = abstract_surface;
|
|
- cairo_status_t status;
|
|
-
|
|
-
|
|
- if (surface->image == image)
|
|
- {
|
|
- CGRect rect;
|
|
-
|
|
-
|
|
- rect = CGRectMake(0, 0, surface->width, surface->height);
|
|
-
|
|
- CGContextDrawImage(surface->context, rect, surface->cgImage);
|
|
-
|
|
-
|
|
- status = CAIRO_STATUS_SUCCESS;
|
|
- }
|
|
- else
|
|
- {
|
|
- // TODO - set_image from something other than what we returned from get_image
|
|
- status = CAIRO_STATUS_NO_TARGET_SURFACE;
|
|
- }
|
|
-
|
|
-
|
|
- return status;
|
|
}
|
|
|
|
|
|
static cairo_status_t
|
|
-_cairo_quartz_surface_set_matrix(void *abstract_surface, cairo_matrix_t *matrix)
|
|
+_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
|
|
+ cairo_rectangle_t * interest_rect,
|
|
+ cairo_image_surface_t **
|
|
+ image_out,
|
|
+ cairo_rectangle_t * image_rect,
|
|
+ void **image_extra)
|
|
{
|
|
cairo_quartz_surface_t *surface = abstract_surface;
|
|
|
|
- return _cairo_image_surface_set_matrix(surface->image, matrix);
|
|
+ image_rect->x = 0;
|
|
+ image_rect->y = 0;
|
|
+ image_rect->width = surface->image->width;
|
|
+ image_rect->height = surface->image->height;
|
|
+
|
|
+ *image_out = surface->image;
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
-static cairo_status_t
|
|
-_cairo_quartz_surface_set_filter(void *abstract_surface, cairo_filter_t filter)
|
|
+static void
|
|
+_cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
|
+ cairo_rectangle_t *
|
|
+ intersect_rect,
|
|
+ cairo_image_surface_t * image,
|
|
+ cairo_rectangle_t * image_rect,
|
|
+ void *image_extra)
|
|
{
|
|
cairo_quartz_surface_t *surface = abstract_surface;
|
|
|
|
- return _cairo_image_surface_set_filter(surface->image, filter);
|
|
+ if (surface->image == image) {
|
|
+ CGRect rect;
|
|
+
|
|
+ rect = CGRectMake(0, 0, surface->width, surface->height);
|
|
+
|
|
+ CGContextDrawImage(surface->context, rect, surface->cgImage);
|
|
+
|
|
+ memset(surface->image->data, 0, surface->width * surface->height * 4);
|
|
+ }
|
|
}
|
|
|
|
|
|
static cairo_status_t
|
|
-_cairo_quartz_surface_set_repeat(void *abstract_surface, int repeat)
|
|
+_cairo_quartz_surface_clone_similar(void *surface,
|
|
+ cairo_surface_t * src,
|
|
+ cairo_surface_t ** clone_out)
|
|
{
|
|
- cairo_quartz_surface_t *surface = abstract_surface;
|
|
-
|
|
- return _cairo_image_surface_set_repeat(surface->image, repeat);
|
|
+ return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
static cairo_int_status_t
|
|
-_cairo_quartz_surface_composite( cairo_operator_t operator,
|
|
- cairo_surface_t *generic_src,
|
|
- cairo_surface_t *generic_mask,
|
|
- void *abstract_dst,
|
|
- int src_x,
|
|
- int src_y,
|
|
- int mask_x,
|
|
- int mask_y,
|
|
- int dst_x,
|
|
- int dst_y,
|
|
- unsigned int width,
|
|
- unsigned int height)
|
|
+_cairo_quartz_surface_composite(cairo_operator_t operator,
|
|
+ cairo_surface_t * generic_src,
|
|
+ cairo_surface_t * generic_mask,
|
|
+ void *abstract_dst,
|
|
+ int src_x,
|
|
+ int src_y,
|
|
+ int mask_x,
|
|
+ int mask_y,
|
|
+ int dst_x,
|
|
+ int dst_y,
|
|
+ unsigned int width, unsigned int height)
|
|
{
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
static cairo_int_status_t
|
|
-_cairo_quartz_surface_fill_rectangles( void *abstract_surface,
|
|
- cairo_operator_t operator,
|
|
- const cairo_color_t *color,
|
|
- cairo_rectangle_t *rects,
|
|
- int num_rects)
|
|
+_cairo_quartz_surface_fill_rectangles(void *abstract_surface,
|
|
+ cairo_operator_t operator,
|
|
+ const cairo_color_t * color,
|
|
+ cairo_rectangle_t * rects,
|
|
+ int num_rects)
|
|
{
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
static cairo_int_status_t
|
|
-_cairo_quartz_surface_composite_trapezoids( cairo_operator_t operator,
|
|
- cairo_surface_t *generic_src,
|
|
- void *abstract_dst,
|
|
- int xSrc,
|
|
- int ySrc,
|
|
- cairo_trapezoid_t *traps,
|
|
- int num_traps)
|
|
+_cairo_quartz_surface_composite_trapezoids(cairo_operator_t operator,
|
|
+ cairo_surface_t * generic_src,
|
|
+ void *abstract_dst,
|
|
+ int xSrc,
|
|
+ int ySrc,
|
|
+ cairo_trapezoid_t * traps,
|
|
+ int num_traps)
|
|
{
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
}
|
|
@@ -319,8 +297,8 @@
|
|
|
|
|
|
static cairo_int_status_t
|
|
-_cairo_quartz_surface_set_clip_region( void *abstract_surface,
|
|
- pixman_region16_t *region)
|
|
+_cairo_quartz_surface_set_clip_region(void *abstract_surface,
|
|
+ pixman_region16_t * region)
|
|
{
|
|
cairo_quartz_surface_t *surface = abstract_surface;
|
|
|
|
@@ -328,10 +306,19 @@
|
|
}
|
|
|
|
|
|
-static cairo_int_status_t
|
|
-_cairo_quartz_surface_create_pattern( void *abstract_surface,
|
|
- cairo_pattern_t *pattern,
|
|
- cairo_box_t *extents)
|
|
+static cairo_status_t
|
|
+_cairo_quartz_surface_show_glyphs(cairo_font_t * font,
|
|
+ cairo_operator_t operator,
|
|
+ cairo_pattern_t * pattern,
|
|
+ void *abstract_surface,
|
|
+ int source_x,
|
|
+ int source_y,
|
|
+ int dest_x,
|
|
+ int dest_y,
|
|
+ unsigned int width,
|
|
+ unsigned int height,
|
|
+ const cairo_glyph_t * glyphs,
|
|
+ int num_glyphs)
|
|
{
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
}
|
|
@@ -341,52 +328,41 @@
|
|
_cairo_quartz_surface_create_similar,
|
|
_cairo_quartz_surface_destroy,
|
|
_cairo_quartz_surface_pixels_per_inch,
|
|
- _cairo_quartz_surface_get_image,
|
|
- _cairo_quartz_surface_set_image,
|
|
- _cairo_quartz_surface_set_matrix,
|
|
- _cairo_quartz_surface_set_filter,
|
|
- _cairo_quartz_surface_set_repeat,
|
|
+ _cairo_quartz_surface_acquire_source_image,
|
|
+ _cairo_quartz_surface_release_source_image,
|
|
+ _cairo_quartz_surface_acquire_dest_image,
|
|
+ _cairo_quartz_surface_release_dest_image,
|
|
+ _cairo_quartz_surface_clone_similar,
|
|
_cairo_quartz_surface_composite,
|
|
_cairo_quartz_surface_fill_rectangles,
|
|
_cairo_quartz_surface_composite_trapezoids,
|
|
_cairo_quartz_surface_copy_page,
|
|
_cairo_quartz_surface_show_page,
|
|
_cairo_quartz_surface_set_clip_region,
|
|
- _cairo_quartz_surface_create_pattern
|
|
+ _cairo_quartz_surface_show_glyphs
|
|
};
|
|
|
|
|
|
-cairo_surface_t *
|
|
-cairo_quartz_surface_create( CGContextRef context,
|
|
- int width,
|
|
- int height)
|
|
+cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
|
+ int width, int height)
|
|
{
|
|
cairo_quartz_surface_t *surface;
|
|
-
|
|
-
|
|
+
|
|
surface = malloc(sizeof(cairo_quartz_surface_t));
|
|
if (surface == NULL)
|
|
return NULL;
|
|
-
|
|
+
|
|
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);
|
|
-
|
|
-
|
|
- surface->context = context;
|
|
-
|
|
- surface->width = width;
|
|
- surface->height = height;
|
|
-
|
|
- surface->image = NULL;
|
|
-
|
|
- surface->cgImage = NULL;
|
|
-
|
|
-
|
|
- // Set up the image surface which Cairo draws into and we blit to & from.
|
|
- surface->image = _cairo_quartz_surface_get_image(surface);
|
|
-
|
|
-
|
|
- return (cairo_surface_t *)surface;
|
|
-}
|
|
|
|
+ surface->context = context;
|
|
+ surface->width = width;
|
|
+ surface->height = height;
|
|
+ surface->image = NULL;
|
|
+ surface->cgImage = NULL;
|
|
+
|
|
+ // Set up the image surface which Cairo draws into and we blit to & from.
|
|
+ void *foo;
|
|
+ _cairo_quartz_surface_acquire_source_image(surface, &surface->image, &foo);
|
|
|
|
-DEPRECATE (cairo_surface_create_for_drawable, cairo_quartz_surface_create);
|
|
+ return (cairo_surface_t *) surface;
|
|
+}
|