revert quartz surface back to older version; new version has SDK 10.4 depenencies

This commit is contained in:
vladimir%pobox.com 2006-06-06 02:47:09 +00:00
parent af7d5c7dd6
commit d55c74e8c7
3 changed files with 229 additions and 249 deletions

View File

@ -218,8 +218,6 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
cairo_status_t status;
font = malloc(sizeof(cairo_atsui_font_t));
if (font == NULL)
return CAIRO_STATUS_NO_MEMORY;
_cairo_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
&cairo_atsui_scaled_font_backend);
@ -596,134 +594,105 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
int num_glyphs)
{
cairo_atsui_font_t *font = abstract_font;
CGContextRef myBitmapContext = 0, drawingContext;
CGContextRef myBitmapContext;
CGColorSpaceRef colorSpace;
cairo_image_surface_t *destImageSurface;
int i;
int i, bits_per_comp, alpha;
void *extra = NULL;
cairo_bool_t can_draw_directly;
cairo_rectangle_fixed_t rect;
/* Check if we can draw directly to the destination surface */
can_draw_directly = _cairo_surface_is_quartz (generic_surface) &&
_cairo_pattern_is_opaque_solid (pattern) &&
op == CAIRO_OPERATOR_OVER;
cairo_rectangle_fixed_t rect = {dest_x, dest_y, width, height};
_cairo_surface_acquire_dest_image(generic_surface,
&rect,
&destImageSurface,
&rect,
&extra);
if (!can_draw_directly) {
CGColorSpaceRef colorSpace = 0;
int bits_per_comp, alpha;
rect.x = dest_x;
rect.y = dest_y;
rect.width = width;
rect.height = height;
_cairo_surface_acquire_dest_image(generic_surface,
&rect,
&destImageSurface,
&rect,
&extra);
/* Create a CGBitmapContext for the dest surface for drawing into */
if (destImageSurface->depth == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
bits_per_comp = 1;
alpha = kCGImageAlphaNone;
} else if (destImageSurface->depth == 8) {
colorSpace = CGColorSpaceCreateDeviceGray();
bits_per_comp = 8;
alpha = kCGImageAlphaNone;
} else if (destImageSurface->depth == 24) {
colorSpace = CGColorSpaceCreateDeviceRGB();
bits_per_comp = 8;
alpha = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
} else if (destImageSurface->depth == 32) {
colorSpace = CGColorSpaceCreateDeviceRGB();
bits_per_comp = 8;
alpha = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
} else {
// not reached
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Create a CGBitmapContext for the dest surface for drawing into */
colorSpace = CGColorSpaceCreateDeviceRGB();
myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
destImageSurface->width,
destImageSurface->height,
bits_per_comp,
destImageSurface->stride,
colorSpace,
alpha);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height);
CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f);
drawingContext = myBitmapContext;
/* Create a CGBitmapContext for the dest surface for drawing into */
if (destImageSurface->depth == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
bits_per_comp = 1;
alpha = kCGImageAlphaNone;
} else if (destImageSurface->depth == 8) {
colorSpace = CGColorSpaceCreateDeviceGray();
bits_per_comp = 8;
alpha = kCGImageAlphaNone;
} else if (destImageSurface->depth == 24) {
colorSpace = CGColorSpaceCreateDeviceRGB();
bits_per_comp = 8;
alpha = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
} else if (destImageSurface->depth == 32) {
colorSpace = CGColorSpaceCreateDeviceRGB();
bits_per_comp = 8;
alpha = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
} else {
drawingContext = ((cairo_quartz_surface_t *)generic_surface)->context;
CGContextSaveGState (drawingContext);
// not reached
return CAIRO_INT_STATUS_UNSUPPORTED;
}
myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
destImageSurface->width,
destImageSurface->height,
bits_per_comp,
destImageSurface->stride,
colorSpace,
alpha);
CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height);
CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f);
ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID);
CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont);
CGContextSetFont(drawingContext, cgFont);
CGContextSetFont(myBitmapContext, cgFont);
CGAffineTransform textTransform =
CGAffineTransformMakeWithCairoFontScale(&font->base.scale);
textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f);
CGContextSetFontSize(drawingContext, 1.0);
CGContextSetTextMatrix(drawingContext, textTransform);
CGContextSetFontSize(myBitmapContext, 1.0);
CGContextSetTextMatrix(myBitmapContext, textTransform);
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID &&
_cairo_pattern_is_opaque_solid(pattern))
{
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
CGContextSetRGBFillColor(drawingContext,
CGContextSetRGBFillColor(myBitmapContext,
solid->color.red,
solid->color.green,
solid->color.blue, 1.0f);
} else {
CGContextSetRGBFillColor(drawingContext, 0.0f, 0.0f, 0.0f, 0.0f);
CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f);
}
if (_cairo_surface_is_quartz (generic_surface)) {
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)generic_surface;
if (surface->clip_region) {
pixman_box16_t *boxes = pixman_region_rects (surface->clip_region);
int num_boxes = pixman_region_num_rects (surface->clip_region);
CGRect stack_rects[10];
CGRect *rects;
int i;
/* XXX: Return-value of malloc needs to be checked for
* NULL. Can someone fix this who is more familiar with
* the cleanup needed in this function?
*/
if (num_boxes > 10)
rects = malloc (sizeof (CGRect) * num_boxes);
else
rects = stack_rects;
for (i = 0; i < num_boxes; i++) {
rects[i].origin.x = boxes[i].x1;
rects[i].origin.y = boxes[i].y1;
rects[i].size.width = boxes[i].x2 - boxes[i].x1;
rects[i].size.height = boxes[i].y2 - boxes[i].y1;
}
CGContextClipToRects (drawingContext, rects, num_boxes);
if (rects != stack_rects)
free(rects);
if (_cairo_surface_is_quartz (generic_surface)) {
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)generic_surface;
if (surface->clip_region) {
pixman_box16_t *boxes = pixman_region_rects (surface->clip_region);
int num_boxes = pixman_region_num_rects (surface->clip_region);
CGRect stack_rects[10];
CGRect *rects;
int i;
if (num_boxes > 10)
rects = malloc (sizeof (CGRect) * num_boxes);
else
rects = stack_rects;
for (i = 0; i < num_boxes; i++) {
rects[i].origin.x = boxes[i].x1;
rects[i].origin.y = boxes[i].y1;
rects[i].size.width = boxes[i].x2 - boxes[i].x1;
rects[i].size.height = boxes[i].y2 - boxes[i].y1;
}
CGContextClipToRects (myBitmapContext, rects, num_boxes);
if (rects != stack_rects)
free(rects);
}
} else {
/* XXX: Need to get the text clipped */
}
} else {
/* XXX: Need to get the text clipped */
}
/* TODO - bold and italic text
*
@ -736,23 +705,21 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
for (i = 0; i < num_glyphs; i++) {
CGGlyph theGlyph = glyphs[i].index;
CGContextShowGlyphsAtPoint(drawingContext,
CGContextShowGlyphsAtPoint(myBitmapContext,
glyphs[i].x,
glyphs[i].y,
&theGlyph, 1);
}
if (!can_draw_directly) {
CGContextRelease(myBitmapContext);
_cairo_surface_release_dest_image(generic_surface,
&rect,
destImageSurface,
&rect,
extra);
} else {
CGContextRestoreGState (drawingContext);
}
CGColorSpaceRelease(colorSpace);
CGContextRelease(myBitmapContext);
_cairo_surface_release_dest_image(generic_surface,
&rect,
destImageSurface,
&rect,
extra);
return CAIRO_STATUS_SUCCESS;
}

View File

@ -44,11 +44,15 @@ typedef struct cairo_quartz_surface {
CGContextRef context;
cairo_bool_t y_grows_down;
cairo_bool_t flipped;
cairo_rectangle_fixed_t extents;
int width;
int height;
pixman_region16_t *clip_region;
cairo_image_surface_t *image;
pixman_region16_t *clip_region;
CGImageRef cgImage;
} cairo_quartz_surface_t;
cairo_bool_t

View File

@ -37,13 +37,27 @@
#include "cairo-private.h"
#include "cairo-quartz-private.h"
static void
ImageDataReleaseFunc(void *info, const void *data, size_t size)
{
if (data != NULL) {
free((void *) data);
}
}
static cairo_status_t
_cairo_quartz_surface_finish(void *abstract_surface)
{
cairo_quartz_surface_t *surface = abstract_surface;
if (surface->clip_region)
pixman_region_destroy (surface->clip_region);
if (surface->image)
cairo_surface_destroy(&surface->image->base);
if (surface->cgImage)
CGImageRelease(surface->cgImage);
if (surface->clip_region)
pixman_region_destroy (surface->clip_region);
return CAIRO_STATUS_SUCCESS;
}
@ -52,128 +66,118 @@ 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;
if (CGBitmapContextGetBitmapInfo (surface->context) != 0) {
/* XXX: We can create an image out of the bitmap here */
}
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
cairo_rectangle_fixed_t *interest_rect,
cairo_image_surface_t **image_out,
cairo_rectangle_fixed_t *image_rect,
void **image_extra)
{
cairo_quartz_surface_t *surface = abstract_surface;
cairo_surface_t *image_surface;
unsigned char *data;
int x1, y1, x2, y2;
CGColorSpaceRef colorSpace;
void *imageData;
UInt32 imageDataSize, rowBytes;
CGDataProviderRef dataProvider;
x1 = surface->extents.x;
x2 = surface->extents.x + surface->extents.width;
y1 = surface->extents.y;
y2 = surface->extents.y + surface->extents.height;
/* 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) {
cairo_surface_reference(&surface->image->base);
if (interest_rect->x > x1)
x1 = interest_rect->x;
if (interest_rect->y > y1)
y1 = interest_rect->y;
if (interest_rect->x + interest_rect->width < x2)
x2 = interest_rect->x + interest_rect->width;
if (interest_rect->y + interest_rect->height < y2)
y2 = interest_rect->y + interest_rect->height;
if (x1 >= x2 || y1 >= y2) {
*image_out = NULL;
*image_extra = NULL;
*image_out = surface->image;
return CAIRO_STATUS_SUCCESS;
}
image_rect->x = x1;
image_rect->y = y1;
image_rect->width = x2 - x1;
image_rect->height = y2 - y1;
colorSpace = CGColorSpaceCreateDeviceRGB();
data = calloc (image_rect->width * image_rect->height * 4, 1);
image_surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
image_rect->width,
image_rect->height,
image_rect->width * 4);
*image_out = (cairo_image_surface_t *)image_surface;
*image_extra = data;
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);
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);
if (surface->image->base.status) {
if (surface->cgImage)
CGImageRelease(surface->cgImage);
return CAIRO_STATUS_NO_MEMORY;
}
*image_out = surface->image;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static CGImageRef
create_image_from_surface (cairo_image_surface_t *image_surface, void *data)
{
CGImageRef image;
CGColorSpaceRef color_space;
CGDataProviderRef data_provider;
int width, height;
width = cairo_image_surface_get_width ((cairo_surface_t *)image_surface);
height = cairo_image_surface_get_height ((cairo_surface_t *)image_surface);
color_space = CGColorSpaceCreateDeviceRGB();
data_provider = CGDataProviderCreateWithData (NULL, data,
width * height * 4, NULL);
image = CGImageCreate (width, height,
8, 32,
width * 4,
color_space,
kCGImageAlphaPremultipliedFirst,
data_provider,
NULL,
FALSE, kCGRenderingIntentDefault);
CGColorSpaceRelease (color_space);
CGDataProviderRelease (data_provider);
return image;
}
static void
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
cairo_rectangle_fixed_t *intersect_rect,
cairo_image_surface_t *image,
cairo_rectangle_fixed_t *image_rect,
void *image_extra)
static cairo_status_t
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
cairo_rectangle_fixed_t * interest_rect,
cairo_image_surface_t **
image_out,
cairo_rectangle_fixed_t * image_rect,
void **image_extra)
{
cairo_quartz_surface_t *surface = abstract_surface;
CGImageRef image_ref;
CGRect rect;
image_ref = create_image_from_surface (image, image_extra);
rect = CGRectMake (image_rect->x, image_rect->y, image_rect->width, image_rect->height);
image_rect->x = 0;
image_rect->y = 0;
image_rect->width = surface->image->width;
image_rect->height = surface->image->height;
if (surface->y_grows_down) {
CGContextSaveGState (surface->context);
CGContextTranslateCTM (surface->context, 0, image_rect->height + 2 * image_rect->y);
CGContextScaleCTM (surface->context, 1, -1);
*image_out = surface->image;
if (image_extra)
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
cairo_rectangle_fixed_t *
intersect_rect,
cairo_image_surface_t * image,
cairo_rectangle_fixed_t * image_rect,
void *image_extra)
{
cairo_quartz_surface_t *surface = abstract_surface;
if (surface->image == image) {
CGRect rect;
rect = CGRectMake(0, 0, surface->width, surface->height);
if (surface->flipped) {
CGContextSaveGState (surface->context);
CGContextTranslateCTM (surface->context, 0, surface->height);
CGContextScaleCTM (surface->context, 1, -1);
}
CGContextDrawImage(surface->context, rect, surface->cgImage);
if (surface->flipped)
CGContextRestoreGState (surface->context);
memset(surface->image->data, 0, surface->width * surface->height * 4);
}
CGContextDrawImage(surface->context, rect, image_ref);
CFRelease (image_ref);
if (surface->y_grows_down) {
CGContextRestoreGState (surface->context);
}
cairo_surface_destroy ((cairo_surface_t *)image);
free (image_extra);
}
static cairo_int_status_t
@ -181,26 +185,33 @@ _cairo_quartz_surface_set_clip_region(void *abstract_surface,
pixman_region16_t * region)
{
cairo_quartz_surface_t *surface = abstract_surface;
unsigned int serial;
if (surface->clip_region)
pixman_region_destroy (surface->clip_region);
serial = _cairo_surface_allocate_clip_serial (&surface->image->base);
if (surface->clip_region)
pixman_region_destroy (surface->clip_region);
if (region) {
surface->clip_region = pixman_region_create ();
pixman_region_copy (surface->clip_region, region);
} else
surface->clip_region = NULL;
return CAIRO_STATUS_SUCCESS;
if (region) {
surface->clip_region = pixman_region_create ();
pixman_region_copy (surface->clip_region, region);
} else
surface->clip_region = NULL;
return _cairo_surface_set_clip_region(&surface->image->base,
region, serial);
}
static cairo_int_status_t
_cairo_quartz_surface_get_extents (void *abstract_surface,
cairo_rectangle_fixed_t *rectangle)
_cairo_quartz_surface_get_extents (void *abstract_surface,
cairo_rectangle_fixed_t * rectangle)
{
cairo_quartz_surface_t *surface = abstract_surface;
*rectangle = surface->extents;
rectangle->x = 0;
rectangle->y = 0;
rectangle->width = surface->width;
rectangle->height = surface->height;
return CAIRO_STATUS_SUCCESS;
}
@ -227,12 +238,10 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
int width,
int height,
cairo_bool_t y_grows_down)
cairo_bool_t flipped,
int width, int height)
{
cairo_quartz_surface_t *surface;
CGRect clip_box;
surface = malloc(sizeof(cairo_quartz_surface_t));
if (surface == NULL) {
@ -240,19 +249,19 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
return (cairo_surface_t*) &_cairo_surface_nil;
}
/* XXX: The content value here might be totally wrong. */
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend,
CAIRO_CONTENT_COLOR_ALPHA);
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);
surface->context = context;
surface->clip_region = NULL;
surface->y_grows_down = y_grows_down;
surface->width = width;
surface->height = height;
surface->image = NULL;
surface->cgImage = NULL;
surface->clip_region = NULL;
surface->flipped = flipped;
clip_box = CGContextGetClipBoundingBox (context);
surface->extents.x = clip_box.origin.x;
surface->extents.y = clip_box.origin.y;
surface->extents.width = clip_box.size.width;
surface->extents.height = clip_box.size.height;
/* 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);
return (cairo_surface_t *) surface;
}