Add CAIRO_STATUS_INVALID_CONTENT, CAIRO_STATUS_INVALID_FORMAT, and CAIRO_STATUS_INVALID_VISUAL.

Change functions to return type of void:
cairo_scaled_font_extents cairo_surface_finish
Add new functions to query object status:
cairo_scaled_font_status cairo_surface_status
Implementation of new error handling scheme for cairo_surface_t and cairo_scaled_font_t.
Track change in return value of cairo_surface_finish.
This commit is contained in:
Carl Worth 2005-07-27 15:39:34 +00:00
parent c884c4c541
commit 2b5d9c8e00
26 changed files with 995 additions and 465 deletions

View file

@ -1,3 +1,45 @@
2005-07-26 Carl Worth <cworth@cworth.org>
* src/cairo.h: Add CAIRO_STATUS_INVALID_CONTENT,
CAIRO_STATUS_INVALID_FORMAT, and CAIRO_STATUS_INVALID_VISUAL.
Change functions to return type of void:
cairo_scaled_font_extents
cairo_surface_finish
Add new functions to query object status:
cairo_scaled_font_status
cairo_surface_status
* doc/public/tmpl/cairo.sgml:
* src/cairo-array.c:
* src/cairo-atsui-font.c:
* src/cairo-font.c:
* src/cairo-ft-font.c:
* src/cairo-glitz-surface.c:
* src/cairo-gstate.c:
* src/cairo-image-surface.c:
* src/cairo-meta-surface.c:
* src/cairo-path-data.c:
* src/cairo-pattern.c:
* src/cairo-pdf-surface.c:
* src/cairo-png.c:
* src/cairo-ps-surface.c:
* src/cairo-quartz-surface.c:
* src/cairo-surface.c:
* src/cairo-win32-font.c:
* src/cairo-win32-surface.c:
* src/cairo-xcb-surface.c:
* src/cairo-xlib-surface.c:
* src/cairo.c:
* src/cairoint.h: Implementation of new error handling scheme for
cairo_surface_t and cairo_scaled_font_t.
* test/surface-finish-twice.c: Track change in return value of
cairo_surface_finish.
2005-07-27 Owen Taylor <otaylor@redhat.com>
* src/cairo-xlib-surface.c (_cairo_xlib_surface_get_font_options):

View file

@ -59,6 +59,7 @@ cairo_surface_t
</para>
@surface:
<!-- # Unused Parameters # -->
@Returns:

View file

@ -994,6 +994,9 @@ Drawing contexts.
@CAIRO_STATUS_SURFACE_FINISHED:
@CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
@CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
@CAIRO_STATUS_INVALID_CONTENT:
@CAIRO_STATUS_INVALID_FORMAT:
@CAIRO_STATUS_INVALID_VISUAL:
<!-- ##### FUNCTION cairo_status ##### -->
<para>

View file

