[cairo] Native Mac OS X port
Calum Robinson
calumr at mac.com
Sun Dec 5 09:53:58 PST 2004
On 4 Dec 2004, at 18:22, Miguel de Icaza wrote:
> Hello Calum, Cairo developers,
>
> We are wondering over in Mono-land about the state of the OSX port
> of Cairo, we are very interested in this, as we are using Cairo as the
> substrate for our Windows.Forms API implementation.
>
> The last post we have seen was from September 23rd, is there a more
> recent patch against Cairo/OSX?
I have a more recent version here, and have attached it to this mail.
I am in the process of implementing an ATSUI font backend for Cairo,
similar to the existing FreeType one. I also need to modify the Cairo
Makefile (as my port is currently built by an Xcode project).
Calum Robinson
http://homepage.mac.com/calumr
-------------- next part --------------
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Calum Robinson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Calum Robinson
*
* Contributor(s):
* Calum Robinson <calumr at mac.com>
*/
#include "cairoint.h"
#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;
#pragma mark Private functions
void ImageDataReleaseFunc(void *info, const void *data, size_t size)
{
if (data != NULL)
{
free(data);
}
}
#pragma mark Public functions
void
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)
{
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 */
cairo_surface_destroy (surface);
}
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)
{
cairo_quartz_surface_t *surface = abstract_surface;
if (surface->cgImage)
{
CGImageRelease(surface->cgImage);
}
free(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)
{
cairo_quartz_surface_t *surface = abstract_surface;
OSStatus err;
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)
{
cairo_surface_reference (&surface->image->base);
return surface->image;
}
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);
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);
// 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));
return surface->image;
}
static cairo_status_t
_cairo_quartz_surface_set_image( void *abstract_surface,
cairo_image_surface_t *image)
{
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
{
/*PixMapHandle pixMap;
pixMap = GetPortPixMap(windowPort);
if (GetPixDepth(pixMap) == 32 && image->depth == 32)
{
UInt32 row;
void *dstData, *srcData;
UInt32 srcRowBytes, dstRowBytes;
dstRowBytes = GetPixRowBytes(pixMap);
srcRowBytes = image->stride;
srcData = image->data;
dstData = GetPixBaseAddr(pixMap) + GetOffsetToWindowContentPixels(surface->window, dstRowBytes);
for (row = 0; row < image->height; row++)
{
memcpy(dstData, srcData, srcRowBytes);
dstData += dstRowBytes;
srcData += srcRowBytes;
}
status = CAIRO_STATUS_SUCCESS;
}
else
{
status = CAIRO_INT_STATUS_UNSUPPORTED;
}*/
}
return status;
}
static cairo_status_t
_cairo_quartz_surface_set_matrix(void *abstract_surface, cairo_matrix_t *matrix)
{
cairo_quartz_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_matrix (surface->image, matrix);
}
static cairo_status_t
_cairo_quartz_surface_set_filter(void *abstract_surface, cairo_filter_t filter)
{
cairo_quartz_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_filter (surface->image, filter);
}
static cairo_status_t
_cairo_quartz_surface_set_repeat(void *abstract_surface, int repeat)
{
cairo_quartz_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_repeat (surface->image, repeat);
}
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)
{
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)
{
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)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_quartz_surface_copy_page (void *abstract_surface)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_quartz_surface_show_page (void *abstract_surface)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_quartz_surface_set_clip_region( void *abstract_surface,
pixman_region16_t *region)
{
cairo_quartz_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_clip_region (surface->image, region);
}
static cairo_int_status_t
_cairo_quartz_surface_create_pattern( void *abstract_surface,
cairo_pattern_t *pattern,
cairo_box_t *extents)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static const struct cairo_surface_backend cairo_quartz_surface_backend = {
_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_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_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;
}
DEPRECATE (cairo_surface_create_for_drawable, cairo_quartz_surface_create);
More information about the cairo
mailing list