[cairo-commit] 3 commits - src/cairo-quartz-surface.c
Andrea Canciani
ranma42 at kemper.freedesktop.org
Tue Feb 2 10:59:29 PST 2010
src/cairo-quartz-surface.c | 325 +++++++++++++++++++++++++++++++++------------
1 file changed, 244 insertions(+), 81 deletions(-)
New commits:
commit e2be50c722347734801468d7d9568a18dbbaaa17
Author: Andrea Canciani <ranma42 at gmail.com>
Date: Fri Jan 29 12:06:13 2010 +0100
[quartz] Fix UNSUPPORTED operations
The fallback path shouldn't be used anymore, thus fallbacks are now
handled by passing unsupported ops to the image backend.
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 904cbb8..3efd8b4 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1868,10 +1868,10 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_quartz_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_clip_t *clip)
+_cairo_quartz_surface_paint_cg (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -1917,16 +1917,43 @@ _cairo_quartz_surface_paint (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_quartz_surface_fill (void *abstract_surface,
+_cairo_quartz_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance,
- cairo_antialias_t antialias,
cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ cairo_int_status_t rv;
+ cairo_image_surface_t *image;
+
+ rv = _cairo_quartz_surface_paint_cg (abstract_surface,
+ op,
+ source,
+ clip);
+
+ if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+ return rv;
+
+ rv = _cairo_quartz_get_image (surface, &image);
+ if (rv == CAIRO_STATUS_SUCCESS) {
+ rv = _cairo_surface_paint (&image->base, op, source, clip);
+ cairo_surface_destroy (&image->base);
+ }
+
+ return rv;
+}
+
+static cairo_int_status_t
+_cairo_quartz_surface_fill_cg (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
+{
+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
cairo_quartz_action_t action;
quartz_stroke_t stroke;
@@ -2009,16 +2036,53 @@ _cairo_quartz_surface_fill (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_quartz_surface_stroke (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- const cairo_stroke_style_t *style,
- const cairo_matrix_t *ctm,
- const cairo_matrix_t *ctm_inverse,
- double tolerance,
- cairo_antialias_t antialias,
- cairo_clip_t *clip)
+_cairo_quartz_surface_fill (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
+{
+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ cairo_int_status_t rv;
+ cairo_image_surface_t *image;
+
+ rv = _cairo_quartz_surface_fill_cg (abstract_surface,
+ op,
+ source,
+ path,
+ fill_rule,
+ tolerance,
+ antialias,
+ clip);
+
+ if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+ return rv;
+
+ rv = _cairo_quartz_get_image (surface, &image);
+ if (rv == CAIRO_STATUS_SUCCESS) {
+ rv = _cairo_surface_fill (&image->base, op, source,
+ path, fill_rule, tolerance, antialias,
+ clip);
+ cairo_surface_destroy (&image->base);
+ }
+
+ return rv;
+}
+
+static cairo_int_status_t
+_cairo_quartz_surface_stroke_cg (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ const cairo_stroke_style_t *style,
+ const cairo_matrix_t *ctm,
+ const cairo_matrix_t *ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -2140,16 +2204,52 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
return rv;
}
+static cairo_int_status_t
+_cairo_quartz_surface_stroke (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ const cairo_stroke_style_t *style,
+ const cairo_matrix_t *ctm,
+ const cairo_matrix_t *ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
+{
+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ cairo_int_status_t rv;
+ cairo_image_surface_t *image;
+
+ rv = _cairo_quartz_surface_stroke_cg (abstract_surface, op, source,
+ path, style, ctm, ctm_inverse,
+ tolerance, antialias,
+ clip);
+
+ if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+ return rv;
+
+ rv = _cairo_quartz_get_image (surface, &image);
+ if (rv == CAIRO_STATUS_SUCCESS) {
+ rv = _cairo_surface_stroke (&image->base, op, source,
+ path, style, ctm, ctm_inverse,
+ tolerance, antialias,
+ clip);
+ cairo_surface_destroy (&image->base);
+ }
+
+ return rv;
+}
+
#if CAIRO_HAS_QUARTZ_FONT
static cairo_int_status_t
-_cairo_quartz_surface_show_glyphs (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- cairo_clip_t *clip,
- int *remaining_glyphs)
+_cairo_quartz_surface_show_glyphs_cg (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font,
+ cairo_clip_t *clip,
+ int *remaining_glyphs)
{
CGAffineTransform textTransform, ctm;
#define STATIC_BUF_SIZE 64
@@ -2348,6 +2448,43 @@ BAIL:
#endif /* CAIRO_HAS_QUARTZ_FONT */
static cairo_int_status_t
+_cairo_quartz_surface_show_glyphs (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font,
+ cairo_clip_t *clip,
+ int *remaining_glyphs)
+{
+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ cairo_int_status_t rv = CAIRO_INT_STATUS_UNSUPPORTED;
+ cairo_image_surface_t *image;
+
+#if CAIRO_HAS_QUARTZ_FONT
+ rv = _cairo_quartz_surface_show_glyphs_cg (abstract_surface, op, source,
+ glyphs, num_glyphs,
+ scaled_font, clip, remaining_glyphs);
+
+ if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+ return rv;
+
+#endif
+
+ rv = _cairo_quartz_get_image (surface, &image);
+ if (rv == CAIRO_STATUS_SUCCESS) {
+ rv = _cairo_surface_show_text_glyphs (&image->base, op, source,
+ NULL, 0,
+ glyphs, num_glyphs,
+ NULL, 0, 0,
+ scaled_font, clip);
+ cairo_surface_destroy (&image->base);
+ }
+
+ return rv;
+}
+
+static cairo_int_status_t
_cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
@@ -2445,11 +2582,11 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
}
static cairo_int_status_t
-_cairo_quartz_surface_mask (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- cairo_clip_t *clip)
+_cairo_quartz_surface_mask_cg (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -2493,6 +2630,35 @@ _cairo_quartz_surface_mask (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_int_status_t
+_cairo_quartz_surface_mask (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ cairo_clip_t *clip)
+{
+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ cairo_int_status_t rv;
+ cairo_image_surface_t *image;
+
+ rv = _cairo_quartz_surface_mask_cg (abstract_surface,
+ op,
+ source,
+ mask,
+ clip);
+
+ if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+ return rv;
+
+ rv = _cairo_quartz_get_image (surface, &image);
+ if (rv == CAIRO_STATUS_SUCCESS) {
+ rv = _cairo_surface_mask (&image->base, op, source, mask, clip);
+ cairo_surface_destroy (&image->base);
+ }
+
+ return rv;
+}
+
static cairo_status_t
_cairo_quartz_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
cairo_path_fixed_t *path,
@@ -2574,11 +2740,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
_cairo_quartz_surface_mask,
_cairo_quartz_surface_stroke,
_cairo_quartz_surface_fill,
-#if CAIRO_HAS_QUARTZ_FONT
_cairo_quartz_surface_show_glyphs,
-#else
- NULL, /* show_glyphs */
-#endif
_cairo_quartz_surface_snapshot,
NULL, /* is_similar */
commit 3e69c38fe642be467fee0cad166b83006741d55c
Author: Andrea Canciani <ranma42 at gmail.com>
Date: Sun Jan 24 21:59:32 2010 +0100
[quartz] Fix surface to CGImage conversion
Snapshotting a surface doesn't produce a cairo_image_surface_t.
Acquiring (and later releasing) the surface is needed to access
its image data.
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index a7a94b4..904cbb8 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -920,11 +920,18 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
/* Obtain a CGImageRef from a #cairo_surface_t * */
+typedef struct {
+ cairo_surface_t *surface;
+ cairo_image_surface_t *image_out;
+ void *image_extra;
+} quartz_source_image_t;
+
static void
DataProviderReleaseCallback (void *info, const void *data, size_t size)
{
- cairo_surface_t *surface = (cairo_surface_t *) info;
- cairo_surface_destroy (surface);
+ quartz_source_image_t *source_img = info;
+ _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra);
+ free (source_img);
}
static cairo_status_t
@@ -932,11 +939,9 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
cairo_surface_t *source,
CGImageRef *image_out)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_surface_type_t stype = cairo_surface_get_type (source);
- cairo_image_surface_t *isurf;
- CGImageRef image;
- void *image_extra;
+ cairo_status_t status;
+ quartz_source_image_t *source_img;
+ cairo_surface_type_t stype = source->backend->type;
if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source;
@@ -958,43 +963,39 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
}
}
- if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
- status = _cairo_surface_acquire_source_image (source,
- &isurf, &image_extra);
- if (status)
- return status;
- } else {
- isurf = (cairo_image_surface_t *) source;
+ source_img = malloc (sizeof (quartz_source_image_t));
+ if (source_img == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ source_img->surface = source;
+
+ status = _cairo_surface_acquire_source_image (source_img->surface, &source_img->image_out, &source_img->image_extra);
+ if (status) {
+ free (source_img);
+ return status;
}
- if (isurf->width == 0 || isurf->height == 0) {
+ if (source_img->image_out->width == 0 || source_img->image_out->height == 0) {
*image_out = NULL;
+ DataProviderReleaseCallback (source_img,
+ source_img->image_out->data,
+ source_img->image_out->height * source_img->image_out->stride);
} else {
- cairo_image_surface_t *isurf_snap = NULL;
-
- isurf_snap = (cairo_image_surface_t*)
- _cairo_surface_snapshot (&isurf->base);
- if (isurf_snap->base.status)
- return isurf_snap->base.status;
-
- image = _cairo_quartz_create_cgimage (isurf_snap->format,
- isurf_snap->width,
- isurf_snap->height,
- isurf_snap->stride,
- isurf_snap->data,
- TRUE,
- NULL,
- DataProviderReleaseCallback,
- isurf_snap);
-
- *image_out = image;
- if (image == NULL)
+ *image_out = _cairo_quartz_create_cgimage (source_img->image_out->format,
+ source_img->image_out->width,
+ source_img->image_out->height,
+ source_img->image_out->stride,
+ source_img->image_out->data,
+ TRUE,
+ NULL,
+ DataProviderReleaseCallback,
+ source_img);
+
+ /* TODO: differentiate memory error and unsupported surface type */
+ if (*image_out == NULL)
status = CAIRO_INT_STATUS_UNSUPPORTED;
}
- if (&isurf->base != source)
- _cairo_surface_release_source_image (source, isurf, image_extra);
-
return status;
}
commit 7aba47e9d87bf09a5fa7e41a3c76c775f28b08f3
Author: Andrea Canciani <ranma42 at gmail.com>
Date: Mon Jan 25 15:09:51 2010 +0100
[quartz] Silence compiler warnings
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index bbfff37..a7a94b4 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -182,14 +182,14 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
CGImageRef image = NULL;
CGDataProviderRef dataProvider = NULL;
CGColorSpaceRef colorSpace = colorSpaceOverride;
- CGBitmapInfo bitinfo;
+ CGBitmapInfo bitinfo = kCGBitmapByteOrder32Host;
int bitsPerComponent, bitsPerPixel;
switch (format) {
case CAIRO_FORMAT_ARGB32:
if (colorSpace == NULL)
colorSpace = CGColorSpaceCreateDeviceRGB();
- bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+ bitinfo |= kCGImageAlphaPremultipliedFirst;
bitsPerComponent = 8;
bitsPerPixel = 32;
break;
@@ -197,7 +197,7 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
case CAIRO_FORMAT_RGB24:
if (colorSpace == NULL)
colorSpace = CGColorSpaceCreateDeviceRGB();
- bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+ bitinfo |= kCGImageAlphaNoneSkipFirst;
bitsPerComponent = 8;
bitsPerPixel = 32;
break;
@@ -302,7 +302,7 @@ _cairo_quartz_verify_surface_size(int width, int height)
typedef struct _quartz_stroke {
CGContextRef cgContext;
- cairo_matrix_t *ctm_inverse;
+ const cairo_matrix_t *ctm_inverse;
} quartz_stroke_t;
/* cairo path -> execute in context */
@@ -864,8 +864,8 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
dy = fabs (mend.y - mstart.y);
if (dx > 1e-6) {
- x_rep_start = (int) ceil(MIN(mstart.x, mend.x) / dx);
- x_rep_end = (int) ceil((surface->extents.width - MAX(mstart.x, mend.x)) / dx);
+ x_rep_start = ceil(MIN(mstart.x, mend.x) / dx);
+ x_rep_end = ceil((surface->extents.width - MAX(mstart.x, mend.x)) / dx);
if (mend.x < mstart.x) {
int swap = x_rep_end;
@@ -875,8 +875,8 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
}
if (dy > 1e-6) {
- y_rep_start = (int) ceil(MIN(mstart.y, mend.y) / dy);
- y_rep_end = (int) ceil((surface->extents.width - MAX(mstart.y, mend.y)) / dy);
+ y_rep_start = ceil(MIN(mstart.y, mend.y) / dy);
+ y_rep_end = ceil((surface->extents.width - MAX(mstart.y, mend.y)) / dy);
if (mend.y < mstart.y) {
int swap = y_rep_end;
More information about the cairo-commit
mailing list