@ -198,6 +198,11 @@ _cairo_user_data_array_get_data (cairo_user_data_array_t *array,
int i, num_slots;
cairo_user_data_slot_t *slots;
/* We allow this to support degenerate objects such as
* cairo_image_surface_nil. */
if (array == NULL)
return NULL;
num_slots = array->num_elements;
slots = (cairo_user_data_slot_t *) array->elements;
for (i = 0; i < num_slots; i++) {

View file

@ -68,7 +68,6 @@ typedef struct cairo_ATSUI_glyph_path_callback_info_t {
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend;
static CGAffineTransform
CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
{
@ -77,7 +76,6 @@ CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
0, 0);
}
static ATSUStyle
CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale)
{
@ -691,7 +689,6 @@ _cairo_atsui_font_glyph_path(void *abstract_font,
return CAIRO_STATUS_SUCCESS;
}
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
_cairo_atsui_font_create,
_cairo_atsui_font_destroy_font,

View file

@ -421,6 +421,56 @@ _cairo_simple_font_face_create (const char *family,
/* cairo_scaled_font_t */
const cairo_scaled_font_t _cairo_scaled_font_nil = {
CAIRO_STATUS_NO_MEMORY, /* status */
-1, /* ref_count */
{ 1., 0., 0., 1., 0, 0}, /* font_matrix */
{ 1., 0., 0., 1., 0, 0}, /* ctm */
{ 1., 0., 0., 1., 0, 0}, /* scale */
NULL, /* font_face */
CAIRO_SCALED_FONT_BACKEND_DEFAULT,
};
/**
* _cairo_scaled_font_set_error:
* @scaled_font: a scaled_font
* @status: a status value indicating an error, (eg. not
* CAIRO_STATUS_SUCCESS)
*
* Sets scaled_font->status to @status and calls _cairo_error;
*
* All assignments of an error status to scaled_font->status should happen
* through _cairo_scaled_font_set_error() or else _cairo_error() should be
* called immediately after the assignment.
*
* The purpose of this function is to allow the user to set a
* breakpoint in _cairo_error() to generate a stack trace for when the
* user causes cairo to detect an error.
**/
void
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
cairo_status_t status)
{
scaled_font->status = status;
_cairo_error (status);
}
/**
* cairo_scaled_font_status:
* @surface: a #cairo_scaled_font_t
*
* Checks whether an error has previously occurred for this
* scaled_font.
*
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NULL_POINTER.
**/
cairo_status_t
cairo_scaled_font_status (cairo_scaled_font_t *scaled_font)
{
return scaled_font->status;
}
/* Here we keep a cache from cairo_font_face_t/matrix/ctm => cairo_scaled_font_t.
*
* The implementation is messy because we want
@ -750,7 +800,8 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
cache = _get_outer_font_cache ();
if (cache == NULL) {
_unlock_global_font_cache ();
return NULL;
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
}
status = _cairo_cache_lookup (cache, &key, (void **) &entry, NULL);
@ -758,8 +809,10 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
cairo_scaled_font_reference (entry->scaled_font);
_unlock_global_font_cache ();
if (status)
return NULL;
if (status) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
}
return entry->scaled_font;
}
@ -770,6 +823,8 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
const cairo_matrix_t *ctm,
const cairo_scaled_font_backend_t *backend)
{
scaled_font->status = CAIRO_STATUS_SUCCESS;
scaled_font->font_matrix = *font_matrix;
scaled_font->ctm = *ctm;
cairo_matrix_multiply (&scaled_font->scale, &scaled_font->font_matrix, &scaled_font->ctm);
@ -784,6 +839,9 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
cairo_glyph_t **glyphs,
int *num_glyphs)
{
if (scaled_font->status)
return scaled_font->status;
return scaled_font->backend->text_to_glyphs (scaled_font, utf8, glyphs, num_glyphs);
}
@ -793,6 +851,9 @@ _cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_text_extents_t *extents)
{
if (scaled_font->status)
return scaled_font->status;
return scaled_font->backend->glyph_extents (scaled_font, glyphs, num_glyphs, extents);
}
@ -803,6 +864,9 @@ _cairo_scaled_font_glyph_bbox (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_box_t *bbox)
{
if (scaled_font->status)
return scaled_font->status;
return scaled_font->backend->glyph_bbox (scaled_font, glyphs, num_glyphs, bbox);
}
@ -822,6 +886,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
{
cairo_status_t status;
if (scaled_font->status)
return scaled_font->status;
status = _cairo_surface_show_glyphs (scaled_font, operator, pattern,
surface,
source_x, source_y,
@ -846,20 +913,31 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_path_fixed_t *path)
{
if (scaled_font->status)
return scaled_font->status;
return scaled_font->backend->glyph_path (scaled_font, glyphs, num_glyphs, path);
}
void
cairo_status_t
_cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t *scaled_font,
cairo_glyph_cache_key_t *key)
{
if (scaled_font->status)
return scaled_font->status;
scaled_font->backend->get_glyph_cache_key (scaled_font, key);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents)
{
if (scaled_font->status)
return scaled_font->status;
return scaled_font->backend->font_extents (scaled_font, extents);
}
@ -913,6 +991,9 @@ cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font)
if (scaled_font == NULL)
return;
if (scaled_font->ref_count == (unsigned int)-1)
return;
scaled_font->ref_count++;
}
@ -933,6 +1014,9 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
if (scaled_font == NULL)
return;
if (scaled_font->ref_count == (unsigned int)-1)
return;
if (--(scaled_font->ref_count) > 0)
return;
@ -966,17 +1050,23 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
* Return value: %CAIRO_STATUS_SUCCESS on success. Otherwise, an
* error such as %CAIRO_STATUS_NO_MEMORY.
**/
cairo_status_t
void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents)
{
cairo_int_status_t status;
double font_scale_x, font_scale_y;
if (scaled_font->status) {
_cairo_scaled_font_set_error (scaled_font, scaled_font->status);
return;
}
status = _cairo_scaled_font_font_extents (scaled_font, extents);
if (status)
return status;
if (status) {
_cairo_scaled_font_set_error (scaled_font, status);
return;
}
_cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
&font_scale_x, &font_scale_y,
@ -992,8 +1082,6 @@ cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
extents->height *= font_scale_y;
extents->max_x_advance *= font_scale_x;
extents->max_y_advance *= font_scale_y;
return status;
}
/**
@ -1020,6 +1108,11 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
double x_pos = 0.0, y_pos = 0.0;
int set = 0;
if (scaled_font->status) {
_cairo_scaled_font_set_error (scaled_font, scaled_font->status);
return;
}
if (!num_glyphs)
{
extents->x_bearing = 0.0;

View file

@ -88,7 +88,6 @@ typedef struct {
* just create a one-off version with a permanent face value.
*/
typedef struct _ft_font_face ft_font_face_t;
typedef struct {
@ -796,10 +795,9 @@ _get_bitmap_surface (cairo_image_glyph_cache_entry_t *val,
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
if (val->image == NULL) {
if (val->image->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
return val->image->base.status;
}
if (subpixel)
@ -1063,8 +1061,8 @@ _transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val)
/* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
width = (width + 3) & ~3;
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
if (!image)
return CAIRO_STATUS_NO_MEMORY;
if (image->status)
return image->status;
/* Initialize it to empty
*/
@ -1380,7 +1378,7 @@ _ft_scaled_font_create (ft_unscaled_font_t *unscaled,
f = malloc (sizeof(cairo_ft_scaled_font_t));
if (f == NULL)
return NULL;
return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
f->unscaled = unscaled;
_cairo_unscaled_font_reference (&unscaled->base);
@ -1875,7 +1873,7 @@ _cairo_ft_scaled_font_show_glyphs (void *abstract_font,
static int
_move_to (FT_Vector *to, void *closure)
_move_to (const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
@ -1890,7 +1888,7 @@ _move_to (FT_Vector *to, void *closure)
}
static int
_line_to (FT_Vector *to, void *closure)
_line_to (const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
@ -1904,7 +1902,7 @@ _line_to (FT_Vector *to, void *closure)
}
static int
_conic_to (FT_Vector *control, FT_Vector *to, void *closure)
_conic_to (const FT_Vector *control, const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
@ -1937,7 +1935,8 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
}
static int
_cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closure)
_cubic_to (const FT_Vector *control1, const FT_Vector *control2,
const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x0, y0;
@ -2351,7 +2350,9 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face,
* implemented, so this function cannot be currently safely used in a
* threaded application.)
* Return value: The #FT_Face object for @font, scaled appropriately.
* Return value: The #FT_Face object for @font, scaled appropriately,
* or %NULL if @scaled_font is in an error state (see
* cairo_scaled_font_status()) or there is insufficient memory.
**/
FT_Face
cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
@ -2359,9 +2360,14 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
FT_Face face;
face = _ft_unscaled_font_lock_face (scaled_font->unscaled);
if (!face)
if (scaled_font->base.status)
return NULL;
face = _ft_unscaled_font_lock_face (scaled_font->unscaled);
if (face == NULL) {
_cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
}
_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
@ -2383,6 +2389,9 @@ cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
{
cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
if (scaled_font->base.status)
return;
_ft_unscaled_font_unlock_face (scaled_font->unscaled);
}

View file

@ -83,12 +83,16 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
gformat = glitz_find_standard_format (drawable,
_glitz_format_from_content (content));
if (!gformat)
return NULL;
if (!gformat) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = glitz_surface_create (drawable, gformat, width, height, 0, NULL);
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
crsurface = cairo_glitz_surface_create (surface);
@ -206,11 +210,10 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
&format,
width, height,
pf.bytes_per_line);
if (!image)
if (image->base.status)
{
free (pixels);
return CAIRO_STATUS_NO_MEMORY;
return image->base.status;
}
_cairo_image_surface_assume_ownership_of_data (image);
@ -341,6 +344,9 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
cairo_glitz_surface_t *surface = abstract_surface;
cairo_glitz_surface_t *clone;
if (surface->base.status)
return surface->base.status;
if (src->backend == surface->base.backend)
{
*clone_out = src;
@ -357,8 +363,8 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
_cairo_glitz_surface_create_similar (surface, content,
image_src->width,
image_src->height);
if (!clone)
return CAIRO_STATUS_NO_MEMORY;
if (clone->base.status)
return clone->base.status;
_cairo_glitz_surface_set_image (clone, image_src, 0, 0);
@ -570,11 +576,11 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_COLOR_ALPHA,
gradient->n_stops, 1);
if (!src)
if (src->base.status)
{
glitz_buffer_destroy (buffer);
free (data);
return CAIRO_STATUS_NO_MEMORY;
return src->base.status;
}
for (i = 0; i < gradient->n_stops; i++)
@ -900,8 +906,8 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
(cairo_color_t *) color);
if (!src)
return CAIRO_STATUS_NO_MEMORY;
if (src->base.status)
return src->base.status;
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
@ -951,6 +957,9 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
cairo_int_status_t status;
unsigned short alpha;
if (dst->base.status)
return dst->base.status;
if (op == CAIRO_OPERATOR_SATURATE)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1002,13 +1011,13 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
_cairo_glitz_surface_create_similar (&dst->base,
CAIRO_CONTENT_ALPHA,
2, 1);
if (!mask)
if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
return CAIRO_INT_STATUS_UNSUPPORTED;
return mask->base.status;
}
color.red = color.green = color.blue = color.alpha = 0xffff;
@ -1097,11 +1106,11 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
CAIRO_FORMAT_A8,
width, height,
-stride);
if (!image)
if (image->base.status)
{
cairo_surface_destroy (&src->base);
free (data);
return CAIRO_STATUS_NO_MEMORY;
return image->base.status;
}
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@ -1111,12 +1120,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_ALPHA,
width, height);
if (!mask)
if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
free (data);
cairo_surface_destroy (&image->base);
return CAIRO_STATUS_NO_MEMORY;
return mask->base.status;
}
_cairo_glitz_surface_set_image (mask, image, 0, 0);
@ -1694,7 +1703,7 @@ _cairo_glitz_get_glyph_cache (cairo_glitz_surface_t *surface)
GLYPH_CACHE_TEXTURE_SIZE,
GLYPH_CACHE_TEXTURE_SIZE,
0, NULL);
if (!cache->surface)
if (cache->surface == NULL)
{
free (cache);
return NULL;
@ -1898,7 +1907,9 @@ _cairo_glitz_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
goto UNLOCK;
}
_cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
if (status)
goto UNLOCK;
for (i = 0; i < num_glyphs; i++)
{
@ -2123,12 +2134,14 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
{
cairo_glitz_surface_t *crsurface;
if (!surface)
return NULL;
if (surface == NULL)
return _cairo_surface_create_in_error (CAIRO_STATUS_NULL_POINTER);
crsurface = malloc (sizeof (cairo_glitz_surface_t));
if (crsurface == NULL)
return NULL;
if (crsurface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend);

View file

@ -282,8 +282,8 @@ _cairo_gstate_begin_group (cairo_gstate_t *gstate)
return CAIRO_STATUS_NO_MEMORY;
gstate->target = cairo_surface_create (gstate->dpy);
if (gstate->target == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (gstate->target->status)
return gstate->target->status;
_cairo_surface_set_drawableWH (gstate->target, pix, width, height);
@ -904,12 +904,15 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
*/
cairo_surface_t *intermediate;
if (gstate->clip.surface->status)
return gstate->clip.surface->status;
intermediate = cairo_surface_create_similar (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents.width,
extents.height);
if (intermediate == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (intermediate->status)
return intermediate->status;
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
mask, NULL, intermediate,
@ -1244,13 +1247,16 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate,
translate_traps (traps, -extents->x, -extents->y);
if (gstate->clip.surface->status)
return gstate->clip.surface->status;
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents->width,
extents->height,
CAIRO_COLOR_TRANSPARENT);
if (intermediate == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (intermediate->status)
return intermediate->status;
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
@ -1720,13 +1726,16 @@ _cairo_gstate_intersect_clip_mask (cairo_gstate_t *gstate,
if (gstate->clip.surface != NULL)
_cairo_rectangle_intersect (&surface_rect, &gstate->clip.surface_rect);
if (gstate->target->status)
return gstate->target->status;
surface = _cairo_surface_create_similar_solid (gstate->target,
CAIRO_CONTENT_ALPHA,
surface_rect.width,
surface_rect.height,
CAIRO_COLOR_WHITE);
if (surface == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (surface->status)
return surface->status;
/* Render the new clipping path into the new mask surface. */
@ -2025,7 +2034,9 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
if (status)
return status;
return cairo_scaled_font_extents (gstate->scaled_font, extents);
cairo_scaled_font_extents (gstate->scaled_font, extents);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
@ -2156,13 +2167,18 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
goto BAIL1;
}
if (gstate->clip.surface->status) {
status = gstate->clip.surface->status;
goto BAIL1;
}
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents.width,
extents.height,
CAIRO_COLOR_TRANSPARENT);
if (intermediate == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
if (intermediate->status) {
status = intermediate->status;
goto BAIL1;
}

View file

@ -36,8 +36,6 @@
#include "cairoint.h"
static const cairo_surface_backend_t cairo_image_surface_backend;
static int
_cairo_format_bpp (cairo_format_t format)
{
@ -53,15 +51,17 @@ _cairo_format_bpp (cairo_format_t format)
}
}
static cairo_image_surface_t *
static cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format)
{
cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_image_surface_backend);
@ -76,17 +76,17 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
surface->stride = pixman_image_get_stride (pixman_image);
surface->depth = pixman_image_get_depth (pixman_image);
return surface;
return &surface->base;
}
cairo_image_surface_t *
cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
cairo_format_masks_t *format,
int width,
int height,
int stride)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
@ -96,16 +96,20 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
format->green_mask,
format->blue_mask);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height, format->bpp, stride);
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
(cairo_format_t)-1);
@ -152,28 +156,31 @@ cairo_image_surface_create (cairo_format_t format,
int width,
int height)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
/* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_FORMAT_VALID (format))
return NULL;
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create (pixman_format, width, height);
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
return surface;
}
/**
@ -205,17 +212,18 @@ cairo_image_surface_create_for_data (unsigned char *data,
int height,
int stride)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
/* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_FORMAT_VALID (format))
return NULL;
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height,
@ -224,12 +232,14 @@ cairo_image_surface_create_for_data (unsigned char *data,
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
return surface;
}
/**
@ -303,9 +313,7 @@ _cairo_image_surface_create_similar (void *abstract_src,
int width,
int height)
{
/* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_CONTENT_VALID (content))
return NULL;
assert (CAIRO_CONTENT_VALID (content));
return cairo_image_surface_create (_cairo_format_from_content (content),
width, height);
@ -724,15 +732,15 @@ _cairo_image_abstract_surface_get_extents (void *abstract_surface,
*
* Checks if a surface is an #cairo_image_surface_t
*
* Return value: True if the surface is an image surface
* Return value: TRUE if the surface is an image surface
**/
int
cairo_bool_t
_cairo_surface_is_image (cairo_surface_t *surface)
{
return surface->backend == &cairo_image_surface_backend;
}
static const cairo_surface_backend_t cairo_image_surface_backend = {
const cairo_surface_backend_t cairo_image_surface_backend = {
_cairo_image_surface_create_similar,
_cairo_image_abstract_surface_finish,
_cairo_image_surface_acquire_source_image,

View file

@ -53,8 +53,10 @@ _cairo_meta_surface_create (double width, double height)
cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t));
if (meta == NULL)
return NULL;
if (meta == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
meta->width = width;
meta->height = height;

View file

@ -460,6 +460,8 @@ _cairo_path_data_create_in_error (cairo_status_t status)
path->data = NULL;
path->num_data = 0;
_cairo_error (status);
return path;
}

View file

@ -96,6 +96,31 @@ static const cairo_radial_pattern_t cairo_radial_pattern_nil = {
1.0, 1.0, /* radius0, radius1 */
};
/**
* _cairo_pattern_set_error:
* @pattern: a pattern
* @status: a status value indicating an error, (eg. not
* CAIRO_STATUS_SUCCESS)
*
* Sets pattern->status to @status and calls _cairo_error;
*
* All assignments of an error status to pattern->status should happen
* through _cairo_pattern_set_error() or else _cairo_error() should be
* called immediately after the assignment.
*
* The purpose of this function is to allow the user to set a
* breakpoint in _cairo_error() to generate a stack trace for when the
* user causes cairo to detect an error.
**/
static void
_cairo_pattern_set_error (cairo_pattern_t *pattern,
cairo_status_t status)
{
pattern->status = status;
_cairo_error (status);
}
static void
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
{
@ -127,10 +152,13 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
*dst = *src;
}
if (other->base.status)
_cairo_pattern_set_error (&pattern->base, other->base.status);
if (other->n_stops)
{
pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
if (!pattern->stops) {
if (pattern->stops == NULL) {
if (other->base.type == CAIRO_PATTERN_LINEAR)
_cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base);
else
@ -289,7 +317,7 @@ _cairo_pattern_create_in_error (cairo_status_t status)
_cairo_pattern_init_solid (pattern, CAIRO_COLOR_BLACK);
pattern->base.status = status;
_cairo_pattern_set_error (&pattern->base, status);
return &pattern->base;
}
@ -317,6 +345,7 @@ _cairo_pattern_create_in_error (cairo_status_t status)
cairo_pattern_t *
cairo_pattern_create_rgb (double red, double green, double blue)
{
cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@ -325,7 +354,11 @@ cairo_pattern_create_rgb (double red, double green, double blue)
_cairo_color_init_rgb (&color, red, green, blue);
return _cairo_pattern_create_solid (&color);
pattern = _cairo_pattern_create_solid (&color);
if (pattern->status)
_cairo_pattern_set_error (pattern, pattern->status);
return pattern;
}
/**
@ -353,6 +386,7 @@ cairo_pattern_t *
cairo_pattern_create_rgba (double red, double green, double blue,
double alpha)
{
cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@ -362,7 +396,11 @@ cairo_pattern_create_rgba (double red, double green, double blue,
_cairo_color_init_rgba (&color, red, green, blue, alpha);
return _cairo_pattern_create_solid (&color);
pattern = _cairo_pattern_create_solid (&color);
if (pattern->status)
_cairo_pattern_set_error (pattern, pattern->status);
return pattern;
}
/**
@ -386,8 +424,10 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
cairo_surface_pattern_t *pattern;
pattern = malloc (sizeof (cairo_surface_pattern_t));
if (pattern == NULL)
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&cairo_surface_pattern_nil.base;
}
_cairo_pattern_init_for_surface (pattern, surface);
@ -422,8 +462,10 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
cairo_linear_pattern_t *pattern;
pattern = malloc (sizeof (cairo_linear_pattern_t));
if (pattern == NULL)
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_linear_pattern_nil.base;
}
_cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
@ -461,8 +503,10 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
cairo_radial_pattern_t *pattern;
pattern = malloc (sizeof (cairo_radial_pattern_t));
if (pattern == NULL)
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_radial_pattern_nil.base;
}
_cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
@ -541,7 +585,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
new_stops = realloc (pattern->stops,
pattern->n_stops * sizeof (cairo_color_stop_t));
if (new_stops == NULL) {
pattern->base.status = CAIRO_STATUS_NO_MEMORY;
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
@ -568,7 +612,7 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@ -599,7 +643,7 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@ -619,8 +663,10 @@ void
cairo_pattern_set_matrix (cairo_pattern_t *pattern,
const cairo_matrix_t *matrix)
{
if (pattern->status)
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
pattern->matrix = *matrix;
}
@ -634,8 +680,10 @@ cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
void
cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
{
if (pattern->status)
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
pattern->filter = filter;
}
@ -649,8 +697,10 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
{
if (pattern->status)
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
pattern->extend = extend;
}
@ -1164,7 +1214,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
data = malloc (width * height * 4);
if (!data)
if (data == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
@ -1228,9 +1278,8 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
&pattern->color);
if (*out == NULL)
return CAIRO_STATUS_NO_MEMORY;
if ((*out)->status)
return (*out)->status;
attribs->x_offset = attribs->y_offset = 0;
cairo_matrix_init_identity (&attribs->matrix);

View file

@ -290,8 +290,10 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *stream,
cairo_surface_t *surface;
document = _cairo_pdf_document_create (stream, width, height);
if (document == NULL)
return NULL;
if (document == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_pdf_surface_create_for_document (document, width, height);
@ -310,8 +312,10 @@ cairo_pdf_surface_create_for_stream (cairo_write_func_t write,
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write, closure);
if (stream == NULL)
return NULL;
if (stream == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}
@ -324,8 +328,10 @@ cairo_pdf_surface_create (const char *filename,
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_file (filename);
if (stream == NULL)
return NULL;
if (stream == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}
@ -349,8 +355,10 @@ _cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document,
cairo_pdf_surface_t *surface;
surface = malloc (sizeof (cairo_pdf_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);

View file

@ -36,6 +36,7 @@
*/
#include <png.h>
#include <errno.h>
#include "cairoint.h"
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
@ -315,19 +316,15 @@ static cairo_surface_t *
read_png (png_rw_ptr read_func,
void *closure)
{
cairo_surface_t *surface;
png_byte *data;
cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil;
png_byte *data = NULL;
int i;
png_struct *png;
png_struct *png = NULL;
png_info *info;
png_uint_32 png_width, png_height, stride;
int depth, color_type, interlace;
unsigned int pixel_size;
png_byte **row_pointers;
surface = NULL;
data = NULL;
row_pointers = NULL;
png_byte **row_pointers = NULL;
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
@ -335,7 +332,7 @@ read_png (png_rw_ptr read_func,
NULL,
NULL);
if (png == NULL)
return NULL;
goto BAIL;
info = png_create_info_struct (png);
if (info == NULL)
@ -402,13 +399,22 @@ read_png (png_rw_ptr read_func,
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
png_width, png_height, stride);
if (surface->status)
goto BAIL;
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
data = NULL;
BAIL:
free (row_pointers);
free (data);
png_destroy_read_struct (&png, &info, NULL);
if (row_pointers)
free (row_pointers);
if (data)
free (data);
if (png)
png_destroy_read_struct (&png, &info, NULL);
if (surface == &_cairo_surface_nil)
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return surface;
}
@ -441,8 +447,12 @@ cairo_image_surface_create_from_png (const char *filename)
cairo_surface_t *surface;
fp = fopen (filename, "rb");
if (fp == NULL)
return NULL;
if (fp == NULL) {
if (errno == ENOMEM)
return (cairo_surface_t*) &_cairo_surface_nil;
else
return _cairo_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
}
surface = read_png (stdio_read_func, fp);

View file

@ -89,8 +89,10 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
cairo_ps_surface_t *surface;
surface = malloc (sizeof (cairo_ps_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_ps_surface_backend);
@ -103,9 +105,10 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->current_page = _cairo_meta_surface_create (width,
height);
if (surface->current_page == NULL) {
if (surface->current_page->status) {
free (surface);
return NULL;
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_array_init (&surface->pages, sizeof (cairo_surface_t *));
@ -122,8 +125,10 @@ cairo_ps_surface_create (const char *filename,
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_file (filename);
if (stream == NULL)
return NULL;
if (stream == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points,
@ -139,23 +144,16 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, closure);
if (stream == NULL)
return NULL;
if (stream == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points,
height_in_points);
}
static cairo_surface_t *
_cairo_ps_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height)
{
return NULL;
}
static cairo_status_t
_cairo_ps_surface_finish (void *abstract_surface)
{
@ -316,8 +314,8 @@ _cairo_ps_surface_show_page (void *abstract_surface)
_cairo_array_append (&surface->pages, &surface->current_page, 1);
surface->current_page = _cairo_meta_surface_create (surface->width,
surface->height);
if (surface->current_page == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (surface->current_page->status)
return surface->current_page->status;
return CAIRO_STATUS_SUCCESS;
}
@ -453,7 +451,7 @@ _cairo_ps_surface_fill_path (cairo_operator_t operator,
}
static const cairo_surface_backend_t cairo_ps_surface_backend = {
_cairo_ps_surface_create_similar,
NULL, /* create_similar */
_cairo_ps_surface_finish,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
@ -652,7 +650,7 @@ emit_image (cairo_ps_surface_t *surface,
cairo_image_surface_t *image,
cairo_matrix_t *matrix)
{
cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
cairo_status_t status;
unsigned char *rgb, *compressed;
unsigned long rgb_size, compressed_size;
cairo_surface_t *opaque;
@ -663,13 +661,18 @@ emit_image (cairo_ps_surface_t *surface,
/* PostScript can not represent the alpha channel, so we blend the
current image over a white RGB surface to eliminate it. */
if (image->base.status)
return image->base.status;
opaque = _cairo_surface_create_similar_solid (&image->base,
CAIRO_CONTENT_COLOR,
image->width,
image->height,
CAIRO_COLOR_WHITE);
if (opaque == NULL)
if (opaque->status) {
status = opaque->status;
goto bail0;
}
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
@ -687,8 +690,10 @@ emit_image (cairo_ps_surface_t *surface,
rgb_size = 3 * image->width * image->height;
rgb = malloc (rgb_size);
if (rgb == NULL)
if (rgb == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto bail1;
}
i = 0;
for (y = 0; y < image->height; y++) {
@ -701,8 +706,10 @@ emit_image (cairo_ps_surface_t *surface,
}
compressed = compress_dup (rgb, rgb_size, &compressed_size);
if (compressed == NULL)
if (compressed == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto bail2;
}
/* matrix transforms from user space to image space. We need to
* transform from device space to image space to compensate for
@ -1242,8 +1249,8 @@ _ps_output_render_fallbacks (cairo_surface_t *surface,
height = ps_output->parent->height * ps_output->parent->y_dpi / 72;
image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
if (image == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (image->status)
return image->status;
status = _cairo_surface_fill_rectangle (image,
CAIRO_OPERATOR_SOURCE,
@ -1278,8 +1285,10 @@ _ps_output_surface_create (cairo_ps_surface_t *parent)
ps_output_surface_t *ps_output;
ps_output = malloc (sizeof (ps_output_surface_t));
if (ps_output == NULL)
return NULL;
if (ps_output == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&ps_output->base, &ps_output_backend);
ps_output->parent = parent;
@ -1301,8 +1310,8 @@ _cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
page_number);
ps_output = _ps_output_surface_create (surface);
if (ps_output == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (ps_output->status)
return ps_output->status;
status = _cairo_meta_surface_replay (page, ps_output);

View file

@ -58,15 +58,6 @@ ImageDataReleaseFunc(void *info, const void *data, size_t size)
}
}
static cairo_surface_t *
_cairo_quartz_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height)
{
return NULL;
}
static cairo_status_t
_cairo_quartz_surface_finish(void *abstract_surface)
{
@ -209,7 +200,7 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
}
static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
_cairo_quartz_surface_create_similar,
NULL, /* create_similar */
_cairo_quartz_surface_finish,
_cairo_quartz_surface_acquire_source_image,
NULL, /* release_source_image */
@ -234,8 +225,10 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
cairo_quartz_surface_t *surface;
surface = malloc(sizeof(cairo_quartz_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);

View file

@ -40,6 +40,65 @@
#include "cairoint.h"
#include "cairo-gstate-private.h"
const cairo_surface_t _cairo_surface_nil = {
&cairo_image_surface_backend, /* backend */
-1, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
FALSE, /* finished */
{ 0, /* size */
0, /* num_elements */
0, /* element_size */
NULL, /* elements */
}, /* user_data */
0.0, /* device_x_offset */
0.0, /* device_y_offset */
0, /* next_clip_serial */
0 /* current_clip_serial */
};
/**
* _cairo_surface_set_error:
* @surface: a surface
* @status: a status value indicating an error, (eg. not
* CAIRO_STATUS_SUCCESS)
*
* Sets surface->status to @status and calls _cairo_error;
*
* All assignments of an error status to surface->status should happen
* through _cairo_surface_set_error() or else _cairo_error() should be
* called immediately after the assignment.
*
* The purpose of this function is to allow the user to set a
* breakpoint in _cairo_error() to generate a stack trace for when the
* user causes cairo to detect an error.
**/
static void
_cairo_surface_set_error (cairo_surface_t *surface,
cairo_status_t status)
{
surface->status = status;
_cairo_error (status);
}
/**
* cairo_surface_status:
* @surface: a #cairo_surface_t
*
* Checks whether an error has previously occurred for this
* surface.
*
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
* %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
* %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALUE_FORMAT, or
* %CAIRO_STATUS_INVALID_VISUAL.
**/
cairo_status_t
cairo_surface_status (cairo_surface_t *surface)
{
return surface->status;
}
void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend)
@ -47,6 +106,7 @@ _cairo_surface_init (cairo_surface_t *surface,
surface->backend = backend;
surface->ref_count = 1;
surface->status = CAIRO_STATUS_SUCCESS;
surface->finished = FALSE;
_cairo_user_data_array_init (&surface->user_data);
@ -64,10 +124,15 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
int width,
int height)
{
if (other == NULL)
return NULL;
cairo_format_t format = _cairo_format_from_content (content);
return other->backend->create_similar (other, content, width, height);
if (other->status)
return _cairo_surface_create_in_error (other->status);
if (other->backend->create_similar)
return other->backend->create_similar (other, content, width, height);
else
return cairo_image_surface_create (format, width, height);
}
/**
@ -91,12 +156,11 @@ cairo_surface_create_similar (cairo_surface_t *other,
int width,
int height)
{
if (other == NULL)
return NULL;
if (other->status)
return _cairo_surface_create_in_error (other->status);
/* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_CONTENT_VALID (content))
return NULL;
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
return _cairo_surface_create_similar_solid (other, content,
width, height,
@ -112,25 +176,40 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
{
cairo_status_t status;
cairo_surface_t *surface;
cairo_format_t format = _cairo_format_from_content (content);
surface = _cairo_surface_create_similar_scratch (other, content,
width, height);
if (surface == NULL)
surface = cairo_image_surface_create (format, width, height);
status = _cairo_surface_fill_rectangle (surface,
CAIRO_OPERATOR_SOURCE, color,
0, 0, width, height);
if (status) {
cairo_surface_destroy (surface);
return NULL;
return _cairo_surface_create_in_error (status);
}
return surface;
}
cairo_surface_t *
_cairo_surface_create_in_error (cairo_status_t status)
{
cairo_surface_t *surface;
/* The format here is totally arbitrary. */
surface = cairo_image_surface_create_for_data (NULL, CAIRO_FORMAT_ARGB32,
0, 0, 0);
/* If that failed, then there are bigger problems than the error
* we want to stash here. */
if (surface->ref_count == -1)
return surface;
_cairo_surface_set_error (surface, status);
return surface;
}
cairo_clip_mode_t
_cairo_surface_get_clip_mode (cairo_surface_t *surface)
{
@ -148,6 +227,9 @@ cairo_surface_reference (cairo_surface_t *surface)
if (surface == NULL)
return;
if (surface->ref_count == (unsigned int)-1)
return;
surface->ref_count++;
}
@ -157,6 +239,9 @@ cairo_surface_destroy (cairo_surface_t *surface)
if (surface == NULL)
return;
if (surface->ref_count == (unsigned int)-1)
return;
surface->ref_count--;
if (surface->ref_count)
return;
@ -178,36 +263,37 @@ slim_hidden_def(cairo_surface_destroy);
* that cairo will no longer access the drawable, which can be freed.
* After calling cairo_surface_finish() the only valid operations on a
* surface are getting and setting user data and referencing and
* destroying it. Further drawing the the surface will not affect the
* surface but set the surface status to
* CAIRO_STATUS_SURFACE_FINISHED.
* destroying it. Further drawing to the surface will not affect the
* surface but will instead trigger a CAIRO_STATUS_SURFACE_FINISHED
* error.
*
* When the last call to cairo_surface_destroy() decreases the
* reference count to zero, cairo will call cairo_surface_finish() if
* it hasn't been called already, before freeing the resources
* associated with the surface.
*
* Return value: CAIRO_STATUS_SUCCESS if the surface was finished
* successfully, otherwise CAIRO_STATUS_NO_MEMORY or
* CAIRO_STATUS_WRITE_ERROR.
**/
cairo_status_t
void
cairo_surface_finish (cairo_surface_t *surface)
{
cairo_status_t status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
if (surface->finished) {
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
return;
}
if (surface->backend->finish) {
status = surface->backend->finish (surface);
if (status)
return status;
if (surface->backend->finish == NULL) {
surface->finished = TRUE;
return;
}
status = surface->backend->finish (surface);
if (status) {
_cairo_surface_set_error (surface, status);
return;
}
surface->finished = TRUE;
return CAIRO_STATUS_SUCCESS;
}
/**
@ -272,14 +358,10 @@ void
cairo_surface_get_font_options (cairo_surface_t *surface,
cairo_font_options_t *options)
{
if (!surface->finished && surface->backend->get_font_options) {
surface->backend->get_font_options (surface, options);
} else {
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
_cairo_font_options_init_default (options);
}
}
@ -306,6 +388,16 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
double x_offset,
double y_offset)
{
if (surface->status) {
_cairo_surface_set_error (surface, surface->status);
return;
}
if (surface->finished) {
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
return;
}
surface->device_x_offset = x_offset;
surface->device_y_offset = y_offset;
}
@ -480,7 +572,17 @@ typedef struct {
void *image_extra;
} fallback_state_t;
static cairo_status_t
/**
* _fallback_init:
*
* Acquire destination image surface needed for an image-based
* fallback.
*
* Return value: CAIRO_INT_STATUS_NOTHING_TO_DO if the extents are not
* visible, CAIRO_STATUS_SUCCESS if some portion is visible and all
* went well, or some error status otherwise.
**/
static cairo_int_status_t
_fallback_init (fallback_state_t *state,
cairo_surface_t *dst,
int x,
@ -488,6 +590,8 @@ _fallback_init (fallback_state_t *state,
int width,
int height)
{
cairo_status_t status;
state->extents.x = x;
state->extents.y = y;
state->extents.width = width;
@ -495,15 +599,29 @@ _fallback_init (fallback_state_t *state,
state->dst = dst;
return _cairo_surface_acquire_dest_image (dst, &state->extents,
&state->image, &state->image_rect, &state->image_extra);
status = _cairo_surface_acquire_dest_image (dst, &state->extents,
&state->image, &state->image_rect,
&state->image_extra);
if (status)
return status;
/* XXX: This NULL value tucked away in state->image is a rather
* ugly interface. Cleaner would be to push the
* CAIRO_INT_STATUS_NOTHING_TO_DO value down into
* _cairo_surface_acquire_dest_image and its backend
* counterparts. */
if (state->image == NULL)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
return CAIRO_STATUS_SUCCESS;
}
static void
_fallback_cleanup (fallback_state_t *state)
_fallback_fini (fallback_state_t *state)
{
_cairo_surface_release_dest_image (state->dst, &state->extents,
state->image, &state->image_rect, state->image_extra);
state->image, &state->image_rect,
state->image_extra);
}
static cairo_status_t
@ -524,18 +642,20 @@ _fallback_composite (cairo_operator_t operator,
cairo_status_t status;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
if (status || !state.image)
if (status) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
}
state.image->base.backend->composite (operator, src, mask,
&state.image->base,
src_x, src_y, mask_x, mask_y,
dst_x - state.image_rect.x,
dst_y - state.image_rect.y,
width, height);
status = state.image->base.backend->composite (operator, src, mask,
&state.image->base,
src_x, src_y, mask_x, mask_y,
dst_x - state.image_rect.x,
dst_y - state.image_rect.y,
width, height);
_fallback_fini (&state);
_fallback_cleanup (&state);
return status;
}
@ -555,6 +675,9 @@ _cairo_surface_composite (cairo_operator_t operator,
{
cairo_int_status_t status;
if (dst->status)
return dst->status;
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -588,6 +711,9 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
{
cairo_rectangle_t rect;
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -636,16 +762,19 @@ _fallback_fill_rectangles (cairo_surface_t *surface,
}
status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1);
if (status || !state.image)
if (status) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
}
/* If the fetched image isn't at 0,0, we need to offset the rectangles */
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
offset_rects = malloc (sizeof (cairo_rectangle_t) * num_rects);
if (!offset_rects) {
if (offset_rects == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
goto DONE;
}
for (i = 0; i < num_rects; i++) {
@ -658,15 +787,15 @@ _fallback_fill_rectangles (cairo_surface_t *surface,
rects = offset_rects;
}
state.image->base.backend->fill_rectangles (&state.image->base, operator, color,
rects, num_rects);
status = state.image->base.backend->fill_rectangles (&state.image->base,
operator, color,
rects, num_rects);
if (offset_rects)
free (offset_rects);
free (offset_rects);
DONE:
_fallback_fini (&state);
FAIL:
_fallback_cleanup (&state);
return status;
}
@ -679,6 +808,9 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
{
cairo_int_status_t status;
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -705,11 +837,11 @@ _cairo_surface_fill_path (cairo_operator_t operator,
cairo_fill_rule_t fill_rule,
double tolerance)
{
if (dst->backend->fill_path)
return dst->backend->fill_path (operator, pattern, dst, path,
fill_rule, tolerance);
else
return CAIRO_INT_STATUS_UNSUPPORTED;
if (dst->backend->fill_path)
return dst->backend->fill_path (operator, pattern, dst, path,
fill_rule, tolerance);
else
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -732,8 +864,11 @@ _fallback_composite_trapezoids (cairo_operator_t operator,
int i;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
if (status || !state.image)
if (status) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
}
/* If the destination image isn't at 0,0, we need to offset the trapezoids */
@ -745,7 +880,7 @@ _fallback_composite_trapezoids (cairo_operator_t operator,
offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
if (!offset_traps) {
status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
goto DONE;
}
for (i = 0; i < num_traps; i++) {
@ -773,13 +908,12 @@ _fallback_composite_trapezoids (cairo_operator_t operator,
if (offset_traps)
free (offset_traps);
FAIL:
_fallback_cleanup (&state);
DONE:
_fallback_fini (&state);
return status;
}
cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
cairo_pattern_t *pattern,
@ -795,6 +929,9 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator,
{
cairo_int_status_t status;
if (dst->status)
return dst->status;
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -809,16 +946,19 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator,
return status;
}
return _fallback_composite_trapezoids (operator, pattern, dst,
src_x, src_y,
dst_x, dst_y,
width, height,
traps, num_traps);
return _fallback_composite_trapezoids (operator, pattern, dst,
src_x, src_y,
dst_x, dst_y,
width, height,
traps, num_traps);
}
cairo_status_t
_cairo_surface_copy_page (cairo_surface_t *surface)
{
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -826,12 +966,15 @@ _cairo_surface_copy_page (cairo_surface_t *surface)
if (surface->backend->copy_page == NULL)
return CAIRO_STATUS_SUCCESS;
return surface->backend->copy_page (surface);
return surface->backend->copy_page (surface);
}
cairo_status_t
_cairo_surface_show_page (cairo_surface_t *surface)
{
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -861,15 +1004,19 @@ _cairo_surface_get_current_clip_serial (cairo_surface_t *surface)
* _cairo_surface_allocate_clip_serial:
* @surface: the #cairo_surface_t to allocate a serial number from
*
* Each surface has a separate set of clipping serial numbers,
* and this function allocates one from the specified surface.
* As zero is reserved for the special no-clipping case,
* this function will not return that.
* Each surface has a separate set of clipping serial numbers, and
* this function allocates one from the specified surface. As zero is
* reserved for the special no-clipping case, this function will not
* return that except for an in-error surface, (ie. surface->status !=
* CAIRO_STATUS_SUCCESS).
*/
unsigned int
_cairo_surface_allocate_clip_serial (cairo_surface_t *surface)
{
unsigned int serial;
if (surface->status)
return 0;
if ((serial = ++(surface->next_clip_serial)) == 0)
serial = ++(surface->next_clip_serial);
@ -890,6 +1037,9 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
{
cairo_status_t status;
if (surface->status)
return status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -909,6 +1059,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
@ -927,12 +1078,16 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
pixman_region16_t *region,
unsigned int serial)
{
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
assert (surface->backend->set_clip_region != NULL);
surface->current_clip_serial = serial;
return surface->backend->set_clip_region (surface, region);
}
@ -942,6 +1097,9 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
cairo_fill_rule_t fill_rule,
double tolerance)
{
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -972,7 +1130,6 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface,
clip_path->tolerance);
}
/**
* _cairo_surface_set_clip_path:
* @surface: the #cairo_surface_t to reset the clip on
@ -991,6 +1148,9 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface,
{
cairo_status_t status;
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -1031,6 +1191,9 @@ cairo_status_t
_cairo_surface_get_extents (cairo_surface_t *surface,
cairo_rectangle_t *rectangle)
{
if (surface->status)
return surface->status;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@ -1053,6 +1216,9 @@ _cairo_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
{
cairo_status_t status;
if (dst->status)
return dst->status;
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;

View file

@ -223,8 +223,10 @@ _win32_scaled_font_create (LOGFONTW *logfont,
cairo_matrix_t scale;
f = malloc (sizeof(cairo_win32_scaled_font_t));
if (f == NULL)
return NULL;
if (f == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_scaled_font_nil;
}
f->logfont = *logfont;
f->options = *options;
@ -1009,7 +1011,7 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,
image24->width, image24->height);
if (!image8)
if (image8->status)
return NULL;
for (i = 0; i < image24->height; i++) {
@ -1082,8 +1084,8 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
RECT r;
tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
if (!tmp_surface)
return CAIRO_STATUS_NO_MEMORY;
if (tmp_surface->status)
return tmp_surface->status;
r.left = 0;
r.top = 0;
@ -1387,6 +1389,11 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,
HFONT old_hfont = NULL;
int old_mode;
if (scaled_font->status) {
_cairo_scaled_font_set_error (scaled_font, scaled_font->status);
return scaled_font->status;
}
hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
if (!hfont)
return CAIRO_STATUS_NO_MEMORY;

View file

@ -243,23 +243,29 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
int width,
int height)
{
cairo_status_t status;
cairo_win32_surface_t *surface;
char *bits;
int rowstride;
surface = malloc (sizeof (cairo_win32_surface_t));
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
if (_create_dc_and_bitmap (surface, original_dc, format,
width, height,
&bits, &rowstride) != CAIRO_STATUS_SUCCESS)
status = _create_dc_and_bitmap (surface, original_dc, format,
width, height,
&bits, &rowstride);
if (status)
goto FAIL;
surface->image = cairo_image_surface_create_for_data (bits, format,
width, height, rowstride);
if (!surface->image)
if (surface->image->status) {
status = surface->image->status;
goto FAIL;
}
surface->format = format;
@ -283,9 +289,13 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
}
if (surface)
free (surface);
return NULL;
if (status == CAIRO_STATUS_NO_MEMORY) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
} else {
return _cairo_surface_create_in_error (status);
}
}
static cairo_surface_t *
@ -359,8 +369,8 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
content,
width,
height);
if (!local)
return CAIRO_STATUS_NO_MEMORY;
if (local->status)
return local->status;
if (!BitBlt (local->dc,
0, 0,
@ -892,12 +902,16 @@ cairo_win32_surface_create (HDC hdc)
*/
if (GetClipBox (hdc, &rect) == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
return NULL;
/* XXX: Can we make a more reasonable guess at the error cause here? */
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
surface = malloc (sizeof (cairo_win32_surface_t));
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
surface->image = NULL;
surface->format = CAIRO_FORMAT_RGB24;

View file

@ -503,6 +503,8 @@ _get_image_surface (cairo_xcb_surface_t *surface,
x2 - x1,
y2 - y1,
bytes_per_line);
if (image->base.status)
goto FAIL;
} else {
/*
* XXX This can't work. We must convert the data to one of the
@ -510,12 +512,14 @@ _get_image_surface (cairo_xcb_surface_t *surface,
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
image = _cairo_image_surface_create_with_masks (data,
&masks,
x2 - x1,
y2 - y1,
bytes_per_line);
image = (cairo_image_surface_t *)
_cairo_image_surface_create_with_masks (data,
&masks,
x2 - x1,
y2 - y1,
bytes_per_line);
if (image->base.status)
goto FAIL;
}
/* Let the surface take ownership of the data */
@ -523,6 +527,10 @@ _get_image_surface (cairo_xcb_surface_t *surface,
*image_out = image;
return CAIRO_STATUS_SUCCESS;
FAIL:
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
static void
@ -637,12 +645,15 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
} else if (_cairo_surface_is_image (src)) {
cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
cairo_content_t content = _cairo_content_from_format (image_src->format);
if (surface->base.status)
return surface->base.status;
clone = (cairo_xcb_surface_t *)
_cairo_xcb_surface_create_similar (surface, content,
image_src->width, image_src->height);
if (clone == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (clone->base.status)
return clone->base.status;
_draw_image_surface (clone, image_src, 0, 0);
@ -1062,8 +1073,10 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
cairo_xcb_surface_t *surface;
surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_xcb_surface_backend);

View file

@ -430,11 +430,14 @@ _get_image_surface (cairo_xlib_surface_t *surface,
*/
if (_CAIRO_MASK_FORMAT (&masks, &format))
{
image = (cairo_image_surface_t *) cairo_image_surface_create_for_data ((unsigned char *) ximage->data,
format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
image = (cairo_image_surface_t*)
cairo_image_surface_create_for_data ((unsigned char *) ximage->data,
format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
if (image->base.status)
goto FAIL;
}
else
{
@ -444,11 +447,14 @@ _get_image_surface (cairo_xlib_surface_t *surface,
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
image = _cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
&masks,
ximage->width,
ximage->height,
ximage->bytes_per_line);
image = (cairo_image_surface_t*)
_cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
&masks,
ximage->width,
ximage->height,
ximage->bytes_per_line);
if (image->base.status)
goto FAIL;
}
/* Let the surface take ownership of the data */
@ -458,6 +464,10 @@ _get_image_surface (cairo_xlib_surface_t *surface,
*image_out = image;
return CAIRO_STATUS_SUCCESS;
FAIL:
XDestroyImage (ximage);
return CAIRO_STATUS_NO_MEMORY;
}
static void
@ -658,8 +668,8 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
clone = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_similar (surface, content,
image_src->width, image_src->height);
if (clone == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (clone->base.status)
return clone->base.status;
_draw_image_surface (clone, image_src, 0, 0);
@ -1400,12 +1410,16 @@ _cairo_xlib_surface_create_internal (Display *dpy,
cairo_xlib_screen_info_t *screen_info;
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
if (!screen_info)
return NULL;
if (screen_info == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend);
@ -1534,7 +1548,7 @@ cairo_xlib_surface_create (Display *dpy,
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
if (screen == NULL)
return NULL;
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_VISUAL);
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
visual, NULL, width, height, 0);
@ -2376,7 +2390,9 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
/* Work out the index size to use. */
elt_size = 8;
_cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
if (status)
goto UNLOCK;
for (i = 0; i < num_glyphs; ++i) {
key.index = glyphs[i].index;

File diff suppressed because it is too large Load diff

View file

@ -154,6 +154,9 @@ typedef struct _cairo_user_data_key {
* @CAIRO_STATUS_SURFACE_FINISHED: target surface has been finished
* @CAIRO_STATUS_SURFACE_TYPE_MISMATCH: the surface type is not appropriate for the operation
* @CAIRO_STATUS_PATTERN_TYPE_MISMATCH: the pattern type is not appropriate for the operation
* @CAIRO_STATUS_INVALID_CONTENT: invalid value for an input cairo_content_t
* @CAIRO_STATUS_INVALID_FORMAT: invalid value for an input cairo_format_t
* @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual*
*
* #cairo_status_t is used to indicate errors that can occur when
* using Cairo. In some cases it is returned directly by functions.
@ -175,7 +178,10 @@ typedef enum _cairo_status {
CAIRO_STATUS_WRITE_ERROR,
CAIRO_STATUS_SURFACE_FINISHED,
CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
CAIRO_STATUS_PATTERN_TYPE_MISMATCH
CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
CAIRO_STATUS_INVALID_CONTENT,
CAIRO_STATUS_INVALID_FORMAT,
CAIRO_STATUS_INVALID_VISUAL
} cairo_status_t;
/**
@ -894,6 +900,9 @@ void
cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
cairo_status_t
cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents);
@ -1102,6 +1111,9 @@ void
cairo_surface_destroy (cairo_surface_t *surface);
cairo_status_t
cairo_surface_status (cairo_surface_t *surface);
void
cairo_surface_finish (cairo_surface_t *surface);
#if CAIRO_HAS_PNG_FUNCTIONS

View file

@ -229,7 +229,8 @@ typedef struct _cairo_rectangle {
offset */
typedef enum cairo_int_status {
CAIRO_INT_STATUS_DEGENERATE = 1000,
CAIRO_INT_STATUS_UNSUPPORTED
CAIRO_INT_STATUS_UNSUPPORTED,
CAIRO_INT_STATUS_NOTHING_TO_DO
} cairo_int_status_t;
typedef enum cairo_direction {
@ -458,6 +459,7 @@ struct _cairo_unscaled_font {
};
struct _cairo_scaled_font {
cairo_status_t status;
int ref_count;
cairo_matrix_t font_matrix; /* font space => user space */
cairo_matrix_t ctm; /* user space => device space */
@ -794,6 +796,7 @@ struct _cairo_surface {
const cairo_surface_backend_t *backend;
unsigned int ref_count;
cairo_status_t status;
cairo_bool_t finished;
cairo_user_data_array_t user_data;
@ -833,6 +836,8 @@ struct _cairo_image_surface {
pixman_image_t *pixman_image;
};
extern const cairo_surface_backend_t cairo_image_surface_backend;
/* XXX: Right now, the cairo_color structure puts unpremultiplied
color in the doubles and premultiplied color in the shorts. Yes,
this is crazy insane, (but at least we don't export this
@ -1293,6 +1298,10 @@ _cairo_color_get_rgba_premultiplied (cairo_color_t *color,
/* cairo-font.c */
cairo_private void
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
cairo_status_t status);
cairo_private void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend);
@ -1302,6 +1311,8 @@ _cairo_simple_font_face_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
extern const cairo_scaled_font_t _cairo_scaled_font_nil;
cairo_private void
_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
const cairo_matrix_t *font_matrix,
@ -1360,7 +1371,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_path_fixed_t *path);
cairo_private void
cairo_private cairo_status_t
_cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t *scaled_font,
cairo_glyph_cache_key_t *key);
@ -1468,6 +1479,9 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
cairo_traps_t *traps);
/* cairo-surface.c */
extern const cairo_surface_t _cairo_surface_nil;
cairo_private cairo_surface_t *
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
cairo_content_t content,
@ -1481,6 +1495,9 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
int height,
const cairo_color_t *color);
cairo_surface_t *
_cairo_surface_create_in_error (cairo_status_t status);
cairo_private void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend);
@ -1627,7 +1644,7 @@ _cairo_format_from_content (cairo_content_t content);
cairo_private cairo_content_t
_cairo_content_from_format (cairo_format_t format);
cairo_private cairo_image_surface_t *
cairo_private cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
cairo_format_masks_t *format,
int width,
@ -1641,7 +1658,7 @@ cairo_private cairo_int_status_t
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
pixman_region16_t *region);
cairo_private int
cairo_private cairo_bool_t
_cairo_surface_is_image (cairo_surface_t *surface);
/* cairo_pen.c */
@ -1909,6 +1926,9 @@ _cairo_output_stream_get_status (cairo_output_stream_t *stream);
cairo_output_stream_t *
_cairo_output_stream_create_for_file (const char *filename);
cairo_private void
_cairo_error (cairo_status_t status);
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(cairo_get_current_point)

View file

@ -55,12 +55,13 @@ draw (cairo_t *cr, int width, int height)
cairo_status_t status;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
status = cairo_surface_finish (surface);
if (status != CAIRO_STATUS_SUCCESS)
cairo_surface_finish (surface);
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
return CAIRO_TEST_FAILURE;
status = cairo_surface_finish (surface);
if (status != CAIRO_STATUS_SURFACE_FINISHED)
cairo_surface_finish (surface);
if (cairo_surface_status (surface) != CAIRO_STATUS_SURFACE_FINISHED)
return CAIRO_TEST_FAILURE;
cairo_surface_destroy (surface);