b=413878, upgrade cairo/pixman to latest git

This commit is contained in:
vladimir@pobox.com 2008-01-25 16:25:15 -08:00
Родитель 2859f9cdda
Коммит 8dca786a0a
64 изменённых файлов: 1525 добавлений и 1413 удалений

Просмотреть файл

@ -7,8 +7,8 @@ http://www.cairographics.org/.
VERSIONS: VERSIONS:
cairo (1.5.x - 1.5.4-141-g57c2b75) cairo (1.5.x - 1.5.6-65-gea9afec)
pixman (0.9.x - pixman-0.9.6-25-ge0af592) pixman (0.9.x - pixman-0.9.6-34-g787cc57)
glitz 0.5.2 (cvs - 2006-01-10) glitz 0.5.2 (cvs - 2006-01-10)
***** NOTE FOR VISUAL C++ 6.0 ***** ***** NOTE FOR VISUAL C++ 6.0 *****
@ -28,5 +28,3 @@ nonfatal-assertions.patch: Make assertions non-fatal
endian.patch: include cairo-platform.h for endian macros endian.patch: include cairo-platform.h for endian macros
fixed-24-8.patch: Switch fixed point mode from 16.16 to 24.8 fixed-24-8.patch: Switch fixed point mode from 16.16 to 24.8
mac-runtime-linkage.patch: Do some runtime dlsym lookups instead of relying on gcc attributes

Просмотреть файл

@ -95,7 +95,6 @@ CSRCS = \
cairo-matrix.c \ cairo-matrix.c \
cairo-meta-surface.c \ cairo-meta-surface.c \
cairo-mutex.c \ cairo-mutex.c \
cairo-operator.c \
cairo-output-stream.c \ cairo-output-stream.c \
cairo-paginated-surface.c \ cairo-paginated-surface.c \
cairo-path.c \ cairo-path.c \

Просмотреть файл

@ -228,7 +228,7 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
surface->current_clip.width = surface->width; surface->current_clip.width = surface->width;
surface->current_clip.height = surface->height; surface->current_clip.height = surface->height;
} else { } else {
_cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2); _cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2, tolerance);
extent.x = floor (x1); extent.x = floor (x1);
extent.y = floor (y1); extent.y = floor (y1);
@ -600,7 +600,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface = malloc (sizeof (cairo_analysis_surface_t)); surface = malloc (sizeof (cairo_analysis_surface_t));
if (surface == NULL) if (surface == NULL)
goto FAIL; return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
/* I believe the content type here is truly arbitrary. I'm quite /* I believe the content type here is truly arbitrary. I'm quite
* sure nothing will ever use this value. */ * sure nothing will ever use this value. */
@ -625,9 +625,6 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface->current_clip.height = height; surface->current_clip.height = height;
return &surface->base; return &surface->base;
FAIL:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
} }
cairo_region_t * cairo_region_t *

Просмотреть файл

@ -396,8 +396,7 @@ _cairo_user_data_array_get_data (cairo_user_data_array_t *array,
int i, num_slots; int i, num_slots;
cairo_user_data_slot_t *slots; cairo_user_data_slot_t *slots;
/* We allow this to support degenerate objects such as /* We allow this to support degenerate objects such as cairo_surface_nil. */
* cairo_image_surface_nil. */
if (array == NULL) if (array == NULL)
return NULL; return NULL;

Просмотреть файл

@ -113,6 +113,9 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
{ {
cairo_base85_stream_t *stream; cairo_base85_stream_t *stream;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_base85_stream_t)); stream = malloc (sizeof (cairo_base85_stream_t));
if (stream == NULL) { if (stream == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);

Просмотреть файл

@ -721,7 +721,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
cairo_box_int_t *boxes; cairo_box_int_t *boxes;
int i; int i;
if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS) if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes))
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
if (n_boxes) { if (n_boxes) {

Просмотреть файл

@ -111,6 +111,16 @@ CAIRO_BEGIN_DECLS
#define __attribute__(x) #define __attribute__(x)
#endif #endif
#ifdef _MSC_VER
#define snprintf _snprintf
#undef inline
#define inline __inline
#endif
#ifdef __STRICT_ANSI__
#undef inline
#define inline __inline__
#endif
CAIRO_END_DECLS CAIRO_END_DECLS

Просмотреть файл

@ -117,11 +117,8 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)
{ {
cairo_deflate_stream_t *stream; cairo_deflate_stream_t *stream;
if (output->status) { if (output->status)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_output_stream_create_in_error (output->status);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
stream = malloc (sizeof (cairo_deflate_stream_t)); stream = malloc (sizeof (cairo_deflate_stream_t));
if (stream == NULL) { if (stream == NULL) {

Просмотреть файл

@ -37,39 +37,11 @@
#ifndef CAIRO_FIXED_PRIVATE_H #ifndef CAIRO_FIXED_PRIVATE_H
#define CAIRO_FIXED_PRIVATE_H #define CAIRO_FIXED_PRIVATE_H
#include "cairo-fixed-type-private.h"
#include "cairo-wideint-private.h" #include "cairo-wideint-private.h"
/* /* Implementation */
* Fixed-point configuration
*/
typedef int32_t cairo_fixed_16_16_t;
typedef cairo_int64_t cairo_fixed_32_32_t;
typedef cairo_int64_t cairo_fixed_48_16_t;
typedef cairo_int128_t cairo_fixed_64_64_t;
typedef cairo_int128_t cairo_fixed_96_32_t;
/* Eventually, we should allow changing this, but I think
* there are some assumptions in the tesselator about the
* size of a fixed type. For now, it must be 32.
*/
#define CAIRO_FIXED_BITS 32
/* The number of fractional bits. Changing this involves
* making sure that you compute a double-to-fixed magic number.
* (see below).
*/
#define CAIRO_FIXED_FRAC_BITS 8
/* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */
typedef int32_t cairo_fixed_t;
/* An unsigned type of the same size as cairo_fixed_t */
typedef uint32_t cairo_fixed_unsigned_t;
/*
* No configurable bits below this.
*/
#if (CAIRO_FIXED_BITS != 32) #if (CAIRO_FIXED_BITS != 32)
# error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type. # error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type.

Просмотреть файл

@ -0,0 +1,70 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* Cairo - a vector graphics library with display and print output
*
* Copyright © 2007 Mozilla Corporation
*
* 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 Mozilla Corporation
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
*/
#ifndef CAIRO_FIXED_TYPE_PRIVATE_H
#define CAIRO_FIXED_TYPE_PRIVATE_H
#include "cairo-wideint-type-private.h"
/*
* Fixed-point configuration
*/
typedef int32_t cairo_fixed_16_16_t;
typedef cairo_int64_t cairo_fixed_32_32_t;
typedef cairo_int64_t cairo_fixed_48_16_t;
typedef cairo_int128_t cairo_fixed_64_64_t;
typedef cairo_int128_t cairo_fixed_96_32_t;
/* Eventually, we should allow changing this, but I think
* there are some assumptions in the tesselator about the
* size of a fixed type. For now, it must be 32.
*/
#define CAIRO_FIXED_BITS 32
/* The number of fractional bits. Changing this involves
* making sure that you compute a double-to-fixed magic number.
* (see below).
*/
#define CAIRO_FIXED_FRAC_BITS 8
/* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */
typedef int32_t cairo_fixed_t;
/* An unsigned type of the same size as cairo_fixed_t */
typedef uint32_t cairo_fixed_unsigned_t;
#endif /* CAIRO_FIXED_TYPE_PRIVATE_H */

Просмотреть файл

@ -476,9 +476,11 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
if (font_face->base.status) if (font_face->base.status)
return font_face->base.status; return font_face->base.status;
status = cairo_font_options_status ((cairo_font_options_t *) options); if (options != NULL) {
if (status) status = cairo_font_options_status ((cairo_font_options_t *) options);
return status; if (status)
return status;
}
return _cairo_font_face_set_error (&font_face->base, return _cairo_font_face_set_error (&font_face->base,
backend->create_toy (font_face, backend->create_toy (font_face,

Просмотреть файл

@ -52,7 +52,7 @@ static const cairo_font_options_t _cairo_font_options_nil = {
void void
_cairo_font_options_init_default (cairo_font_options_t *options) _cairo_font_options_init_default (cairo_font_options_t *options)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
options->antialias = CAIRO_ANTIALIAS_DEFAULT; options->antialias = CAIRO_ANTIALIAS_DEFAULT;
@ -65,10 +65,13 @@ void
_cairo_font_options_init_copy (cairo_font_options_t *options, _cairo_font_options_init_copy (cairo_font_options_t *options,
const cairo_font_options_t *other) const cairo_font_options_t *other)
{ {
options->antialias = other->antialias; if (other != NULL) {
options->subpixel_order = other->subpixel_order; options->antialias = other->antialias;
options->hint_style = other->hint_style; options->subpixel_order = other->subpixel_order;
options->hint_metrics = other->hint_metrics; options->hint_style = other->hint_style;
options->hint_metrics = other->hint_metrics;
} else
_cairo_font_options_init_default (options);
} }
/** /**
@ -91,7 +94,7 @@ cairo_font_options_create (void)
options = malloc (sizeof (cairo_font_options_t)); options = malloc (sizeof (cairo_font_options_t));
if (!options) { if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_options_t *)&_cairo_font_options_nil; return (cairo_font_options_t *) &_cairo_font_options_nil;
} }
_cairo_font_options_init_default (options); _cairo_font_options_init_default (options);
@ -118,13 +121,16 @@ cairo_font_options_copy (const cairo_font_options_t *original)
{ {
cairo_font_options_t *options; cairo_font_options_t *options;
if (original == &_cairo_font_options_nil) if (original != NULL &&
return (cairo_font_options_t *)&_cairo_font_options_nil; cairo_font_options_status ((cairo_font_options_t *) original))
{
return (cairo_font_options_t *) &_cairo_font_options_nil;
}
options = malloc (sizeof (cairo_font_options_t)); options = malloc (sizeof (cairo_font_options_t));
if (!options) { if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_options_t *)&_cairo_font_options_nil; return (cairo_font_options_t *) &_cairo_font_options_nil;
} }
_cairo_font_options_init_copy (options, original); _cairo_font_options_init_copy (options, original);
@ -142,7 +148,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
void void
cairo_font_options_destroy (cairo_font_options_t *options) cairo_font_options_destroy (cairo_font_options_t *options)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
free (options); free (options);
@ -161,7 +167,9 @@ slim_hidden_def (cairo_font_options_destroy);
cairo_status_t cairo_status_t
cairo_font_options_status (cairo_font_options_t *options) cairo_font_options_status (cairo_font_options_t *options)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (options == NULL)
return CAIRO_STATUS_NULL_POINTER;
else if (options == (cairo_font_options_t *) &_cairo_font_options_nil)
return CAIRO_STATUS_NO_MEMORY; return CAIRO_STATUS_NO_MEMORY;
else else
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
@ -182,7 +190,11 @@ void
cairo_font_options_merge (cairo_font_options_t *options, cairo_font_options_merge (cairo_font_options_t *options,
const cairo_font_options_t *other) const cairo_font_options_t *other)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return;
/* A NULL other maps to the defaults and would not overwrite options */
if (cairo_font_options_status ((cairo_font_options_t *) other))
return; return;
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT) if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
@ -209,6 +221,14 @@ cairo_bool_t
cairo_font_options_equal (const cairo_font_options_t *options, cairo_font_options_equal (const cairo_font_options_t *options,
const cairo_font_options_t *other) const cairo_font_options_t *other)
{ {
if (options == NULL)
options = &_cairo_font_options_nil;
if (other == NULL)
other = &_cairo_font_options_nil;
if (options == other)
return TRUE;
return (options->antialias == other->antialias && return (options->antialias == other->antialias &&
options->subpixel_order == other->subpixel_order && options->subpixel_order == other->subpixel_order &&
options->hint_style == other->hint_style && options->hint_style == other->hint_style &&
@ -231,6 +251,9 @@ slim_hidden_def (cairo_font_options_equal);
unsigned long unsigned long
cairo_font_options_hash (const cairo_font_options_t *options) cairo_font_options_hash (const cairo_font_options_t *options)
{ {
if (options == NULL)
options = &_cairo_font_options_nil;
return ((options->antialias) | return ((options->antialias) |
(options->subpixel_order << 4) | (options->subpixel_order << 4) |
(options->hint_style << 8) | (options->hint_style << 8) |
@ -250,7 +273,7 @@ void
cairo_font_options_set_antialias (cairo_font_options_t *options, cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias) cairo_antialias_t antialias)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
options->antialias = antialias; options->antialias = antialias;
@ -268,6 +291,9 @@ slim_hidden_def (cairo_font_options_set_antialias);
cairo_antialias_t cairo_antialias_t
cairo_font_options_get_antialias (const cairo_font_options_t *options) cairo_font_options_get_antialias (const cairo_font_options_t *options)
{ {
if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_ANTIALIAS_DEFAULT;
return options->antialias; return options->antialias;
} }
@ -286,7 +312,7 @@ void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options, cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order) cairo_subpixel_order_t subpixel_order)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
options->subpixel_order = subpixel_order; options->subpixel_order = subpixel_order;
@ -305,6 +331,9 @@ slim_hidden_def (cairo_font_options_set_subpixel_order);
cairo_subpixel_order_t cairo_subpixel_order_t
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options) cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
{ {
if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_SUBPIXEL_ORDER_DEFAULT;
return options->subpixel_order; return options->subpixel_order;
} }
@ -322,7 +351,7 @@ void
cairo_font_options_set_hint_style (cairo_font_options_t *options, cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style) cairo_hint_style_t hint_style)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
options->hint_style = hint_style; options->hint_style = hint_style;
@ -341,6 +370,9 @@ slim_hidden_def (cairo_font_options_set_hint_style);
cairo_hint_style_t cairo_hint_style_t
cairo_font_options_get_hint_style (const cairo_font_options_t *options) cairo_font_options_get_hint_style (const cairo_font_options_t *options)
{ {
if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_HINT_STYLE_DEFAULT;
return options->hint_style; return options->hint_style;
} }
@ -358,7 +390,7 @@ void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options, cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics) cairo_hint_metrics_t hint_metrics)
{ {
if (options == (cairo_font_options_t *)&_cairo_font_options_nil) if (cairo_font_options_status (options))
return; return;
options->hint_metrics = hint_metrics; options->hint_metrics = hint_metrics;
@ -377,5 +409,8 @@ slim_hidden_def (cairo_font_options_set_hint_metrics);
cairo_hint_metrics_t cairo_hint_metrics_t
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options) cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
{ {
if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_HINT_METRICS_DEFAULT;
return options->hint_metrics; return options->hint_metrics;
} }

Просмотреть файл

@ -1365,7 +1365,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
if (!hinting) { if (!hinting) {
ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
} }
#endif /* FC_FHINT_STYLE */ #endif /* FC_HINT_STYLE */
} else { } else {
ft_options.base.antialias = CAIRO_ANTIALIAS_NONE; ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
} }
@ -1467,6 +1467,8 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
options->load_flags = load_flags | load_target; options->load_flags = load_flags | load_target;
options->extra_flags = other->extra_flags; options->extra_flags = other->extra_flags;
if (options->base.hint_metrics != CAIRO_HINT_METRICS_OFF)
options->extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
} }
static cairo_status_t static cairo_status_t
@ -1497,9 +1499,6 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
_cairo_unscaled_font_reference (&unscaled->base); _cairo_unscaled_font_reference (&unscaled->base);
scaled_font->unscaled = unscaled; scaled_font->unscaled = unscaled;
if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
_cairo_font_options_init_copy (&scaled_font->ft_options.base, options); _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
_cairo_ft_options_merge (&scaled_font->ft_options, &ft_options); _cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
@ -1648,7 +1647,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
cairo_matrix_multiply (&scale, font_matrix, ctm); cairo_matrix_multiply (&scale, font_matrix, ctm);
_compute_transform (&sf, &scale); _compute_transform (&sf, &scale);
if (! FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale)) { if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FREE_PATTERN; goto FREE_PATTERN;
} }
@ -1658,9 +1657,11 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
goto FREE_PATTERN; goto FREE_PATTERN;
} }
status = _cairo_ft_font_options_substitute (font_options, pattern); if (font_options != NULL) {
if (status) status = _cairo_ft_font_options_substitute (font_options, pattern);
goto FREE_PATTERN; if (status)
goto FREE_PATTERN;
}
FcDefaultSubstitute (pattern); FcDefaultSubstitute (pattern);
@ -2446,6 +2447,9 @@ void
cairo_ft_font_options_substitute (const cairo_font_options_t *options, cairo_ft_font_options_substitute (const cairo_font_options_t *options,
FcPattern *pattern) FcPattern *pattern)
{ {
if (cairo_font_options_status ((cairo_font_options_t *) options))
return;
_cairo_ft_font_options_substitute (options, pattern); _cairo_ft_font_options_substitute (options, pattern);
} }

Просмотреть файл

@ -88,20 +88,16 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
gformat = gformat =
glitz_find_standard_format (drawable, glitz_find_standard_format (drawable,
_glitz_format_from_content (content)); _glitz_format_from_content (content));
if (!gformat) { if (!gformat)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = glitz_surface_create (drawable, gformat, surface = glitz_surface_create (drawable, gformat,
width <= 0 ? 1 : width, width <= 0 ? 1 : width,
height <= 0 ? 1 : height, height <= 0 ? 1 : height,
0, NULL); 0, NULL);
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
crsurface = cairo_glitz_surface_create (surface); crsurface = cairo_glitz_surface_create (surface);
@ -150,36 +146,39 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
return FALSE; return FALSE;
} }
static glitz_box_t * static cairo_status_t
_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes) _cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, int *nboxes)
{ {
cairo_box_int_t *cboxes; cairo_box_int_t *cboxes;
glitz_box_t *gboxes; cairo_status_t status;
int n, i; int n, i;
if (_cairo_region_get_boxes (region, &n, &cboxes) != CAIRO_STATUS_SUCCESS) status = _cairo_region_get_boxes (region, &n, &cboxes);
return NULL; if (status)
return status;
*nboxes = n; if (n == 0) {
if (n == 0) status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL; goto done;
}
gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t)); *boxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
if (gboxes == NULL) { if (*boxes == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto done; goto done;
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
gboxes[i].x1 = cboxes[i].p1.x; (*boxes)[i].x1 = cboxes[i].p1.x;
gboxes[i].y1 = cboxes[i].p1.y; (*boxes)[i].y1 = cboxes[i].p1.y;
gboxes[i].x2 = cboxes[i].p2.x; (*boxes)[i].x2 = cboxes[i].p2.x;
gboxes[i].y2 = cboxes[i].p2.y; (*boxes)[i].y2 = cboxes[i].p2.y;
} }
*nboxes = n;
done: done:
_cairo_region_boxes_fini (region, cboxes); _cairo_region_boxes_fini (region, cboxes);
return gboxes; return status;
} }
static cairo_status_t static cairo_status_t
@ -296,12 +295,13 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
/* restore the clip, if any */ /* restore the clip, if any */
if (surface->has_clip) { if (surface->has_clip) {
glitz_box_t *box; glitz_box_t *box;
cairo_status_t status;
int n; int n;
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n); status = _cairo_glitz_get_boxes_from_region (&surface->clip, &box, &n);
if (box == NULL && n != 0) { if (status) {
free (pixels); free (pixels);
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
} }
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n); glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
@ -1467,11 +1467,11 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface,
return status; return status;
} }
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n); status = _cairo_glitz_get_boxes_from_region (&surface->clip, &box, &n);
if (box == NULL && n != 0) { if (status) {
_cairo_region_fini (&surface->clip); _cairo_region_fini (&surface->clip);
surface->has_clip = FALSE; surface->has_clip = FALSE;
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
} }
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n); glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
@ -2456,13 +2456,11 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
glitz_format_t *format; glitz_format_t *format;
if (surface == NULL) if (surface == NULL)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
crsurface = malloc (sizeof (cairo_glitz_surface_t)); crsurface = malloc (sizeof (cairo_glitz_surface_t));
if (crsurface == NULL) { if (crsurface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
format = glitz_surface_get_format (surface); format = glitz_surface_get_format (surface);
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend, _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,

Просмотреть файл

@ -818,6 +818,17 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate)
} }
*/ */
void
_cairo_gstate_path_extents (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2)
{
_cairo_path_fixed_bounds (path, x1, y1, x2, y2, gstate->tolerance);
_cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
}
static cairo_status_t static cairo_status_t
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
cairo_pattern_t *pattern, cairo_pattern_t *pattern,
@ -1365,7 +1376,7 @@ _cairo_gstate_set_font_options (cairo_gstate_t *gstate,
{ {
_cairo_gstate_unset_scaled_font (gstate); _cairo_gstate_unset_scaled_font (gstate);
gstate->font_options = *options; _cairo_font_options_init_copy (&gstate->font_options, options);
} }
void void

Просмотреть файл

@ -37,101 +37,6 @@
#include "cairoint.h" #include "cairoint.h"
static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
{
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
CAIRO_CONTENT_COLOR,
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_INVALID_FORMAT, /* status */
FALSE, /* finished */
{ 0, /* size */
0, /* num_elements */
0, /* element_size */
NULL, /* elements */
}, /* user_data */
{ 1.0, 0.0,
0.0, 1.0,
0.0, 0.0
}, /* device_transform */
{ 1.0, 0.0,
0.0, 1.0,
0.0, 0.0
}, /* device_transform_inverse */
0.0, /* x_resolution */
0.0, /* y_resolution */
0.0, /* x_fallback_resolution */
0.0, /* y_fallback_resolution */
NULL, /* clip */
0, /* next_clip_serial */
0, /* current_clip_serial */
FALSE, /* is_snapshot */
FALSE, /* has_font_options */
{ CAIRO_ANTIALIAS_DEFAULT,
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_METRICS_DEFAULT
} /* font_options */
}, /* base */
PIXMAN_a8r8g8b8, /* pixman_format */
CAIRO_FORMAT_ARGB32, /* format */
NULL, /* data */
FALSE, /* owns_data */
FALSE, /* has_clip */
0, /* width */
0, /* height */
0, /* stride */
0, /* depth */
NULL /* pixman_image */
};
static const cairo_image_surface_t _cairo_image_surface_nil_invalid_content = {
{
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
CAIRO_CONTENT_COLOR,
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_INVALID_CONTENT, /* status */
FALSE, /* finished */
{ 0, /* size */
0, /* num_elements */
0, /* element_size */
NULL, /* elements */
}, /* user_data */
{ 1.0, 0.0,
0.0, 1.0,
0.0, 0.0
}, /* device_transform */
{ 1.0, 0.0,
0.0, 1.0,
0.0, 0.0
}, /* device_transform_inverse */
0.0, /* x_resolution */
0.0, /* y_resolution */
0.0, /* x_fallback_resolution */
0.0, /* y_fallback_resolution */
NULL, /* clip */
0, /* next_clip_serial */
0, /* current_clip_serial */
FALSE, /* is_snapshot */
FALSE, /* has_font_options */
{ CAIRO_ANTIALIAS_DEFAULT,
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_METRICS_DEFAULT
} /* font_options */
}, /* base */
PIXMAN_a8r8g8b8, /* pixman_format */
CAIRO_FORMAT_ARGB32, /* format */
NULL, /* data */
FALSE, /* owns_data */
FALSE, /* has_clip */
0, /* width */
0, /* height */
0, /* stride */
0, /* depth */
NULL /* pixman_image */
};
static cairo_format_t static cairo_format_t
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format) _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
{ {
@ -213,10 +118,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_image_surface_t *surface; cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t)); surface = malloc (sizeof (cairo_image_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_image_surface_backend, _cairo_surface_init (&surface->base, &cairo_image_surface_backend,
_cairo_content_from_pixman_format (pixman_format)); _cairo_content_from_pixman_format (pixman_format));
@ -399,7 +302,7 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
static pixman_format_code_t static pixman_format_code_t
_cairo_format_to_pixman_format_code (cairo_format_t format) _cairo_format_to_pixman_format_code (cairo_format_t format)
{ {
int ret = 0; pixman_format_code_t ret;
switch (format) { switch (format) {
case CAIRO_FORMAT_A1: case CAIRO_FORMAT_A1:
ret = PIXMAN_a1; ret = PIXMAN_a1;
@ -415,7 +318,6 @@ _cairo_format_to_pixman_format_code (cairo_format_t format)
ret = PIXMAN_a8r8g8b8; ret = PIXMAN_a8r8g8b8;
break; break;
} }
assert (ret);
return ret; return ret;
} }
@ -432,16 +334,13 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data,
pixman_image = pixman_image_create_bits (pixman_format, width, height, pixman_image = pixman_image_create_bits (pixman_format, width, height,
(uint32_t *) data, stride); (uint32_t *) data, stride);
if (pixman_image == NULL) { if (pixman_image == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
pixman_format); pixman_format);
if (cairo_surface_status (surface)) { if (cairo_surface_status (surface))
pixman_image_unref (pixman_image); pixman_image_unref (pixman_image);
}
return surface; return surface;
} }
@ -473,10 +372,8 @@ cairo_image_surface_create (cairo_format_t format,
{ {
pixman_format_code_t pixman_format; pixman_format_code_t pixman_format;
if (! CAIRO_FORMAT_VALID (format)) { if (! CAIRO_FORMAT_VALID (format))
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
}
pixman_format = _cairo_format_to_pixman_format_code (format); pixman_format = _cairo_format_to_pixman_format_code (format);
@ -490,10 +387,8 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
int width, int width,
int height) int height)
{ {
if (! CAIRO_CONTENT_VALID (content)) { if (! CAIRO_CONTENT_VALID (content))
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
}
return cairo_image_surface_create (_cairo_format_from_content (content), return cairo_image_surface_create (_cairo_format_from_content (content),
width, height); width, height);
@ -541,10 +436,8 @@ cairo_image_surface_create_for_data (unsigned char *data,
/* XXX pixman does not support images with arbitrary strides and /* XXX pixman does not support images with arbitrary strides and
* attempting to create such surfaces will failure but we will interpret * attempting to create such surfaces will failure but we will interpret
* such failure as CAIRO_STATUS_NO_MEMORY. */ * such failure as CAIRO_STATUS_NO_MEMORY. */
if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0) { if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0)
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT); return _cairo_surface_create_in_error (_cairo_error(CAIRO_STATUS_INVALID_FORMAT));
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
}
pixman_format = _cairo_format_to_pixman_format_code (format); pixman_format = _cairo_format_to_pixman_format_code (format);
@ -560,10 +453,8 @@ _cairo_image_surface_create_for_data_with_content (unsigned char *data,
int height, int height,
int stride) int stride)
{ {
if (! CAIRO_CONTENT_VALID (content)) { if (! CAIRO_CONTENT_VALID (content))
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
}
return cairo_image_surface_create_for_data (data, return cairo_image_surface_create_for_data (data,
_cairo_format_from_content (content), _cairo_format_from_content (content),
@ -1191,7 +1082,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
case CAIRO_ANTIALIAS_NONE: case CAIRO_ANTIALIAS_NONE:
format = PIXMAN_a1; format = PIXMAN_a1;
ret = 1; ret = 1;
assert (ret);
mask_stride = ((width + 31) / 8) & ~0x03; mask_stride = ((width + 31) / 8) & ~0x03;
mask_bpp = 1; mask_bpp = 1;
break; break;
@ -1201,7 +1091,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
default: default:
format = PIXMAN_a8; format = PIXMAN_a8;
ret = 1; ret = 1;
assert (ret);
mask_stride = (width + 3) & ~3; mask_stride = (width + 3) & ~3;
mask_bpp = 8; mask_bpp = 8;
break; break;
@ -1382,7 +1271,7 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
if (status) { if (status) {
cairo_surface_destroy (&clone->base); cairo_surface_destroy (&clone->base);
return (cairo_image_surface_t *) &_cairo_surface_nil; return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
} }
return clone; return clone;

Просмотреть файл

@ -753,6 +753,10 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
*pixman_transform = pixman_identity_transform; *pixman_transform = pixman_identity_transform;
} }
else { else {
cairo_matrix_t inv = *matrix;
double x = 0, y = 0;
pixman_vector_t vector;
pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx); pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy); pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0); pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
@ -764,5 +768,36 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
pixman_transform->matrix[2][0] = 0; pixman_transform->matrix[2][0] = 0;
pixman_transform->matrix[2][1] = 0; pixman_transform->matrix[2][1] = 0;
pixman_transform->matrix[2][2] = 1 << 16; pixman_transform->matrix[2][2] = 1 << 16;
/* The conversion above breaks cairo's translation invariance:
* a translation of (a, b) in device space translates to
* a translation of (xx * a + xy * b, yx * a + yy * b)
* for cairo, while pixman uses rounded versions of xx ... yy.
* This error increases as a and b get larger.
*
* To compensate for this, we fix the point (0, 0) in pattern
* space and adjust pixman's transform to agree with cairo's at
* that point. */
/* Note: If we can't invert the transformation, skip the adjustment. */
if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
return;
/* find the device space coordinate that maps to (0, 0) */
cairo_matrix_transform_point (&inv, &x, &y);
/* transform the resulting device space coordinate back
* to the pattern space, using pixman's transform */
vector.vector[0] = _cairo_fixed_16_16_from_double (x);
vector.vector[1] = _cairo_fixed_16_16_from_double (y);
vector.vector[2] = 1 << 16;
if (!pixman_transform_point_3d (pixman_transform, &vector))
return;
/* Ideally, the vector should now be (0, 0). We can now compensate
* for the resulting error */
pixman_transform->matrix[0][2] -= vector.vector[0];
pixman_transform->matrix[1][2] -= vector.vector[1];
} }
} }

Просмотреть файл

@ -83,10 +83,8 @@ _cairo_meta_surface_create (cairo_content_t content,
cairo_meta_surface_t *meta; cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t)); meta = malloc (sizeof (cairo_meta_surface_t));
if (meta == NULL) { if (meta == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend, _cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
content); content);
@ -498,10 +496,8 @@ _cairo_meta_surface_snapshot (void *abstract_other)
cairo_meta_surface_t *meta; cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t)); meta = malloc (sizeof (cairo_meta_surface_t));
if (meta == NULL) { if (meta == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend, _cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
other->base.content); other->base.content);

Просмотреть файл

@ -1,119 +0,0 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2006 Keith Packard
* Copyright © 2006 Red Hat, Inc
*
* 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 University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Keith Packard <keithp@keithp.com>
*/
#include "cairoint.h"
/* The analysis here assumes destination alpha semantics (that is
* CAIRO_CONTENT_COLOR_ALPHA). More things can be considered opaque
* otherwise (CAIRO_CONTENT_COLOR) so we'll probably want to add a
* cairo_content_t parameter to this function
*
* We also need a definition of what "opaque" means. Is it, "does not
* requiring 'knowing' the original contents of destination, nor does
* it set the destination alpha to anything but 1.0" ?
*/
cairo_bool_t
_cairo_operator_always_opaque (cairo_operator_t op)
{
switch (op) {
case CAIRO_OPERATOR_CLEAR:
return FALSE;
case CAIRO_OPERATOR_SOURCE:
return FALSE;
case CAIRO_OPERATOR_OVER:
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_ATOP:
return FALSE;
case CAIRO_OPERATOR_DEST:
return TRUE;
case CAIRO_OPERATOR_DEST_OVER:
case CAIRO_OPERATOR_DEST_IN:
case CAIRO_OPERATOR_DEST_OUT:
case CAIRO_OPERATOR_DEST_ATOP:
return FALSE;
case CAIRO_OPERATOR_XOR:
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_SATURATE:
return FALSE;
}
return FALSE;
}
/* As above, we'll probably want to add a cairo_content_t parameter to
* this function
*
* We also need a definition of what "translucent" means.
*/
cairo_bool_t
_cairo_operator_always_translucent (cairo_operator_t op)
{
switch (op) {
case CAIRO_OPERATOR_CLEAR:
return TRUE;
case CAIRO_OPERATOR_SOURCE:
return FALSE;
case CAIRO_OPERATOR_OVER:
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_ATOP:
return FALSE;
case CAIRO_OPERATOR_DEST:
return FALSE;
case CAIRO_OPERATOR_DEST_OVER:
case CAIRO_OPERATOR_DEST_IN:
case CAIRO_OPERATOR_DEST_OUT:
case CAIRO_OPERATOR_DEST_ATOP:
return FALSE;
case CAIRO_OPERATOR_XOR:
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_SATURATE:
return TRUE;
}
return TRUE;
}

Просмотреть файл

@ -722,6 +722,7 @@ cairo_os2_surface_create (HPS hps_client_window,
int height) int height)
{ {
cairo_os2_surface_t *local_os2_surface; cairo_os2_surface_t *local_os2_surface;
cairo_status_t status;
int rc; int rc;
/* Check the size of the window */ /* Check the size of the window */
@ -729,15 +730,13 @@ cairo_os2_surface_create (HPS hps_client_window,
(height <= 0)) (height <= 0))
{ {
/* Invalid window size! */ /* Invalid window size! */
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t)); local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t));
if (!local_os2_surface) { if (!local_os2_surface) {
/* Not enough memory! */ /* Not enough memory! */
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
/* Initialize the OS/2 specific parts of the surface! */ /* Initialize the OS/2 specific parts of the surface! */
@ -749,8 +748,7 @@ cairo_os2_surface_create (HPS hps_client_window,
FALSE); FALSE);
if (rc != NO_ERROR) { if (rc != NO_ERROR) {
/* Could not create mutex semaphore! */ /* Could not create mutex semaphore! */
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
/* Save PS handle */ /* Save PS handle */
@ -769,8 +767,7 @@ cairo_os2_surface_create (HPS hps_client_window,
/* Could not create event semaphore! */ /* Could not create event semaphore! */
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface); free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
/* Prepare BITMAPINFO2 structure for our buffer */ /* Prepare BITMAPINFO2 structure for our buffer */
@ -788,8 +785,7 @@ cairo_os2_surface_create (HPS hps_client_window,
DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface); free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
/* Create image surface from pixel array */ /* Create image surface from pixel array */
@ -800,14 +796,14 @@ cairo_os2_surface_create (HPS hps_client_window,
height, /* Height */ height, /* Height */
width * 4); /* Rowstride */ width * 4); /* Rowstride */
if (local_os2_surface->image_surface->base.status) { status = local_os2_surface->image_surface->base.status;
if (status) {
/* Could not create image surface! */ /* Could not create image surface! */
_buffer_free (local_os2_surface->pixels); _buffer_free (local_os2_surface->pixels);
DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface); free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (status);
return (cairo_surface_t *) &_cairo_surface_nil;
} }
/* Initialize base surface */ /* Initialize base surface */

Просмотреть файл

@ -87,6 +87,9 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
cairo_close_func_t close_func, cairo_close_func_t close_func,
void *closure); void *closure);
cairo_private cairo_output_stream_t *
_cairo_output_stream_create_in_error (cairo_status_t status);
/* Returns the final status value associated with this object, just /* Returns the final status value associated with this object, just
* before its last gasp. This final status value will capture any * before its last gasp. This final status value will capture any
* status failure returned by the stream's close_func as well. */ * status failure returned by the stream's close_func as well. */

Просмотреть файл

@ -134,6 +134,29 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
return &stream->base; return &stream->base;
} }
cairo_output_stream_t *
_cairo_output_stream_create_in_error (cairo_status_t status)
{
cairo_output_stream_t *stream;
/* check for the common ones */
if (status == CAIRO_STATUS_NO_MEMORY)
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
if (status == CAIRO_STATUS_WRITE_ERROR)
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
stream = malloc (sizeof (cairo_output_stream_t));
if (stream == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
_cairo_output_stream_init (stream, NULL, NULL);
stream->status = status;
return stream;
}
cairo_status_t cairo_status_t
_cairo_output_stream_close (cairo_output_stream_t *stream) _cairo_output_stream_close (cairo_output_stream_t *stream)
{ {
@ -165,8 +188,7 @@ _cairo_output_stream_destroy (cairo_output_stream_t *stream)
{ {
cairo_status_t status; cairo_status_t status;
if (stream == NULL) assert (stream != NULL);
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
if (stream == &_cairo_output_stream_nil || if (stream == &_cairo_output_stream_nil ||
stream == &_cairo_output_stream_nil_write_error) stream == &_cairo_output_stream_nil_write_error)

Просмотреть файл

@ -74,10 +74,11 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
const cairo_paginated_surface_backend_t *backend) const cairo_paginated_surface_backend_t *backend)
{ {
cairo_paginated_surface_t *surface; cairo_paginated_surface_t *surface;
cairo_status_t status;
surface = malloc (sizeof (cairo_paginated_surface_t)); surface = malloc (sizeof (cairo_paginated_surface_t));
if (surface == NULL) { if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL; goto FAIL;
} }
@ -97,7 +98,8 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
surface->backend = backend; surface->backend = backend;
surface->meta = _cairo_meta_surface_create (content, width, height); surface->meta = _cairo_meta_surface_create (content, width, height);
if (cairo_surface_status (surface->meta)) status = cairo_surface_status (surface->meta);
if (status)
goto FAIL_CLEANUP_SURFACE; goto FAIL_CLEANUP_SURFACE;
surface->page_num = 1; surface->page_num = 1;
@ -108,7 +110,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
FAIL_CLEANUP_SURFACE: FAIL_CLEANUP_SURFACE:
free (surface); free (surface);
FAIL: FAIL:
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
} }
cairo_bool_t cairo_bool_t
@ -292,9 +294,8 @@ _paint_page (cairo_paginated_surface_t *surface)
analysis = _cairo_analysis_surface_create (surface->target, analysis = _cairo_analysis_surface_create (surface->target,
surface->width, surface->height); surface->width, surface->height);
if (analysis == NULL) if (analysis->status)
return _cairo_surface_set_error (surface->target, return _cairo_surface_set_error (surface->target, analysis->status);
CAIRO_STATUS_NO_MEMORY);
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE); surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
status = _cairo_meta_surface_replay_and_create_regions (surface->meta, analysis); status = _cairo_meta_surface_replay_and_create_regions (surface->meta, analysis);
@ -326,6 +327,16 @@ _paint_page (cairo_paginated_surface_t *surface)
has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis); has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis);
break; break;
case CAIRO_SURFACE_TYPE_IMAGE:
case CAIRO_SURFACE_TYPE_XLIB:
case CAIRO_SURFACE_TYPE_XCB:
case CAIRO_SURFACE_TYPE_GLITZ:
case CAIRO_SURFACE_TYPE_QUARTZ:
case CAIRO_SURFACE_TYPE_WIN32:
case CAIRO_SURFACE_TYPE_BEOS:
case CAIRO_SURFACE_TYPE_DIRECTFB:
case CAIRO_SURFACE_TYPE_SVG:
case CAIRO_SURFACE_TYPE_OS2:
default: default:
if (_cairo_analysis_surface_has_unsupported (analysis)) { if (_cairo_analysis_surface_has_unsupported (analysis)) {
has_supported = FALSE; has_supported = FALSE;

Просмотреть файл

@ -37,7 +37,9 @@
#include "cairoint.h" #include "cairoint.h"
typedef struct cairo_path_bounder { typedef struct cairo_path_bounder {
int has_point; cairo_point_t move_to_point;
cairo_bool_t has_move_to_point;
cairo_bool_t has_point;
cairo_fixed_t min_x; cairo_fixed_t min_x;
cairo_fixed_t min_y; cairo_fixed_t min_y;
@ -60,25 +62,21 @@ _cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
static cairo_status_t static cairo_status_t
_cairo_path_bounder_line_to (void *closure, cairo_point_t *point); _cairo_path_bounder_line_to (void *closure, cairo_point_t *point);
static cairo_status_t
_cairo_path_bounder_curve_to (void *closure,
cairo_point_t *b,
cairo_point_t *c,
cairo_point_t *d);
static cairo_status_t static cairo_status_t
_cairo_path_bounder_close_path (void *closure); _cairo_path_bounder_close_path (void *closure);
static void static void
_cairo_path_bounder_init (cairo_path_bounder_t *bounder) _cairo_path_bounder_init (cairo_path_bounder_t *bounder)
{ {
bounder->has_point = 0; bounder->has_move_to_point = FALSE;
bounder->has_point = FALSE;
} }
static void static void
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder) _cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
{ {
bounder->has_point = 0; bounder->has_move_to_point = FALSE;
bounder->has_point = FALSE;
} }
static void static void
@ -102,7 +100,7 @@ _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *poi
bounder->max_x = point->x; bounder->max_x = point->x;
bounder->max_y = point->y; bounder->max_y = point->y;
bounder->has_point = 1; bounder->has_point = TRUE;
} }
} }
@ -111,7 +109,8 @@ _cairo_path_bounder_move_to (void *closure, cairo_point_t *point)
{ {
cairo_path_bounder_t *bounder = closure; cairo_path_bounder_t *bounder = closure;
_cairo_path_bounder_add_point (bounder, point); bounder->move_to_point = *point;
bounder->has_move_to_point = TRUE;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -121,26 +120,17 @@ _cairo_path_bounder_line_to (void *closure, cairo_point_t *point)
{ {
cairo_path_bounder_t *bounder = closure; cairo_path_bounder_t *bounder = closure;
if (bounder->has_move_to_point) {
_cairo_path_bounder_add_point (bounder,
&bounder->move_to_point);
bounder->has_move_to_point = FALSE;
}
_cairo_path_bounder_add_point (bounder, point); _cairo_path_bounder_add_point (bounder, point);
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
static cairo_status_t
_cairo_path_bounder_curve_to (void *closure,
cairo_point_t *b,
cairo_point_t *c,
cairo_point_t *d)
{
cairo_path_bounder_t *bounder = closure;
_cairo_path_bounder_add_point (bounder, b);
_cairo_path_bounder_add_point (bounder, c);
_cairo_path_bounder_add_point (bounder, d);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t static cairo_status_t
_cairo_path_bounder_close_path (void *closure) _cairo_path_bounder_close_path (void *closure)
{ {
@ -151,7 +141,8 @@ _cairo_path_bounder_close_path (void *closure)
void void
_cairo_path_fixed_bounds (cairo_path_fixed_t *path, _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1, double *x1, double *y1,
double *x2, double *y2) double *x2, double *y2,
double tolerance)
{ {
cairo_status_t status; cairo_status_t status;
@ -159,21 +150,24 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
_cairo_path_bounder_init (&bounder); _cairo_path_bounder_init (&bounder);
status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD,
_cairo_path_bounder_move_to, _cairo_path_bounder_move_to,
_cairo_path_bounder_line_to, _cairo_path_bounder_line_to,
_cairo_path_bounder_curve_to, _cairo_path_bounder_close_path,
_cairo_path_bounder_close_path, &bounder,
&bounder); tolerance);
assert (status == CAIRO_STATUS_SUCCESS); assert (status == CAIRO_STATUS_SUCCESS);
if (! bounder.has_point) { if (bounder.has_point) {
*x1 = *y1 = *x2 = *y2 = 0.;
} else {
*x1 = _cairo_fixed_to_double (bounder.min_x); *x1 = _cairo_fixed_to_double (bounder.min_x);
*y1 = _cairo_fixed_to_double (bounder.min_y); *y1 = _cairo_fixed_to_double (bounder.min_y);
*x2 = _cairo_fixed_to_double (bounder.max_x); *x2 = _cairo_fixed_to_double (bounder.max_x);
*y2 = _cairo_fixed_to_double (bounder.max_y); *y2 = _cairo_fixed_to_double (bounder.max_y);
} else {
*x1 = 0.0;
*y1 = 0.0;
*x2 = 0.0;
*y2 = 0.0;
} }
_cairo_path_bounder_fini (&bounder); _cairo_path_bounder_fini (&bounder);

Просмотреть файл

@ -622,3 +622,102 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
} }
return TRUE; return TRUE;
} }
/* Closure for path flattening */
typedef struct cairo_path_flattener {
double tolerance;
cairo_point_t current_point;
cairo_path_fixed_move_to_func_t *move_to;
cairo_path_fixed_line_to_func_t *line_to;
cairo_path_fixed_close_path_func_t *close_path;
void *closure;
} cpf_t;
static cairo_status_t
_cpf_move_to (void *closure, cairo_point_t *point)
{
cpf_t *cpf = closure;
cpf->current_point = *point;
return cpf->move_to (cpf->closure, point);
}
static cairo_status_t
_cpf_line_to (void *closure, cairo_point_t *point)
{
cpf_t *cpf = closure;
cpf->current_point = *point;
return cpf->line_to (cpf->closure, point);
}
static cairo_status_t
_cpf_curve_to (void *closure,
cairo_point_t *p1,
cairo_point_t *p2,
cairo_point_t *p3)
{
cpf_t *cpf = closure;
cairo_status_t status;
cairo_spline_t spline;
int i;
cairo_point_t *p0 = &cpf->current_point;
status = _cairo_spline_init (&spline, p0, p1, p2, p3);
if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS;
status = _cairo_spline_decompose (&spline, cpf->tolerance);
if (status)
goto out;
for (i=1; i < spline.num_points; i++) {
status = cpf->line_to (cpf->closure, &spline.points[i]);
if (status)
goto out;
}
cpf->current_point = *p3;
status = CAIRO_STATUS_SUCCESS;
out:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t
_cpf_close_path (void *closure)
{
cpf_t *cpf = closure;
return cpf->close_path (cpf->closure);
}
cairo_status_t
_cairo_path_fixed_interpret_flat (cairo_path_fixed_t *path,
cairo_direction_t dir,
cairo_path_fixed_move_to_func_t *move_to,
cairo_path_fixed_line_to_func_t *line_to,
cairo_path_fixed_close_path_func_t *close_path,
void *closure,
double tolerance)
{
cpf_t flattener;
flattener.tolerance = tolerance;
flattener.move_to = move_to;
flattener.line_to = line_to;
flattener.close_path = close_path;
flattener.closure = closure;
return _cairo_path_fixed_interpret (path, dir,
_cpf_move_to,
_cpf_line_to,
_cpf_curve_to,
_cpf_close_path,
&flattener);
}

Просмотреть файл

@ -882,7 +882,7 @@ _cairo_stroker_curve_to (void *closure,
status = _cairo_spline_init (&spline, a, b, c, d); status = _cairo_spline_init (&spline, a, b, c, d);
if (status == CAIRO_INT_STATUS_DEGENERATE) if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS; return _cairo_stroker_line_to (closure, d);
status = _cairo_pen_init_copy (&pen, &stroker->pen); status = _cairo_pen_init_copy (&pen, &stroker->pen);
if (status) if (status)
@ -966,7 +966,7 @@ _cairo_stroker_curve_to_dashed (void *closure,
status = _cairo_spline_init (&spline, a, b, c, d); status = _cairo_spline_init (&spline, a, b, c, d);
if (status == CAIRO_INT_STATUS_DEGENERATE) if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS; return _cairo_stroker_line_to_dashed (closure, d);
/* If the line width is so small that the pen is reduced to a /* If the line width is so small that the pen is reduced to a
single point, then we have nothing to do. */ single point, then we have nothing to do. */
@ -1358,6 +1358,12 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
return CAIRO_INT_STATUS_UNSUPPORTED; return CAIRO_INT_STATUS_UNSUPPORTED;
if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER) if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER)
return CAIRO_INT_STATUS_UNSUPPORTED; return CAIRO_INT_STATUS_UNSUPPORTED;
/* If the miter limit turns right angles into bevels, then we
* can't use this optimization. Remember, the ratio is
* 1/sin(ɸ/2). So the cutoff is 1/sin(π/4.0) or 2,
* which we round for safety. */
if (stroke_style->miter_limit < M_SQRT2)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (stroke_style->dash) if (stroke_style->dash)
return CAIRO_INT_STATUS_UNSUPPORTED; return CAIRO_INT_STATUS_UNSUPPORTED;
if (! (stroke_style->line_cap == CAIRO_LINE_CAP_BUTT || if (! (stroke_style->line_cap == CAIRO_LINE_CAP_BUTT ||

Просмотреть файл

@ -44,7 +44,6 @@ static const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
/* Closure for path interpretation. */ /* Closure for path interpretation. */
typedef struct cairo_path_count { typedef struct cairo_path_count {
int count; int count;
double tolerance;
cairo_point_t current_point; cairo_point_t current_point;
} cpc_t; } cpc_t;
@ -87,39 +86,6 @@ _cpc_curve_to (void *closure,
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
static cairo_status_t
_cpc_curve_to_flatten (void *closure,
cairo_point_t *p1,
cairo_point_t *p2,
cairo_point_t *p3)
{
cpc_t *cpc = closure;
cairo_status_t status;
cairo_spline_t spline;
int i;
cairo_point_t *p0 = &cpc->current_point;
status = _cairo_spline_init (&spline, p0, p1, p2, p3);
if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS;
status = _cairo_spline_decompose (&spline, cpc->tolerance);
if (status)
goto out;
for (i=1; i < spline.num_points; i++)
_cpc_line_to (cpc, &spline.points[i]);
cpc->current_point = *p3;
status = CAIRO_STATUS_SUCCESS;
out:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t static cairo_status_t
_cpc_close_path (void *closure) _cpc_close_path (void *closure)
{ {
@ -140,19 +106,27 @@ _cairo_path_count (cairo_path_t *path,
cpc_t cpc; cpc_t cpc;
cpc.count = 0; cpc.count = 0;
cpc.tolerance = tolerance;
cpc.current_point.x = 0; cpc.current_point.x = 0;
cpc.current_point.y = 0; cpc.current_point.y = 0;
status = _cairo_path_fixed_interpret (path_fixed, if (flatten) {
CAIRO_DIRECTION_FORWARD, status = _cairo_path_fixed_interpret_flat (path_fixed,
_cpc_move_to, CAIRO_DIRECTION_FORWARD,
_cpc_line_to, _cpc_move_to,
flatten ? _cpc_line_to,
_cpc_curve_to_flatten : _cpc_close_path,
_cpc_curve_to, &cpc,
_cpc_close_path, tolerance);
&cpc); } else {
status = _cairo_path_fixed_interpret (path_fixed,
CAIRO_DIRECTION_FORWARD,
_cpc_move_to,
_cpc_line_to,
_cpc_curve_to,
_cpc_close_path,
&cpc);
}
if (status) if (status)
return -1; return -1;
@ -262,40 +236,6 @@ _cpp_curve_to (void *closure,
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
static cairo_status_t
_cpp_curve_to_flatten (void *closure,
cairo_point_t *p1,
cairo_point_t *p2,
cairo_point_t *p3)
{
cpp_t *cpp = closure;
cairo_status_t status;
cairo_spline_t spline;
int i;
cairo_point_t *p0 = &cpp->current_point;
status = _cairo_spline_init (&spline, p0, p1, p2, p3);
if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS;
status = _cairo_spline_decompose (&spline,
_cairo_gstate_get_tolerance (cpp->gstate));
if (status)
goto out;
for (i=1; i < spline.num_points; i++)
_cpp_line_to (cpp, &spline.points[i]);
cpp->current_point = *p3;
status = CAIRO_STATUS_SUCCESS;
out:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t static cairo_status_t
_cpp_close_path (void *closure) _cpp_close_path (void *closure)
{ {
@ -324,15 +264,25 @@ _cairo_path_populate (cairo_path_t *path,
cpp.current_point.x = 0; cpp.current_point.x = 0;
cpp.current_point.y = 0; cpp.current_point.y = 0;
status = _cairo_path_fixed_interpret (path_fixed, if (flatten) {
double tolerance = _cairo_gstate_get_tolerance (gstate);
status = _cairo_path_fixed_interpret_flat (path_fixed,
CAIRO_DIRECTION_FORWARD,
_cpp_move_to,
_cpp_line_to,
_cpp_close_path,
&cpp,
tolerance);
} else {
status = _cairo_path_fixed_interpret (path_fixed,
CAIRO_DIRECTION_FORWARD, CAIRO_DIRECTION_FORWARD,
_cpp_move_to, _cpp_move_to,
_cpp_line_to, _cpp_line_to,
flatten ?
_cpp_curve_to_flatten :
_cpp_curve_to, _cpp_curve_to,
_cpp_close_path, _cpp_close_path,
&cpp); &cpp);
}
if (status) if (status)
return status; return status;

Просмотреть файл

@ -164,7 +164,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
static void static void
_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res); _cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res);
static cairo_pdf_resource_t static cairo_status_t
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource, cairo_pdf_resource_t *resource,
cairo_bool_t compressed, cairo_bool_t compressed,
@ -234,14 +234,13 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
double height) double height)
{ {
cairo_pdf_surface_t *surface; cairo_pdf_surface_t *surface;
cairo_status_t status; cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_pdf_surface_t)); surface = malloc (sizeof (cairo_pdf_surface_t));
if (surface == NULL) { if (surface == NULL) {
/* destroy stream on behalf of caller */ /* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output); status = _cairo_output_stream_destroy (output);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
_cairo_surface_init (&surface->base, &cairo_pdf_surface_backend, _cairo_surface_init (&surface->base, &cairo_pdf_surface_backend,
@ -265,14 +264,16 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
surface->font_subsets = _cairo_scaled_font_subsets_create_composite (); surface->font_subsets = _cairo_scaled_font_subsets_create_composite ();
if (! surface->font_subsets) { if (! surface->font_subsets) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL0; goto BAIL0;
} }
surface->next_available_resource.id = 1; surface->next_available_resource.id = 1;
surface->pages_resource = _cairo_pdf_surface_new_object (surface); surface->pages_resource = _cairo_pdf_surface_new_object (surface);
if (surface->pages_resource.id == 0) if (surface->pages_resource.id == 0) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL1; goto BAIL1;
}
surface->compress_content = TRUE; surface->compress_content = TRUE;
surface->pdf_stream.active = FALSE; surface->pdf_stream.active = FALSE;
@ -304,7 +305,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
width, height, width, height,
&cairo_pdf_surface_paginated_backend); &cairo_pdf_surface_paginated_backend);
if (surface->paginated_surface->status == CAIRO_STATUS_SUCCESS) status = surface->paginated_surface->status;
if (status == CAIRO_STATUS_SUCCESS)
return surface->paginated_surface; return surface->paginated_surface;
BAIL1: BAIL1:
@ -314,9 +316,9 @@ BAIL0:
free (surface); free (surface);
/* destroy stream on behalf of caller */ /* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output); status_ignored = _cairo_output_stream_destroy (output);
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
} }
/** /**
@ -345,13 +347,11 @@ cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
double width_in_points, double width_in_points,
double height_in_points) double height_in_points)
{ {
cairo_status_t status;
cairo_output_stream_t *output; cairo_output_stream_t *output;
output = _cairo_output_stream_create (write_func, NULL, closure); output = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (output); if (_cairo_output_stream_get_status (output))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_pdf_surface_create_for_stream_internal (output, return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points, width_in_points,
@ -382,15 +382,11 @@ cairo_pdf_surface_create (const char *filename,
double width_in_points, double width_in_points,
double height_in_points) double height_in_points)
{ {
cairo_status_t status;
cairo_output_stream_t *output; cairo_output_stream_t *output;
output = _cairo_output_stream_create_for_filename (filename); output = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (output); if (_cairo_output_stream_get_status (output))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t*) &_cairo_surface_nil_write_error :
(cairo_surface_t*) &_cairo_surface_nil;
return _cairo_pdf_surface_create_for_stream_internal (output, return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points, width_in_points,
@ -816,7 +812,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
static cairo_pdf_resource_t static cairo_status_t
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource, cairo_pdf_resource_t *resource,
cairo_bool_t compressed, cairo_bool_t compressed,
@ -833,19 +829,17 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
} else { } else {
self = _cairo_pdf_surface_new_object (surface); self = _cairo_pdf_surface_new_object (surface);
if (self.id == 0) if (self.id == 0)
return self; return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} }
length = _cairo_pdf_surface_new_object (surface); length = _cairo_pdf_surface_new_object (surface);
if (length.id == 0) if (length.id == 0)
return length; return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (compressed) { if (compressed) {
output = _cairo_deflate_stream_create (surface->output); output = _cairo_deflate_stream_create (surface->output);
if (_cairo_output_stream_get_status (output)) { if (_cairo_output_stream_get_status (output))
self.id = 0; return _cairo_output_stream_destroy (output);
return self;
}
} }
surface->pdf_stream.active = TRUE; surface->pdf_stream.active = TRUE;
@ -881,7 +875,7 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
} }
return surface->pdf_stream.self; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -919,6 +913,9 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
surface->pdf_stream.active = FALSE; surface->pdf_stream.active = FALSE;
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_output_stream_get_status (surface->output);
return status; return status;
} }
@ -1049,7 +1046,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
if (group) if (group)
*group = surface->group_stream.resource; *group = surface->group_stream.resource;
status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream); status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream);
if (status == CAIRO_STATUS_SUCCESS) if (status == CAIRO_STATUS_SUCCESS)
status = status2; status = status2;
@ -1061,9 +1058,10 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
static cairo_status_t static cairo_status_t
_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface, _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource,
cairo_bool_t is_form) cairo_bool_t is_form)
{ {
cairo_status_t status;
assert (surface->pdf_stream.active == FALSE); assert (surface->pdf_stream.active == FALSE);
assert (surface->group_stream.active == FALSE); assert (surface->group_stream.active == FALSE);
@ -1072,7 +1070,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (is_form) { if (is_form) {
*resource = status =
_cairo_pdf_surface_open_stream (surface, _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
surface->compress_content, surface->compress_content,
@ -1088,21 +1086,23 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
surface->width, surface->width,
surface->height, surface->height,
surface->content_resources.id); surface->content_resources.id);
if (resource->id == 0) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
} else { } else {
surface->content = status =
_cairo_pdf_surface_open_stream (surface, _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
surface->compress_content, surface->compress_content,
NULL); NULL);
if (surface->content.id == 0) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
} }
surface->content = surface->pdf_stream.self;
_cairo_output_stream_printf (surface->output, "q\r\n"); _cairo_output_stream_printf (surface->output, "q\r\n");
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -1126,7 +1126,7 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
"endobj\r\n"); "endobj\r\n");
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_surface_t * static cairo_surface_t *
@ -1233,7 +1233,7 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
surface->has_fallback_images = FALSE; surface->has_fallback_images = FALSE;
_cairo_pdf_group_resources_clear (&surface->resources); _cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, &surface->content, TRUE); status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
if (status) if (status)
return status; return status;
@ -1284,11 +1284,13 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
uint8_t a; uint8_t a;
int src_bit, dst_bit; int src_bit, dst_bit;
/* This is the only image format we support, which simplfies things. */ /* This is the only image format we support, which simplifies things. */
assert (image->format == CAIRO_FORMAT_ARGB32 || assert (image->format == CAIRO_FORMAT_ARGB32 ||
image->format == CAIRO_FORMAT_A8 || image->format == CAIRO_FORMAT_A8 ||
image->format == CAIRO_FORMAT_A1 ); image->format == CAIRO_FORMAT_A1 );
stream_ret->id = 0;
if (image->format == CAIRO_FORMAT_A1) if (image->format == CAIRO_FORMAT_A1)
alpha_size = (image->height * image->width + 7)/8; alpha_size = (image->height * image->width + 7)/8;
else else
@ -1345,10 +1347,8 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
} }
/* Bail out without emitting smask if it's all opaque. */ /* Bail out without emitting smask if it's all opaque. */
if (opaque) { if (opaque)
stream_ret->id = 0;
goto CLEANUP_ALPHA; goto CLEANUP_ALPHA;
}
alpha_compressed = compress_dup (alpha, alpha_size, &alpha_compressed_size); alpha_compressed = compress_dup (alpha, alpha_size, &alpha_compressed_size);
if (alpha_compressed == NULL) { if (alpha_compressed == NULL) {
@ -1356,22 +1356,22 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
goto CLEANUP_ALPHA; goto CLEANUP_ALPHA;
} }
*stream_ret = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
FALSE, FALSE,
" /Type /XObject\r\n" " /Type /XObject\r\n"
" /Subtype /Image\r\n" " /Subtype /Image\r\n"
" /Width %d\r\n" " /Width %d\r\n"
" /Height %d\r\n" " /Height %d\r\n"
" /ColorSpace /DeviceGray\r\n" " /ColorSpace /DeviceGray\r\n"
" /BitsPerComponent %d\r\n" " /BitsPerComponent %d\r\n"
" /Filter /FlateDecode\r\n", " /Filter /FlateDecode\r\n",
image->width, image->height, image->width, image->height,
image->format == CAIRO_FORMAT_A1 ? 1 : 8); image->format == CAIRO_FORMAT_A1 ? 1 : 8);
if (stream_ret->id == 0) { if (status)
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_ALPHA_COMPRESSED; goto CLEANUP_ALPHA_COMPRESSED;
}
*stream_ret = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size); _cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size);
_cairo_output_stream_printf (surface->output, "\r\n"); _cairo_output_stream_printf (surface->output, "\r\n");
@ -1483,26 +1483,26 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
" /Filter /FlateDecode\r\n" " /Filter /FlateDecode\r\n"
if (need_smask) if (need_smask)
*image_ret = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
FALSE, FALSE,
IMAGE_DICTIONARY IMAGE_DICTIONARY
" /SMask %d 0 R\r\n", " /SMask %d 0 R\r\n",
image->width, image->height, image->width, image->height,
smask.id); smask.id);
else else
*image_ret = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
FALSE, FALSE,
IMAGE_DICTIONARY, IMAGE_DICTIONARY,
image->width, image->height); image->width, image->height);
if (image_ret->id == 0){ if (status)
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPRESSED; goto CLEANUP_COMPRESSED;
}
#undef IMAGE_DICTIONARY #undef IMAGE_DICTIONARY
*image_ret = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, compressed, compressed_size); _cairo_output_stream_write (surface->output, compressed, compressed_size);
_cairo_output_stream_printf (surface->output, "\r\n"); _cairo_output_stream_printf (surface->output, "\r\n");
status = _cairo_pdf_surface_close_stream (surface); status = _cairo_pdf_surface_close_stream (surface);
@ -1522,22 +1522,13 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
int *width, int *width,
int *height) int *height)
{ {
cairo_surface_t *pat_surface;
cairo_surface_attributes_t pat_attr;
cairo_image_surface_t *image; cairo_image_surface_t *image;
void *image_extra; void *image_extra;
cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_status_t status;
status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern, status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
(cairo_surface_t *)surface,
0, 0, -1, -1,
&pat_surface, &pat_attr);
if (status) if (status)
return status; goto BAIL;
status = _cairo_surface_acquire_source_image (pat_surface, &image, &image_extra);
if (status)
goto BAIL2;
status = _cairo_pdf_surface_emit_image (surface, image, resource); status = _cairo_pdf_surface_emit_image (surface, image, resource);
if (status) if (status)
@ -1547,9 +1538,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
*height = image->height; *height = image->height;
BAIL: BAIL:
_cairo_surface_release_source_image (pat_surface, image, image_extra); _cairo_surface_release_source_image (pattern->surface, image, image_extra);
BAIL2:
_cairo_pattern_release_surface ((cairo_pattern_t *)pattern, pat_surface, &pat_attr);
return status; return status;
} }
@ -1562,7 +1551,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
double old_width, old_height; double old_width, old_height;
cairo_matrix_t old_cairo_to_pdf; cairo_matrix_t old_cairo_to_pdf;
cairo_paginated_mode_t old_paginated_mode; cairo_paginated_mode_t old_paginated_mode;
cairo_rectangle_int16_t meta_extents; cairo_rectangle_int_t meta_extents;
cairo_status_t status; cairo_status_t status;
int alpha = 0; int alpha = 0;
@ -1586,7 +1575,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
surface->cairo_to_pdf); surface->cairo_to_pdf);
_cairo_pdf_group_resources_clear (&surface->resources); _cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, &surface->content, TRUE); status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
if (status) if (status)
return status; return status;
@ -1627,19 +1616,20 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_pattern) cairo_pdf_pattern_t *pdf_pattern)
{ {
cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern; cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_status_t status;
cairo_pdf_resource_t pattern_resource = {0}; /* squelch bogus compiler warning */ cairo_pdf_resource_t pattern_resource = {0}; /* squelch bogus compiler warning */
cairo_matrix_t cairo_p2d, pdf_p2d; cairo_matrix_t cairo_p2d, pdf_p2d;
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base); cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
double xstep, ystep; double xstep, ystep;
cairo_rectangle_int16_t surface_extents; cairo_rectangle_int_t surface_extents;
int pattern_width = 0; /* squelch bogus compiler warning */ int pattern_width = 0; /* squelch bogus compiler warning */
int pattern_height = 0; /* squelch bogus compiler warning */ int pattern_height = 0; /* squelch bogus compiler warning */
int bbox_x, bbox_y; int bbox_x, bbox_y;
char draw_surface[200];
if (_cairo_surface_is_meta (pattern->surface)) { if (_cairo_surface_is_meta (pattern->surface)) {
cairo_surface_t *meta_surface = pattern->surface; cairo_surface_t *meta_surface = pattern->surface;
cairo_rectangle_int16_t pattern_extents; cairo_rectangle_int_t pattern_extents;
status = _cairo_pdf_surface_emit_meta_surface (surface, status = _cairo_pdf_surface_emit_meta_surface (surface,
meta_surface, meta_surface,
@ -1758,60 +1748,66 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0); cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
_cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res); _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
if (_cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
&pdf_pattern->pattern_res, &pdf_pattern->pattern_res,
FALSE, FALSE,
" /PatternType 1\r\n" " /PatternType 1\r\n"
" /BBox [0 0 %d %d]\r\n" " /BBox [0 0 %d %d]\r\n"
" /XStep %f\r\n" " /XStep %f\r\n"
" /YStep %f\r\n" " /YStep %f\r\n"
" /TilingType 1\r\n" " /TilingType 1\r\n"
" /PaintType 1\r\n" " /PaintType 1\r\n"
" /Matrix [ %f %f %f %f %f %f ]\r\n" " /Matrix [ %f %f %f %f %f %f ]\r\n"
" /Resources << /XObject << /x%d %d 0 R >> >>\r\n", " /Resources << /XObject << /x%d %d 0 R >> >>\r\n",
bbox_x, bbox_y, bbox_x, bbox_y,
xstep, ystep, xstep, ystep,
pdf_p2d.xx, pdf_p2d.yx, pdf_p2d.xx, pdf_p2d.yx,
pdf_p2d.xy, pdf_p2d.yy, pdf_p2d.xy, pdf_p2d.yy,
pdf_p2d.x0, pdf_p2d.y0, pdf_p2d.x0, pdf_p2d.y0,
pattern_resource.id, pattern_resource.id,
pattern_resource.id).id == 0) pattern_resource.id);
{ if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
}
if (_cairo_surface_is_meta (pattern->surface)) { if (_cairo_surface_is_meta (pattern->surface)) {
if (extend == CAIRO_EXTEND_REFLECT) { snprintf(draw_surface,
_cairo_output_stream_printf (surface->output, sizeof (draw_surface),
"q 0 0 %d %d re W n /x%d Do Q\r\n" "/x%d Do\r\n",
"q -1 0 0 1 %d 0 cm 0 0 %d %d re W n /x%d Do Q\r\n" pattern_resource.id);
"q 1 0 0 -1 0 %d cm 0 0 %d %d re W n /x%d Do Q\r\n" } else {
"q -1 0 0 -1 %d %d cm 0 0 %d %d re W n /x%d Do Q\r\n", snprintf(draw_surface,
pattern_width, pattern_height, sizeof (draw_surface),
pattern_resource.id, "q %d 0 0 %d 0 0 cm /x%d Do Q",
pattern_width*2, pattern_width, pattern_height, pattern_width,
pattern_resource.id, pattern_height,
pattern_height*2, pattern_width, pattern_height, pattern_resource.id);
pattern_resource.id, }
pattern_width*2, pattern_height*2, pattern_width, pattern_height,
pattern_resource.id); if (extend == CAIRO_EXTEND_REFLECT) {
} else { _cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->output, "q 0 0 %d %d re W n %s Q\r\n"
"/x%d Do\r\n", "q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\r\n"
pattern_resource.id); "q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\r\n"
} "q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\r\n",
pattern_width, pattern_height,
draw_surface,
pattern_width*2, pattern_width, pattern_height,
draw_surface,
pattern_height*2, pattern_width, pattern_height,
draw_surface,
pattern_width*2, pattern_height*2, pattern_width, pattern_height,
draw_surface);
} else { } else {
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
"q %d 0 0 %d 0 0 cm /x%d Do Q\r\n", " %s \r\n",
pattern_width, pattern_height, draw_surface);
pattern_resource.id);
} }
status = _cairo_pdf_surface_close_stream (surface); status = _cairo_pdf_surface_close_stream (surface);
if (status) if (status)
return status; return status;
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
typedef struct _cairo_pdf_color_stop { typedef struct _cairo_pdf_color_stop {
@ -1995,7 +1991,7 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
*function = res; *function = res;
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
@ -2088,7 +2084,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
goto BAIL; goto BAIL;
} }
} else { } else {
/* multiple stops: stitch. XXX possible optimization: regulary spaced /* multiple stops: stitch. XXX possible optimization: regularly spaced
* stops do not require stitching. XXX */ * stops do not require stitching. XXX */
status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
n_stops, n_stops,
@ -2172,7 +2168,7 @@ _cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface,
*function = res; *function = res;
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -2180,34 +2176,34 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t gstate_resource, cairo_pdf_resource_t gstate_resource,
cairo_pdf_resource_t gradient_mask) cairo_pdf_resource_t gradient_mask)
{ {
cairo_pdf_resource_t xobj_resource, smask_resource; cairo_pdf_resource_t smask_resource;
cairo_status_t status; cairo_status_t status;
xobj_resource = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
surface->compress_content, surface->compress_content,
" /Type /XObject\r\n" " /Type /XObject\r\n"
" /Subtype /Form\r\n" " /Subtype /Form\r\n"
" /FormType 1\r\n" " /FormType 1\r\n"
" /BBox [ 0 0 %f %f ]\r\n" " /BBox [ 0 0 %f %f ]\r\n"
" /Resources\r\n" " /Resources\r\n"
" << /ExtGState\r\n" " << /ExtGState\r\n"
" << /a0 << /ca 1 /CA 1 >>" " << /a0 << /ca 1 /CA 1 >>"
" >>\r\n" " >>\r\n"
" /Pattern\r\n" " /Pattern\r\n"
" << /p%d %d 0 R >>\r\n" " << /p%d %d 0 R >>\r\n"
" >>\r\n" " >>\r\n"
" /Group\r\n" " /Group\r\n"
" << /Type /Group\r\n" " << /Type /Group\r\n"
" /S /Transparency\r\n" " /S /Transparency\r\n"
" /CS /DeviceGray\r\n" " /CS /DeviceGray\r\n"
" >>\r\n", " >>\r\n",
surface->width, surface->width,
surface->height, surface->height,
gradient_mask.id, gradient_mask.id,
gradient_mask.id); gradient_mask.id);
if (xobj_resource.id == 0) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
"q\r\n" "q\r\n"
@ -2236,7 +2232,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
">>\r\n" ">>\r\n"
"endobj\r\n", "endobj\r\n",
smask_resource.id, smask_resource.id,
xobj_resource.id); surface->pdf_stream.self.id);
/* Create GState which uses the transparency group as an SMask. */ /* Create GState which uses the transparency group as an SMask. */
_cairo_pdf_surface_update_object (surface, gstate_resource); _cairo_pdf_surface_update_object (surface, gstate_resource);
@ -2253,7 +2249,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
gstate_resource.id, gstate_resource.id,
smask_resource.id); smask_resource.id);
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -2453,7 +2449,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
return status; return status;
} }
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -2570,7 +2566,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
return status; return status;
} }
return CAIRO_STATUS_SUCCESS; return _cairo_output_stream_get_status (surface->output);
} }
static cairo_status_t static cairo_status_t
@ -2686,7 +2682,7 @@ _cairo_pdf_surface_get_extents (void *abstract_surface,
rectangle->y = 0; rectangle->y = 0;
/* XXX: The conversion to integers here is pretty bogus, (not to /* XXX: The conversion to integers here is pretty bogus, (not to
* mention the aribitray limitation of width to a short(!). We * mention the arbitrary limitation of width to a short(!). We
* may need to come up with a better interface for get_size. * may need to come up with a better interface for get_size.
*/ */
rectangle->width = (int) ceil (surface->width); rectangle->width = (int) ceil (surface->width);
@ -2768,7 +2764,7 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
_cairo_output_stream_printf (surface->output, " /Count %d\r\n", num_pages); _cairo_output_stream_printf (surface->output, " /Count %d\r\n", num_pages);
/* TODO: Figure out wich other defaults to be inherited by /Page /* TODO: Figure out which other defaults to be inherited by /Page
* objects. */ * objects. */
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
">>\r\n" ">>\r\n"
@ -2804,12 +2800,12 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
return status; return status;
} }
*stream = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
surface->compress_content, surface->compress_content,
NULL); NULL);
if (stream->id == 0) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
"/CIDInit /ProcSet findresource begin\r\n" "/CIDInit /ProcSet findresource begin\r\n"
@ -2866,6 +2862,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
"end\r\n" "end\r\n"
"end\r\n"); "end\r\n");
*stream = surface->pdf_stream.self;
return _cairo_pdf_surface_close_stream (surface); return _cairo_pdf_surface_close_stream (surface);
} }
@ -3410,16 +3407,18 @@ _cairo_pdf_surface_emit_bitmap_glyph (cairo_pdf_surface_t *surface,
return status; return status;
} }
*glyph_ret = _cairo_pdf_surface_open_stream (surface, status = _cairo_pdf_surface_open_stream (surface,
NULL, NULL,
surface->compress_content, surface->compress_content,
NULL); NULL);
if (glyph_ret->id == 0) { if (status) {
if (image != scaled_glyph->surface) if (image != scaled_glyph->surface)
cairo_surface_destroy (&image->base); cairo_surface_destroy (&image->base);
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return status;
} }
*glyph_ret = surface->pdf_stream.self;
_cairo_output_stream_printf (surface->output, _cairo_output_stream_printf (surface->output,
"%f 0 %f %f %f %f d1\r\n", "%f 0 %f %f %f %f d1\r\n",
x_advance, x_advance,
@ -3657,6 +3656,7 @@ _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_s
return status; return status;
} }
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -3671,6 +3671,7 @@ _cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_sub
if (status != CAIRO_INT_STATUS_UNSUPPORTED) if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status; return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -4024,7 +4025,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
return status; return status;
_cairo_pdf_group_resources_clear (&surface->resources); _cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, &surface->content, FALSE); status = _cairo_pdf_surface_open_content_stream (surface, FALSE);
if (status) if (status)
return status; return status;
@ -4218,9 +4219,7 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
surface->has_fallback_images = TRUE; surface->has_fallback_images = TRUE;
_cairo_pdf_group_resources_clear (&surface->resources); _cairo_pdf_group_resources_clear (&surface->resources);
return _cairo_pdf_surface_open_content_stream (surface, return _cairo_pdf_surface_open_content_stream (surface, TRUE);
&surface->content,
TRUE);
} }
static cairo_int_status_t static cairo_int_status_t

Просмотреть файл

@ -382,7 +382,7 @@ static cairo_surface_t *
read_png (png_rw_ptr read_func, read_png (png_rw_ptr read_func,
void *closure) void *closure)
{ {
cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil; cairo_surface_t *surface;
png_struct *png = NULL; png_struct *png = NULL;
png_info *info; png_info *info;
png_byte *data = NULL; png_byte *data = NULL;
@ -398,20 +398,23 @@ read_png (png_rw_ptr read_func,
&status, &status,
png_simple_error_callback, png_simple_error_callback,
png_simple_warning_callback); png_simple_warning_callback);
if (png == NULL) if (png == NULL) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL; goto BAIL;
}
info = png_create_info_struct (png); info = png_create_info_struct (png);
if (info == NULL) if (info == NULL) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL; goto BAIL;
}
png_set_read_fn (png, closure, read_func); png_set_read_fn (png, closure, read_func);
status = CAIRO_STATUS_SUCCESS; status = CAIRO_STATUS_SUCCESS;
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
if (setjmp (png_jmpbuf (png))) { if (setjmp (png_jmpbuf (png))) {
if (status != CAIRO_STATUS_NO_MEMORY) surface = _cairo_surface_create_in_error (status);
surface = (cairo_surface_t*) &_cairo_surface_nil_read_error;
goto BAIL; goto BAIL;
} }
#endif #endif
@ -460,12 +463,16 @@ read_png (png_rw_ptr read_func,
pixel_size = 4; pixel_size = 4;
data = _cairo_malloc_abc (png_height, png_width, pixel_size); data = _cairo_malloc_abc (png_height, png_width, pixel_size);
if (data == NULL) if (data == NULL) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL; goto BAIL;
}
row_pointers = _cairo_malloc_ab (png_height, sizeof (char *)); row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
if (row_pointers == NULL) if (row_pointers == NULL) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL; goto BAIL;
}
for (i = 0; i < png_height; i++) for (i = 0; i < png_height; i++)
row_pointers[i] = &data[i * png_width * pixel_size]; row_pointers[i] = &data[i * png_width * pixel_size];
@ -490,9 +497,6 @@ read_png (png_rw_ptr read_func,
if (png) if (png)
png_destroy_read_struct (&png, &info, NULL); png_destroy_read_struct (&png, &info, NULL);
if (surface->status)
_cairo_error_throw (surface->status);
return surface; return surface;
} }
@ -538,17 +542,19 @@ cairo_image_surface_create_from_png (const char *filename)
fp = fopen (filename, "rb"); fp = fopen (filename, "rb");
if (fp == NULL) { if (fp == NULL) {
cairo_status_t status;
switch (errno) { switch (errno) {
case ENOMEM: case ENOMEM:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil; break;
case ENOENT: case ENOENT:
_cairo_error_throw (CAIRO_STATUS_FILE_NOT_FOUND); status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
return (cairo_surface_t*) &_cairo_surface_nil_file_not_found; break;
default: default:
_cairo_error_throw (CAIRO_STATUS_READ_ERROR); status = _cairo_error (CAIRO_STATUS_READ_ERROR);
return (cairo_surface_t*) &_cairo_surface_nil_read_error; break;
} }
return _cairo_surface_create_in_error (status);
} }
surface = read_png (stdio_read_func, fp); surface = read_png (stdio_read_func, fp);

Просмотреть файл

@ -176,6 +176,9 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
{ {
word_wrap_stream_t *stream; word_wrap_stream_t *stream;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (word_wrap_stream_t)); stream = malloc (sizeof (word_wrap_stream_t));
if (stream == NULL) { if (stream == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
@ -301,7 +304,7 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t *surface,
word_wrap = _word_wrap_stream_create (stream, 79); word_wrap = _word_wrap_stream_create (stream, 79);
status = _cairo_output_stream_get_status (word_wrap); status = _cairo_output_stream_get_status (word_wrap);
if (status) if (status)
return status; return _cairo_output_stream_destroy (word_wrap);
path_info.surface = surface; path_info.surface = surface;
path_info.stream = word_wrap; path_info.stream = word_wrap;
@ -851,6 +854,7 @@ _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_su
if (status != CAIRO_INT_STATUS_UNSUPPORTED) if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status; return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -869,6 +873,7 @@ _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subs
if (status != CAIRO_INT_STATUS_UNSUPPORTED) if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status; return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -937,7 +942,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double width, double width,
double height) double height)
{ {
cairo_status_t status; cairo_status_t status, status_ignored;
cairo_ps_surface_t *surface; cairo_ps_surface_t *surface;
surface = malloc (sizeof (cairo_ps_surface_t)); surface = malloc (sizeof (cairo_ps_surface_t));
@ -967,11 +972,13 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile); surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);
status = _cairo_output_stream_get_status (surface->stream); status = _cairo_output_stream_get_status (surface->stream);
if (status) if (status)
goto CLEANUP_TMPFILE; goto CLEANUP_OUTPUT_STREAM;
surface->font_subsets = _cairo_scaled_font_subsets_create_simple (); surface->font_subsets = _cairo_scaled_font_subsets_create_simple ();
if (! surface->font_subsets) if (surface->font_subsets == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_OUTPUT_STREAM; goto CLEANUP_OUTPUT_STREAM;
}
surface->eps = FALSE; surface->eps = FALSE;
surface->ps_level = CAIRO_PS_LEVEL_3; surface->ps_level = CAIRO_PS_LEVEL_3;
@ -995,22 +1002,21 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
width, height, width, height,
&cairo_ps_surface_paginated_backend); &cairo_ps_surface_paginated_backend);
if (surface->paginated_surface->status == CAIRO_STATUS_SUCCESS) status = surface->paginated_surface->status;
if (status == CAIRO_STATUS_SUCCESS)
return surface->paginated_surface; return surface->paginated_surface;
_cairo_scaled_font_subsets_destroy (surface->font_subsets); _cairo_scaled_font_subsets_destroy (surface->font_subsets);
CLEANUP_OUTPUT_STREAM: CLEANUP_OUTPUT_STREAM:
status = _cairo_output_stream_destroy (surface->stream); status_ignored = _cairo_output_stream_destroy (surface->stream);
/* Ignore status---we're already on a failure path. */
CLEANUP_TMPFILE:
fclose (surface->tmpfile); fclose (surface->tmpfile);
CLEANUP_SURFACE: CLEANUP_SURFACE:
free (surface); free (surface);
CLEANUP: CLEANUP:
/* destroy stream on behalf of caller */ /* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (stream); status_ignored = _cairo_output_stream_destroy (stream);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
} }
/** /**
@ -1042,15 +1048,11 @@ cairo_ps_surface_create (const char *filename,
double width_in_points, double width_in_points,
double height_in_points) double height_in_points)
{ {
cairo_status_t status;
cairo_output_stream_t *stream; cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_filename (filename); stream = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (stream); if (_cairo_output_stream_get_status (stream))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t*) &_cairo_surface_nil_write_error :
(cairo_surface_t*) &_cairo_surface_nil;
return _cairo_ps_surface_create_for_stream_internal (stream, return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points, width_in_points,
@ -1088,13 +1090,11 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
double width_in_points, double width_in_points,
double height_in_points) double height_in_points)
{ {
cairo_status_t status;
cairo_output_stream_t *stream; cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, NULL, closure); stream = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (stream); if (_cairo_output_stream_get_status (stream))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_ps_surface_create_for_stream_internal (stream, return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points, width_in_points,
@ -2031,13 +2031,13 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
string_array_stream = _string_array_stream_create (surface->stream); string_array_stream = _string_array_stream_create (surface->stream);
status = _cairo_output_stream_get_status (string_array_stream); status = _cairo_output_stream_get_status (string_array_stream);
if (status) if (status)
return status; return _cairo_output_stream_destroy (string_array_stream);
base85_stream = _cairo_base85_stream_create (string_array_stream); base85_stream = _cairo_base85_stream_create (string_array_stream);
status = _cairo_output_stream_get_status (base85_stream); status = _cairo_output_stream_get_status (base85_stream);
if (status) { if (status) {
status2 = _cairo_output_stream_destroy (string_array_stream); status2 = _cairo_output_stream_destroy (string_array_stream);
return status; return _cairo_output_stream_destroy (base85_stream);
} }
_cairo_output_stream_write (base85_stream, data, length); _cairo_output_stream_write (base85_stream, data, length);
@ -3255,9 +3255,10 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
_cairo_output_stream_printf (surface->stream, "<%02x> S\n", glyph_ids[i].glyph_id); _cairo_output_stream_printf (surface->stream, "<%02x> S\n", glyph_ids[i].glyph_id);
} else { } else {
word_wrap = _word_wrap_stream_create (surface->stream, 79); word_wrap = _word_wrap_stream_create (surface->stream, 79);
status = _cairo_output_stream_get_status (word_wrap); if (_cairo_output_stream_get_status (word_wrap)) {
if (status) status = _cairo_output_stream_destroy (word_wrap);
goto fail; goto fail;
}
_cairo_output_stream_printf (word_wrap, "<"); _cairo_output_stream_printf (word_wrap, "<");
for (j = i; j < last+1; j++) for (j = i; j < last+1; j++)

Просмотреть файл

@ -123,7 +123,7 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
unsigned int height); unsigned int height);
/* Load all extra symbols */ /* Load all extra symbols */
static void quartz_ensure_symbols() static void quartz_ensure_symbols(void)
{ {
if (_cairo_quartz_symbol_lookup_done) if (_cairo_quartz_symbol_lookup_done)
return; return;
@ -882,27 +882,16 @@ _cairo_quartz_teardown_source (cairo_quartz_surface_t *surface,
* get source/dest image implementation * get source/dest image implementation
*/ */
static void
ImageDataReleaseFunc(void *info, const void *data, size_t size)
{
if (data != NULL) {
free((void *) data);
}
}
/* Read the image from the surface's front buffer */ /* Read the image from the surface's front buffer */
static cairo_int_status_t static cairo_int_status_t
_cairo_quartz_get_image (cairo_quartz_surface_t *surface, _cairo_quartz_get_image (cairo_quartz_surface_t *surface,
cairo_image_surface_t **image_out, cairo_image_surface_t **image_out)
unsigned char **data_out)
{ {
unsigned char *imageData; unsigned char *imageData;
cairo_image_surface_t *isurf; cairo_image_surface_t *isurf;
if (IS_EMPTY(surface)) { if (IS_EMPTY(surface)) {
*image_out = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); *image_out = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
if (data_out)
*data_out = NULL;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1016,12 +1005,12 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface,
//ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface)); //ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface));
*image_extra = NULL; status = _cairo_quartz_get_image (surface, image_out);
status = _cairo_quartz_get_image (surface, image_out, NULL);
if (status) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1043,17 +1032,15 @@ _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
{ {
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t status; cairo_int_status_t status;
unsigned char *data;
ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface)); ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface));
*image_rect = surface->extents; status = _cairo_quartz_get_image (surface, image_out);
status = _cairo_quartz_get_image (surface, image_out, &data);
if (status) if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*image_extra = data; *image_rect = surface->extents;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1065,48 +1052,10 @@ _cairo_quartz_surface_release_dest_image (void *abstract_surface,
cairo_rectangle_int_t *image_rect, cairo_rectangle_int_t *image_rect,
void *image_extra) void *image_extra)
{ {
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; //cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
unsigned char *imageData = (unsigned char *) image_extra;
//ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface)); //ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface));
if (IS_EMPTY(surface)) {
cairo_surface_destroy ((cairo_surface_t*) image);
return;
}
if (!CGBitmapContextGetData (surface->cgContext)) {
CGDataProviderRef dataProvider;
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGImageRef img;
dataProvider = CGDataProviderCreateWithData (NULL, imageData,
surface->extents.width * surface->extents.height * 4,
ImageDataReleaseFunc);
img = CGImageCreate (surface->extents.width, surface->extents.height,
8, 32,
surface->extents.width * 4,
rgb,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider,
NULL,
false,
kCGRenderingIntentDefault);
CGColorSpaceRelease (rgb);
CGContextSetCompositeOperation (surface->cgContext, kPrivateCGCompositeCopy);
CGContextDrawImage (surface->cgContext,
CGRectMake (0, 0, surface->extents.width, surface->extents.height),
img);
CGImageRelease (img);
CGDataProviderRelease (dataProvider);
ND((stderr, "Image for surface %p was recovered from a bitmap\n", surface));
}
cairo_surface_destroy ((cairo_surface_t *) image); cairo_surface_destroy ((cairo_surface_t *) image);
} }
@ -1552,6 +1501,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
cairo_quartz_action_t action; cairo_quartz_action_t action;
float xprev, yprev; float xprev, yprev;
int i; int i;
CGFontRef cgfref;
if (IS_EMPTY(surface)) if (IS_EMPTY(surface))
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
@ -1581,7 +1531,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op)); CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
/* this doesn't addref */ /* this doesn't addref */
CGFontRef cgfref = _cairo_atsui_scaled_font_get_cg_font_ref (scaled_font); cgfref = _cairo_atsui_scaled_font_get_cg_font_ref (scaled_font);
CGContextSetFont (surface->cgContext, cgfref); CGContextSetFont (surface->cgContext, cgfref);
/* So this should include the size; I don't know if I need to extract the /* So this should include the size; I don't know if I need to extract the
@ -1882,10 +1832,8 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
/* Init the base surface */ /* Init the base surface */
surface = malloc(sizeof(cairo_quartz_surface_t)); surface = malloc(sizeof(cairo_quartz_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_quartz_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return NULL;
}
memset(surface, 0, sizeof(cairo_quartz_surface_t)); memset(surface, 0, sizeof(cairo_quartz_surface_t));
@ -1957,10 +1905,10 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
surf = _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA, surf = _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA,
width, height); width, height);
if (!surf) { if (surf->base.status) {
CGContextRelease (cgContext); CGContextRelease (cgContext);
// create_internal will have set an error // create_internal will have set an error
return (cairo_surface_t*) &_cairo_surface_nil; return (cairo_surface_t*) surf;
} }
return (cairo_surface_t *) surf; return (cairo_surface_t *) surf;
@ -1995,10 +1943,8 @@ cairo_quartz_surface_create (cairo_format_t format,
int bitsPerComponent; int bitsPerComponent;
// verify width and height of surface // verify width and height of surface
if (!verify_surface_size(width, height)) { if (!verify_surface_size(width, height))
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (width == 0 || height == 0) { if (width == 0 || height == 0) {
return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format), return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format),
@ -2028,18 +1974,15 @@ cairo_quartz_surface_create (cairo_format_t format,
* cairo_format_t -- these are 1-bit pixels stored in 32-bit * cairo_format_t -- these are 1-bit pixels stored in 32-bit
* quantities. * quantities.
*/ */
_cairo_error (CAIRO_STATUS_INVALID_FORMAT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
return (cairo_surface_t*) &_cairo_surface_nil;
} else { } else {
_cairo_error (CAIRO_STATUS_INVALID_FORMAT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
imageData = _cairo_malloc_ab (height, stride); imageData = _cairo_malloc_ab (height, stride);
if (!imageData) { if (!imageData) {
CGColorSpaceRelease (cgColorspace); CGColorSpaceRelease (cgColorspace);
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
/* zero the memory to match the image surface behaviour */ /* zero the memory to match the image surface behaviour */
memset (imageData, 0, height * stride); memset (imageData, 0, height * stride);
@ -2054,9 +1997,8 @@ cairo_quartz_surface_create (cairo_format_t format,
CGColorSpaceRelease (cgColorspace); CGColorSpaceRelease (cgColorspace);
if (!cgc) { if (!cgc) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
free (imageData); free (imageData);
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
} }
/* flip the Y axis */ /* flip the Y axis */
@ -2065,11 +2007,11 @@ cairo_quartz_surface_create (cairo_format_t format,
surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format), surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
width, height); width, height);
if (!surf) { if (surf->base.status) {
CGContextRelease (cgc); CGContextRelease (cgc);
free (imageData); free (imageData);
// create_internal will have set an error // create_internal will have set an error
return (cairo_surface_t*) &_cairo_surface_nil; return (cairo_surface_t*) surf;
} }
surf->imageData = imageData; surf->imageData = imageData;

Просмотреть файл

@ -121,6 +121,7 @@
#define cairo_paint _moz_cairo_paint #define cairo_paint _moz_cairo_paint
#define cairo_paint_with_alpha _moz_cairo_paint_with_alpha #define cairo_paint_with_alpha _moz_cairo_paint_with_alpha
#define cairo_path_destroy _moz_cairo_path_destroy #define cairo_path_destroy _moz_cairo_path_destroy
#define cairo_path_extents _moz_cairo_path_extents
#define cairo_pattern_add_color_stop_rgb _moz_cairo_pattern_add_color_stop_rgb #define cairo_pattern_add_color_stop_rgb _moz_cairo_pattern_add_color_stop_rgb
#define cairo_pattern_add_color_stop_rgba _moz_cairo_pattern_add_color_stop_rgba #define cairo_pattern_add_color_stop_rgba _moz_cairo_pattern_add_color_stop_rgba
#define cairo_pattern_create_for_surface _moz_cairo_pattern_create_for_surface #define cairo_pattern_create_for_surface _moz_cairo_pattern_create_for_surface
@ -288,3 +289,64 @@
#define cairo_xlib_surface_get_width _moz_cairo_xlib_surface_get_width #define cairo_xlib_surface_get_width _moz_cairo_xlib_surface_get_width
#define cairo_xlib_surface_set_drawable _moz_cairo_xlib_surface_set_drawable #define cairo_xlib_surface_set_drawable _moz_cairo_xlib_surface_set_drawable
#define cairo_xlib_surface_set_size _moz_cairo_xlib_surface_set_size #define cairo_xlib_surface_set_size _moz_cairo_xlib_surface_set_size
#define pixman_transform_point_3d _moz_pixman_transform_point_3d
#define pixman_region_set_static_pointers _moz_pixman_region_set_static_pointers
#define pixman_region_init _moz_pixman_region_init
#define pixman_region_init_rect _moz_pixman_region_init_rect
#define pixman_region_init_with_extents _moz_pixman_region_init_with_extents
#define pixman_region_fini _moz_pixman_region_fini
#define pixman_region_translate _moz_pixman_region_translate
#define pixman_region_copy _moz_pixman_region_copy
#define pixman_region_intersect _moz_pixman_region_intersect
#define pixman_region_union _moz_pixman_region_union
#define pixman_region_union_rect _moz_pixman_region_union_rect
#define pixman_region_subtract _moz_pixman_region_subtract
#define pixman_region_inverse _moz_pixman_region_inverse
#define pixman_region_contains_point _moz_pixman_region_contains_point
#define pixman_region_contains_rectangle _moz_pixman_region_contains_rectangle
#define pixman_region_not_empty _moz_pixman_region_not_empty
#define pixman_region_extents _moz_pixman_region_extents
#define pixman_region_n_rects _moz_pixman_region_n_rects
#define pixman_region_rectangles _moz_pixman_region_rectangles
#define pixman_region_equal _moz_pixman_region_equal
#define pixman_region_selfcheck _moz_pixman_region_selfcheck
#define pixman_region_reset _moz_pixman_region_reset
#define pixman_region_init_rects _moz_pixman_region_init_rects
#define pixman_blt _moz_pixman_blt
#define pixman_fill _moz_pixman_fill
#define pixman_image_create_solid_fill _moz_pixman_image_create_solid_fill
#define pixman_image_create_linear_gradient _moz_pixman_image_create_linear_gradient
#define pixman_image_create_radial_gradient _moz_pixman_image_create_radial_gradient
#define pixman_image_create_conical_gradient _moz_pixman_image_create_conical_gradient
#define pixman_image_create_bits _moz_pixman_image_create_bits
#define pixman_image_ref _moz_pixman_image_ref
#define pixman_image_unref _moz_pixman_image_unref
#define pixman_image_set_clip_region _moz_pixman_image_set_clip_region
#define pixman_image_set_has_client_clip _moz_pixman_image_set_has_client_clip
#define pixman_image_set_transform _moz_pixman_image_set_transform
#define pixman_image_set_repeat _moz_pixman_image_set_repeat
#define pixman_image_set_filter _moz_pixman_image_set_filter
#define pixman_image_set_filter_params _moz_pixman_image_set_filter_params
#define pixman_image_set_alpha_map _moz_pixman_image_set_alpha_map
#define pixman_image_set_component_alpha _moz_pixman_image_set_component_alpha
#define pixman_image_set_accessors _moz_pixman_image_set_accessors
#define pixman_image_set_indexed _moz_pixman_image_set_indexed
#define pixman_image_get_data _moz_pixman_image_get_data
#define pixman_image_get_width _moz_pixman_image_get_width
#define pixman_image_get_height _moz_pixman_image_get_height
#define pixman_image_get_stride _moz_pixman_image_get_stride
#define pixman_image_get_depth _moz_pixman_image_get_depth
#define pixman_image_fill_rectangles _moz_pixman_image_fill_rectangles
#define pixman_compute_composite_region _moz_pixman_compute_composite_region
#define pixman_image_composite _moz_pixman_image_composite
#define pixman_sample_ceil_y _moz_pixman_sample_ceil_y
#define pixman_sample_floor_y _moz_pixman_sample_floor_y
#define pixman_edge_step _moz_pixman_edge_step
#define pixman_edge_init _moz_pixman_edge_init
#define pixman_line_fixed_edge_init _moz_pixman_line_fixed_edge_init
#define pixman_rasterize_edges _moz_pixman_rasterize_edges
#define pixman_add_traps _moz_pixman_add_traps
#define pixman_add_trapezoids _moz_pixman_add_trapezoids
#define pixman_rasterize_trapezoid _moz_pixman_rasterize_trapezoid
#define pixman_transform_point_3d _moz_pixman_transform_point_3d

Просмотреть файл

@ -106,6 +106,11 @@ typedef struct _cairo_string_entry {
char *string; char *string;
} cairo_string_entry_t; } cairo_string_entry_t;
static cairo_status_t
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
cairo_scaled_font_subsets_glyph_t *subset_glyph);
static void static void
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph, _cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
unsigned long scaled_font_glyph_index) unsigned long scaled_font_glyph_index)
@ -221,6 +226,8 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_bool_t is_composite) cairo_bool_t is_composite)
{ {
cairo_sub_font_t *sub_font; cairo_sub_font_t *sub_font;
cairo_status_t status;
cairo_scaled_font_subsets_glyph_t subset_glyph;
sub_font = malloc (sizeof (cairo_sub_font_t)); sub_font = malloc (sizeof (cairo_sub_font_t));
if (sub_font == NULL) { if (sub_font == NULL) {
@ -246,9 +253,11 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
return NULL; return NULL;
} }
if (parent->type != CAIRO_SUBSETS_SCALED) { /* Reserve first glyph in subset for the .notdef glyph */
/* Reserve first glyph in subset for the .notdef glyph */ status = _cairo_sub_font_map_glyph (sub_font, 0, &subset_glyph);
sub_font->num_glyphs_in_current_subset++; if (status) {
_cairo_error_throw (status);
return NULL;
} }
return sub_font; return sub_font;
@ -307,6 +316,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
cairo_sub_font_glyph_t key, *sub_font_glyph; cairo_sub_font_glyph_t key, *sub_font_glyph;
cairo_status_t status; cairo_status_t status;
cairo_scaled_glyph_t *scaled_glyph; cairo_scaled_glyph_t *scaled_glyph;
cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base, if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
@ -317,10 +327,10 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
sub_font->current_subset++; sub_font->current_subset++;
sub_font->num_glyphs_in_current_subset = 0; sub_font->num_glyphs_in_current_subset = 0;
if (sub_font->parent->type != CAIRO_SUBSETS_SCALED) { /* Reserve first glyph in subset for the .notdef glyph */
/* Reserve first glyph in subset for the .notdef glyph */ status = _cairo_sub_font_map_glyph (sub_font, 0, &tmp_subset_glyph);
sub_font->num_glyphs_in_current_subset++; if (status)
} return status;
} }
status = _cairo_scaled_glyph_lookup (sub_font->scaled_font, status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
@ -381,16 +391,8 @@ _cairo_sub_font_collect (void *entry, void *closure)
for (i = 0; i <= sub_font->current_subset; i++) { for (i = 0; i <= sub_font->current_subset; i++) {
collection->subset_id = i; collection->subset_id = i;
collection->num_glyphs = 0;
if (sub_font->parent->type == CAIRO_SUBSETS_SCALED) { collection->max_glyph = 0;
collection->num_glyphs = 0;
collection->max_glyph = 0;
} else {
/* Assign .notdef glyph to the first glyph in the subset */
collection->glyphs[0] = 0;
collection->num_glyphs = 1;
collection->max_glyph = 0;
}
_cairo_hash_table_foreach (sub_font->sub_font_glyphs, _cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_collect, collection); _cairo_sub_font_glyph_collect, collection);

Просмотреть файл

@ -412,7 +412,7 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
/* ignore translation values in the ctm */ /* ignore translation values in the ctm */
scaled_font->ctm.x0 = 0.; scaled_font->ctm.x0 = 0.;
scaled_font->ctm.y0 = 0.; scaled_font->ctm.y0 = 0.;
scaled_font->options = *options; _cairo_font_options_init_copy (&scaled_font->options, options);
/* We do a bytewise hash on the font matrices */ /* We do a bytewise hash on the font matrices */
hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->font_matrix.xx), hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->font_matrix.xx),
@ -466,9 +466,11 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
cairo_matrix_t inverse; cairo_matrix_t inverse;
cairo_status_t status; cairo_status_t status;
status = cairo_font_options_status ((cairo_font_options_t *) options); if (options != NULL) {
if (status) status = cairo_font_options_status ((cairo_font_options_t *) options);
return status; if (status)
return status;
}
/* Initialize scaled_font->scale early for easier bail out on an /* Initialize scaled_font->scale early for easier bail out on an
* invalid matrix. */ * invalid matrix. */
@ -580,7 +582,8 @@ _cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font)
* @ctm: user to device transformation matrix with which the font will * @ctm: user to device transformation matrix with which the font will
* be used. * be used.
* @options: options to use when getting metrics for the font and * @options: options to use when getting metrics for the font and
* rendering with it. * rendering with it. A %NULL pointer will be interpreted as
* meaning the default options.
* *
* Creates a #cairo_scaled_font_t object from a font face and matrices that * Creates a #cairo_scaled_font_t object from a font face and matrices that
* describe the size of the font and the environment in which it will * describe the size of the font and the environment in which it will
@ -602,8 +605,11 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
if (font_face->status) if (font_face->status)
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
if (cairo_font_options_status ((cairo_font_options_t *) options)) if (options != NULL &&
cairo_font_options_status ((cairo_font_options_t *) options))
{
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
}
if (! _cairo_matrix_is_invertible (font_matrix)) if (! _cairo_matrix_is_invertible (font_matrix))
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
@ -901,15 +907,27 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
int num_glyphs; int num_glyphs;
if (scaled_font->status) if (scaled_font->status)
return; goto ZERO_EXTENTS;
if (utf8 == NULL)
goto ZERO_EXTENTS;
status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs); status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);
if (status) { if (status)
status = _cairo_scaled_font_set_error (scaled_font, status); goto ZERO_EXTENTS;
return;
}
cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents); cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);
free (glyphs); free (glyphs);
return;
ZERO_EXTENTS:
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
} }
/** /**
@ -945,7 +963,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
if (scaled_font->status) { if (scaled_font->status) {
extents->x_bearing = 0.0; extents->x_bearing = 0.0;
extents->y_bearing = 0.0; extents->y_bearing = 0.0;
extents->width = 0.0; extents->width = 0.0;
extents->height = 0.0; extents->height = 0.0;
extents->x_advance = 0.0; extents->x_advance = 0.0;
extents->y_advance = 0.0; extents->y_advance = 0.0;
@ -1098,7 +1116,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
if (ucs4) if (ucs4)
free (ucs4); free (ucs4);
return status; return _cairo_scaled_font_set_error (scaled_font, status);
} }
/* /*

Просмотреть файл

@ -1038,8 +1038,8 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
status = _cairo_surface_acquire_source_image (surface, status = _cairo_surface_acquire_source_image (surface,
&image, &image_extra); &image, &image_extra);
if (status != CAIRO_STATUS_SUCCESS) if (status)
return (cairo_surface_t *) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
snapshot = cairo_image_surface_create (image->format, snapshot = cairo_image_surface_create (image->format,
image->width, image->width,
@ -1068,7 +1068,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
if (status) { if (status) {
cairo_surface_destroy (snapshot); cairo_surface_destroy (snapshot);
return (cairo_surface_t *) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
} }
snapshot->device_transform = surface->device_transform; snapshot->device_transform = surface->device_transform;

Просмотреть файл

@ -78,10 +78,14 @@ const cairo_surface_t name = { \
} /* font_options */ \ } /* font_options */ \
} }
DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil); static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_file_error);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
static cairo_status_t static cairo_status_t
_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern, _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
@ -228,7 +232,7 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
cairo_format_t format = _cairo_format_from_content (content); cairo_format_t format = _cairo_format_from_content (content);
if (other->status) if (other->status)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (other->status);
if (other->backend->create_similar) { if (other->backend->create_similar) {
surface = other->backend->create_similar (other, content, width, height); surface = other->backend->create_similar (other, content, width, height);
@ -289,12 +293,10 @@ cairo_surface_create_similar (cairo_surface_t *other,
int height) int height)
{ {
if (other->status) if (other->status)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (other->status);
if (! CAIRO_CONTENT_VALID (content)) { if (! CAIRO_CONTENT_VALID (content))
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_surface_create_similar_solid (other, content, return _cairo_surface_create_similar_solid (other, content,
width, height, width, height,
@ -317,17 +319,14 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
surface = _cairo_surface_create_similar_scratch (other, content, surface = _cairo_surface_create_similar_scratch (other, content,
width, height); width, height);
if (surface->status) { if (surface->status)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return surface;
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (pattern == NULL) { if (pattern == NULL) {
source = _cairo_pattern_create_solid (color, content); source = _cairo_pattern_create_solid (color, content);
if (source->status) { if (source->status) {
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (source->status);
return (cairo_surface_t*) &_cairo_surface_nil;
} }
} else } else
source = pattern; source = pattern;
@ -342,8 +341,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
if (status) { if (status) {
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
_cairo_error_throw (status); return _cairo_surface_create_in_error (status);
return (cairo_surface_t*) &_cairo_surface_nil;
} }
return surface; return surface;
@ -1141,7 +1139,7 @@ cairo_surface_t *
_cairo_surface_snapshot (cairo_surface_t *surface) _cairo_surface_snapshot (cairo_surface_t *surface)
{ {
if (surface->finished) if (surface->finished)
return (cairo_surface_t *) &_cairo_surface_nil; return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
if (surface->backend->snapshot) if (surface->backend->snapshot)
return surface->backend->snapshot (surface); return surface->backend->snapshot (surface);
@ -2191,12 +2189,9 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
has_drawn_region = TRUE; has_drawn_region = TRUE;
has_clear_region = TRUE; has_clear_region = TRUE;
if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region) status = _cairo_region_subtract (&clear_region, &clear_region, &drawn_region);
!= CAIRO_STATUS_SUCCESS) if (status)
{
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_REGIONS; goto CLEANUP_REGIONS;
}
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE, status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
CAIRO_COLOR_TRANSPARENT, CAIRO_COLOR_TRANSPARENT,
@ -2412,5 +2407,31 @@ _cairo_surface_set_resolution (cairo_surface_t *surface,
surface->y_resolution = y_res; surface->y_resolution = y_res;
} }
cairo_surface_t *
_cairo_surface_create_in_error (cairo_status_t status)
{
switch (status) {
case CAIRO_STATUS_NO_MEMORY:
return (cairo_surface_t *) &_cairo_surface_nil;
case CAIRO_STATUS_INVALID_CONTENT:
return (cairo_surface_t *) &_cairo_surface_nil_invalid_content;
case CAIRO_STATUS_INVALID_FORMAT:
return (cairo_surface_t *) &_cairo_surface_nil_invalid_format;
case CAIRO_STATUS_INVALID_VISUAL:
return (cairo_surface_t *) &_cairo_surface_nil_invalid_visual;
case CAIRO_STATUS_READ_ERROR:
return (cairo_surface_t *) &_cairo_surface_nil_read_error;
case CAIRO_STATUS_WRITE_ERROR:
return (cairo_surface_t *) &_cairo_surface_nil_write_error;
case CAIRO_STATUS_FILE_NOT_FOUND:
return (cairo_surface_t *) &_cairo_surface_nil_file_not_found;
case CAIRO_STATUS_TEMP_FILE_ERROR:
return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
}
}
/* LocalWords: rasterized /* LocalWords: rasterized
*/ */

Просмотреть файл

@ -118,11 +118,12 @@ typedef struct {
cairo_meta_surface_t *meta; cairo_meta_surface_t *meta;
} cairo_meta_snapshot_t; } cairo_meta_snapshot_t;
static cairo_svg_document_t * static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *stream, _cairo_svg_document_create (cairo_output_stream_t *stream,
double width, double width,
double height, double height,
cairo_svg_version_t version); cairo_svg_version_t version,
cairo_svg_document_t **document_out);
static cairo_status_t static cairo_status_t
_cairo_svg_document_destroy (cairo_svg_document_t *document); _cairo_svg_document_destroy (cairo_svg_document_t *document);
@ -173,13 +174,11 @@ cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
double width, double width,
double height) double height)
{ {
cairo_status_t status;
cairo_output_stream_t *stream; cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, NULL, closure); stream = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (stream); if (_cairo_output_stream_get_status (stream))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
} }
@ -208,15 +207,11 @@ cairo_svg_surface_create (const char *filename,
double width, double width,
double height) double height)
{ {
cairo_status_t status;
cairo_output_stream_t *stream; cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_filename (filename); stream = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (stream); if (_cairo_output_stream_get_status (stream))
if (status) return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t *) &_cairo_surface_nil_write_error :
(cairo_surface_t *) &_cairo_surface_nil;
return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
} }
@ -332,13 +327,11 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
{ {
cairo_svg_surface_t *surface; cairo_svg_surface_t *surface;
cairo_surface_t *paginated; cairo_surface_t *paginated;
cairo_status_t status; cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_svg_surface_t)); surface = malloc (sizeof (cairo_svg_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_svg_surface_backend, _cairo_surface_init (&surface->base, &cairo_svg_surface_backend,
content); content);
@ -355,8 +348,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->is_base_clip_emitted = FALSE; surface->is_base_clip_emitted = FALSE;
surface->xml_node = _cairo_memory_stream_create (); surface->xml_node = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (surface->xml_node)) status = _cairo_output_stream_get_status (surface->xml_node);
goto CLEANUP_DOCUMENT; if (status)
goto CLEANUP;
_cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t)); _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t));
@ -366,8 +360,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
"style=\"opacity: 1; stroke: none; " "style=\"opacity: 1; stroke: none; "
"fill: rgb(0,0,0);\"/>\n", "fill: rgb(0,0,0);\"/>\n",
width, height); width, height);
if (_cairo_output_stream_get_status (surface->xml_node)) status = _cairo_output_stream_get_status (surface->xml_node);
goto CLEANUP_STREAM; if (status)
goto CLEANUP;
} }
surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
@ -379,18 +374,18 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->width, surface->width,
surface->height, surface->height,
&cairo_svg_surface_paginated_backend); &cairo_svg_surface_paginated_backend);
if (! paginated->status) status = paginated->status;
if (status == CAIRO_STATUS_SUCCESS)
return paginated; return paginated;
/* ignore status as we are on the error path */ /* ignore status as we are on the error path */
CLEANUP_STREAM: CLEANUP:
status = _cairo_output_stream_destroy (surface->xml_node); status_ignored = _cairo_output_stream_destroy (surface->xml_node);
CLEANUP_DOCUMENT: status_ignored = _cairo_svg_document_destroy (document);
status = _cairo_svg_document_destroy (document);
free (surface); free (surface);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
} }
static cairo_surface_t * static cairo_surface_t *
@ -399,23 +394,25 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double height, double height,
cairo_svg_version_t version) cairo_svg_version_t version)
{ {
cairo_svg_document_t *document; cairo_svg_document_t *document = NULL; /* silence compiler */
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_status_t status; cairo_status_t status;
document = _cairo_svg_document_create (stream, width, height, version); status = _cairo_svg_document_create (stream,
if (document == NULL) { width, height, version,
&document);
if (status) {
surface = _cairo_surface_create_in_error (status);
/* consume the output stream on behalf of caller */ /* consume the output stream on behalf of caller */
status = _cairo_output_stream_destroy (stream); status = _cairo_output_stream_destroy (stream);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return surface;
return (cairo_surface_t *) &_cairo_surface_nil;
} }
surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA, surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA,
width, height); width, height);
if (surface->status) { if (surface->status) {
status = _cairo_svg_document_destroy (document); status = _cairo_svg_document_destroy (document);
return (cairo_surface_t *) &_cairo_surface_nil; return surface;
} }
document->owner = surface; document->owner = surface;
@ -432,20 +429,21 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
unsigned int i; unsigned int i;
cairo_svg_page_t page; cairo_svg_page_t page;
cairo_output_stream_t *stream; cairo_output_stream_t *stream;
cairo_status_t status;
stream = _cairo_memory_stream_create (); stream = _cairo_memory_stream_create ();
if (stream->status) if (_cairo_output_stream_get_status (stream)) {
status = _cairo_output_stream_destroy (stream);
return NULL; return NULL;
}
page.surface_id = surface->id; page.surface_id = surface->id;
page.clip_level = surface->clip_level; page.clip_level = surface->clip_level;
page.xml_node = surface->xml_node; page.xml_node = surface->xml_node;
if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS) if (_cairo_array_append (&surface->page_set, &page)) {
{ status = _cairo_output_stream_destroy (stream);
cairo_status_t status = _cairo_output_stream_destroy (stream);
return NULL; return NULL;
(void) status;
} }
surface->xml_node = stream; surface->xml_node = stream;
@ -1960,8 +1958,8 @@ _cairo_svg_surface_paint (void *abstract_surface,
} }
surface->xml_node = _cairo_memory_stream_create (); surface->xml_node = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (surface->xml_node); if (_cairo_output_stream_get_status (surface->xml_node)) {
if (status) { status = _cairo_output_stream_destroy (surface->xml_node);
surface->xml_node = NULL; surface->xml_node = NULL;
return status; return status;
} }
@ -2006,9 +2004,8 @@ _cairo_svg_surface_mask (void *abstract_surface,
* document->xml_node_defs so we need to write the mask element to * document->xml_node_defs so we need to write the mask element to
* a temporary stream and then copy that to xml_node_defs. */ * a temporary stream and then copy that to xml_node_defs. */
mask_stream = _cairo_memory_stream_create (); mask_stream = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (mask_stream); if (_cairo_output_stream_get_status (mask_stream))
if (status) return _cairo_output_stream_destroy (mask_stream);
return status;
_cairo_output_stream_printf (mask_stream, _cairo_output_stream_printf (mask_stream,
"<mask id=\"mask%d\">\n" "<mask id=\"mask%d\">\n"
@ -2246,28 +2243,29 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
_cairo_svg_surface_fill_stroke _cairo_svg_surface_fill_stroke
}; };
static cairo_svg_document_t * static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *output_stream, _cairo_svg_document_create (cairo_output_stream_t *output_stream,
double width, double width,
double height, double height,
cairo_svg_version_t version) cairo_svg_version_t version,
cairo_svg_document_t **document_out)
{ {
cairo_svg_document_t *document; cairo_svg_document_t *document;
cairo_status_t status; cairo_status_t status, status_ignored;
if (output_stream->status) if (output_stream->status)
return NULL; return output_stream->status;
document = malloc (sizeof (cairo_svg_document_t)); document = malloc (sizeof (cairo_svg_document_t));
if (document == NULL) { if (document == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
/* The use of defs for font glyphs imposes no per-subset limit. */ /* The use of defs for font glyphs imposes no per-subset limit. */
document->font_subsets = _cairo_scaled_font_subsets_create_scaled (); document->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
if (document->font_subsets == NULL) if (document->font_subsets == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_DOCUMENT; goto CLEANUP_DOCUMENT;
}
document->output_stream = output_stream; document->output_stream = output_stream;
document->refcount = 1; document->refcount = 1;
@ -2285,12 +2283,14 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->mask_id = 0; document->mask_id = 0;
document->xml_node_defs = _cairo_memory_stream_create (); document->xml_node_defs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_defs)) status = _cairo_output_stream_get_status (document->xml_node_defs);
goto CLEANUP_FONT_SUBSETS; if (status)
goto CLEANUP_NODE_DEFS;
document->xml_node_glyphs = _cairo_memory_stream_create (); document->xml_node_glyphs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_glyphs)) status = _cairo_output_stream_get_status (document->xml_node_glyphs);
goto CLEANUP_NODE_DEFS; if (status)
goto CLEANUP_NODE_GLYPHS;
document->alpha_filter = FALSE; document->alpha_filter = FALSE;
@ -2299,15 +2299,17 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->svg_version = version; document->svg_version = version;
return document; *document_out = document;
return CAIRO_STATUS_SUCCESS;
CLEANUP_NODE_GLYPHS:
status_ignored = _cairo_output_stream_destroy (document->xml_node_glyphs);
CLEANUP_NODE_DEFS: CLEANUP_NODE_DEFS:
status = _cairo_output_stream_destroy (document->xml_node_defs); status_ignored = _cairo_output_stream_destroy (document->xml_node_defs);
CLEANUP_FONT_SUBSETS:
_cairo_scaled_font_subsets_destroy (document->font_subsets); _cairo_scaled_font_subsets_destroy (document->font_subsets);
CLEANUP_DOCUMENT: CLEANUP_DOCUMENT:
free (document); free (document);
return NULL; return status;
} }
static cairo_svg_document_t * static cairo_svg_document_t *

Просмотреть файл

@ -601,10 +601,8 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
cairo_type1_write_stream_encrypted, cairo_type1_write_stream_encrypted,
NULL, NULL,
font); font);
if (encrypted_output == NULL) { if (_cairo_output_stream_get_status (encrypted_output))
status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_output_stream_destroy (encrypted_output);
goto fail;
}
/* Note: the first four spaces at the start of this private dict /* Note: the first four spaces at the start of this private dict
* are the four "random" bytes of plaintext required by the * are the four "random" bytes of plaintext required by the
@ -697,6 +695,8 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
return status; return status;
font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font); font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
if (_cairo_output_stream_get_status (font->output))
return _cairo_output_stream_destroy (font->output);
status = cairo_type1_font_write (font, name); status = cairo_type1_font_write (font, name);
if (status) if (status)

Просмотреть файл

@ -1028,6 +1028,9 @@ cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font)
_cairo_output_stream_write (font->output, cleartomark_token, _cairo_output_stream_write (font->output, cleartomark_token,
font->type1_end - cleartomark_token); font->type1_end - cleartomark_token);
/* some fonts do not have a newline at the end of the last line */
_cairo_output_stream_printf (font->output, "\n");
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1126,9 +1129,10 @@ cairo_type1_font_subset_generate (void *abstract_font,
goto fail; goto fail;
font->output = _cairo_output_stream_create (type1_font_write, NULL, font); font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
status = _cairo_output_stream_get_status (font->output); if (_cairo_output_stream_get_status (font->output)) {
if (status) status = _cairo_output_stream_destroy (font->output);
goto fail; goto fail;
}
status = cairo_type1_font_subset_write (font, name); status = cairo_type1_font_subset_write (font, name);
if (status) if (status)

Просмотреть файл

@ -41,7 +41,7 @@
/* This is the only header file not including cairoint.h. It only contains /* This is the only header file not including cairoint.h. It only contains
* typedefs.*/ * typedefs.*/
#include "cairo.h" #include "cairo.h"
#include "cairo-fixed-private.h" #include "cairo-fixed-type-private.h"
typedef struct _cairo_array cairo_array_t; typedef struct _cairo_array cairo_array_t;
typedef struct _cairo_hash_table cairo_hash_table_t; typedef struct _cairo_hash_table cairo_hash_table_t;
@ -198,7 +198,7 @@ typedef struct _cairo_point_int16 {
} cairo_point_int16_t; } cairo_point_int16_t;
typedef struct _cairo_point_int32 { typedef struct _cairo_point_int32 {
int16_t x, y; int32_t x, y;
} cairo_point_int32_t; } cairo_point_int32_t;
typedef struct _cairo_box_int16 { typedef struct _cairo_box_int16 {

Просмотреть файл

@ -37,42 +37,7 @@
#ifndef CAIRO_WIDEINT_H #ifndef CAIRO_WIDEINT_H
#define CAIRO_WIDEINT_H #define CAIRO_WIDEINT_H
#if HAVE_STDINT_H #include "cairo-wideint-type-private.h"
# include <stdint.h>
#elif HAVE_INTTYPES_H
# include <inttypes.h>
#elif HAVE_SYS_INT_TYPES_H
# include <sys/int_types.h>
#elif defined(_MSC_VER)
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# ifndef HAVE_UINT64_T
# define HAVE_UINT64_T 1
# endif
# ifndef INT16_MIN
# define INT16_MIN (-32767-1)
# endif
# ifndef INT16_MAX
# define INT16_MAX (32767)
# endif
# ifndef UINT16_MAX
# define UINT16_MAX (65535)
# endif
# ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
# endif
# ifndef INT32_MAX
# define INT32_MAX (2147483647)
# endif
#else
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
#endif
#include "cairo-compiler-private.h" #include "cairo-compiler-private.h"
@ -86,10 +51,6 @@
#if !HAVE_UINT64_T #if !HAVE_UINT64_T
typedef struct _cairo_uint64 {
uint32_t lo, hi;
} cairo_uint64_t, cairo_int64_t;
cairo_uint64_t I _cairo_uint32_to_uint64 (uint32_t i); cairo_uint64_t I _cairo_uint32_to_uint64 (uint32_t i);
#define _cairo_uint64_to_uint32(a) ((a).lo) #define _cairo_uint64_to_uint32(a) ((a).lo)
cairo_uint64_t I _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b); cairo_uint64_t I _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b);
@ -125,9 +86,6 @@ int I _cairo_int64_lt (cairo_uint64_t a, cairo_uint64_t b);
#else #else
typedef uint64_t cairo_uint64_t;
typedef int64_t cairo_int64_t;
#define _cairo_uint32_to_uint64(i) ((uint64_t) (i)) #define _cairo_uint32_to_uint64(i) ((uint64_t) (i))
#define _cairo_uint64_to_uint32(i) ((uint32_t) (i)) #define _cairo_uint64_to_uint32(i) ((uint32_t) (i))
#define _cairo_uint64_add(a,b) ((a) + (b)) #define _cairo_uint64_add(a,b) ((a) + (b))
@ -181,16 +139,6 @@ typedef int64_t cairo_int64_t;
* a function which returns both for the 'native' type as well * a function which returns both for the 'native' type as well
*/ */
typedef struct _cairo_uquorem64 {
cairo_uint64_t quo;
cairo_uint64_t rem;
} cairo_uquorem64_t;
typedef struct _cairo_quorem64 {
cairo_int64_t quo;
cairo_int64_t rem;
} cairo_quorem64_t;
cairo_uquorem64_t I cairo_uquorem64_t I
_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den); _cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den);
@ -205,10 +153,6 @@ _cairo_int64_divrem (cairo_int64_t num, cairo_int64_t den);
#if !HAVE_UINT128_T #if !HAVE_UINT128_T
typedef struct cairo_uint128 {
cairo_uint64_t lo, hi;
} cairo_uint128_t, cairo_int128_t;
cairo_uint128_t I _cairo_uint32_to_uint128 (uint32_t i); cairo_uint128_t I _cairo_uint32_to_uint128 (uint32_t i);
cairo_uint128_t I _cairo_uint64_to_uint128 (cairo_uint64_t i); cairo_uint128_t I _cairo_uint64_to_uint128 (cairo_uint64_t i);
#define _cairo_uint128_to_uint64(a) ((a).lo) #define _cairo_uint128_to_uint64(a) ((a).lo)
@ -248,9 +192,6 @@ int I _cairo_int128_lt (cairo_int128_t a, cairo_int128_t b);
#else /* !HAVE_UINT128_T */ #else /* !HAVE_UINT128_T */
typedef uint128_t cairo_uint128_t;
typedef int128_t cairo_int128_t;
#define _cairo_uint32_to_uint128(i) ((uint128_t) (i)) #define _cairo_uint32_to_uint128(i) ((uint128_t) (i))
#define _cairo_uint64_to_uint128(i) ((uint128_t) (i)) #define _cairo_uint64_to_uint128(i) ((uint128_t) (i))
#define _cairo_uint128_to_uint64(i) ((uint64_t) (i)) #define _cairo_uint128_to_uint64(i) ((uint64_t) (i))
@ -290,16 +231,6 @@ typedef int128_t cairo_int128_t;
#endif /* HAVE_UINT128_T */ #endif /* HAVE_UINT128_T */
typedef struct _cairo_uquorem128 {
cairo_uint128_t quo;
cairo_uint128_t rem;
} cairo_uquorem128_t;
typedef struct _cairo_quorem128 {
cairo_int128_t quo;
cairo_int128_t rem;
} cairo_quorem128_t;
cairo_uquorem128_t I cairo_uquorem128_t I
_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den); _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den);

Просмотреть файл

@ -0,0 +1,130 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Keith Packard
*
* 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 Keith Packard
*
* Contributor(s):
* Keith R. Packard <keithp@keithp.com>
*
*/
#ifndef CAIRO_WIDEINT_TYPE_H
#define CAIRO_WIDEINT_TYPE_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#if HAVE_STDINT_H
# include <stdint.h>
#elif HAVE_INTTYPES_H
# include <inttypes.h>
#elif HAVE_SYS_INT_TYPES_H
# include <sys/int_types.h>
#elif defined(_MSC_VER)
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# ifndef HAVE_UINT64_T
# define HAVE_UINT64_T 1
# endif
# ifndef INT16_MIN
# define INT16_MIN (-32767-1)
# endif
# ifndef INT16_MAX
# define INT16_MAX (32767)
# endif
# ifndef UINT16_MAX
# define UINT16_MAX (65535)
# endif
# ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
# endif
# ifndef INT32_MAX
# define INT32_MAX (2147483647)
# endif
#else
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
#endif
#if !HAVE_UINT64_T
typedef struct _cairo_uint64 {
uint32_t lo, hi;
} cairo_uint64_t, cairo_int64_t;
#else
typedef uint64_t cairo_uint64_t;
typedef int64_t cairo_int64_t;
#endif
typedef struct _cairo_uquorem64 {
cairo_uint64_t quo;
cairo_uint64_t rem;
} cairo_uquorem64_t;
typedef struct _cairo_quorem64 {
cairo_int64_t quo;
cairo_int64_t rem;
} cairo_quorem64_t;
#if !HAVE_UINT128_T
typedef struct cairo_uint128 {
cairo_uint64_t lo, hi;
} cairo_uint128_t, cairo_int128_t;
#else
typedef uint128_t cairo_uint128_t;
typedef int128_t cairo_int128_t;
#endif
typedef struct _cairo_uquorem128 {
cairo_uint128_t quo;
cairo_uint128_t rem;
} cairo_uquorem128_t;
typedef struct _cairo_quorem128 {
cairo_int128_t quo;
cairo_int128_t rem;
} cairo_quorem128_t;
#endif /* CAIRO_WIDEINT_H */

Просмотреть файл

@ -273,7 +273,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
* XXX: The other option we could pay attention to, but don't * XXX: The other option we could pay attention to, but don't
* here is the hint_metrics options. * here is the hint_metrics options.
*/ */
if (options->antialias == CAIRO_ANTIALIAS_DEFAULT) if (options == NULL || options->antialias == CAIRO_ANTIALIAS_DEFAULT)
f->quality = _get_system_quality (); f->quality = _get_system_quality ();
else { else {
switch (options->antialias) { switch (options->antialias) {
@ -300,7 +300,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
if (f->quality == logfont->lfQuality || if (f->quality == logfont->lfQuality ||
(logfont->lfQuality == DEFAULT_QUALITY && (logfont->lfQuality == DEFAULT_QUALITY &&
options->antialias == CAIRO_ANTIALIAS_DEFAULT)) { (options == NULL || options->antialias == CAIRO_ANTIALIAS_DEFAULT))) {
/* If face_hfont is non-NULL, then we can use it to avoid creating our /* If face_hfont is non-NULL, then we can use it to avoid creating our
* own --- because the constraints on face_hfont mentioned above * own --- because the constraints on face_hfont mentioned above
* guarantee it was created in exactly the same way that * guarantee it was created in exactly the same way that

Просмотреть файл

@ -70,8 +70,11 @@
# define FEATURESETTING_PSLEVEL 0x0002 # define FEATURESETTING_PSLEVEL 0x0002
#endif #endif
#if !defined(GRADIENT_FILL_RECT_H)
# define GRADIENT_FILL_RECT_H 0x00
#endif
#define PELS_72DPI ((LONG)(72. / 0.0254)) #define PELS_72DPI ((LONG)(72. / 0.0254))
#define NIL_SURFACE ((cairo_surface_t*)&_cairo_surface_nil)
static const cairo_surface_backend_t cairo_win32_printing_surface_backend; static const cairo_surface_backend_t cairo_win32_printing_surface_backend;
static const cairo_paginated_surface_backend_t cairo_win32_surface_paginated_backend; static const cairo_paginated_surface_backend_t cairo_win32_surface_paginated_backend;
@ -457,11 +460,14 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
EndPath (surface->dc); EndPath (surface->dc);
SelectClipPath (surface->dc, RGN_AND); SelectClipPath (surface->dc, RGN_AND);
SaveDC (surface->dc); /* Allow clip path to be reset during replay */
status = _cairo_meta_surface_replay (meta_surface, &surface->base); status = _cairo_meta_surface_replay (meta_surface, &surface->base);
/* Restore both the clip save and our earlier path SaveDC */
RestoreDC (surface->dc, -2);
if (status) if (status)
return status; return status;
RestoreDC (surface->dc, -1);
} }
} }
@ -967,9 +973,8 @@ _cairo_win32_printing_surface_show_page (void *abstract_surface)
{ {
cairo_win32_surface_t *surface = abstract_surface; cairo_win32_surface_t *surface = abstract_surface;
if (surface->clip_saved_dc != 0) /* Undo both SaveDC's that we did in start_page */
RestoreDC (surface->dc, surface->clip_saved_dc); RestoreDC (surface->dc, -2);
RestoreDC (surface->dc, -1);
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -988,10 +993,9 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
if (path == NULL) { if (path == NULL) {
if (surface->clip_saved_dc != 0) { RestoreDC (surface->dc, -1);
RestoreDC (surface->dc, surface->clip_saved_dc); SaveDC (surface->dc);
surface->clip_saved_dc = 0;
}
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1010,8 +1014,6 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
ASSERT_NOT_REACHED; ASSERT_NOT_REACHED;
} }
if (surface->clip_saved_dc == 0)
surface->clip_saved_dc = SaveDC (surface->dc);
SelectClipPath (surface->dc, RGN_AND); SelectClipPath (surface->dc, RGN_AND);
return status; return status;
@ -1326,9 +1328,9 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
color = _cairo_win32_printing_surface_flatten_transparency (surface, color = _cairo_win32_printing_surface_flatten_transparency (surface,
&solid->color); &solid->color);
opaque = cairo_pattern_create_rgb (GetRValue (color), opaque = cairo_pattern_create_rgb (GetRValue (color) / 255.0,
GetGValue (color), GetGValue (color) / 255.0,
GetBValue (color)); GetBValue (color) / 255.0);
if (opaque->status) if (opaque->status)
return opaque->status; return opaque->status;
source = opaque; source = opaque;
@ -1414,7 +1416,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
cairo_win32_surface_t *surface = abstract_surface; cairo_win32_surface_t *surface = abstract_surface;
XFORM xform; XFORM xform;
SaveDC (surface->dc); SaveDC (surface->dc); /* Save application context first, before doing MWT */
SetGraphicsMode (surface->dc, GM_ADVANCED); SetGraphicsMode (surface->dc, GM_ADVANCED);
GetWorldTransform(surface->dc, &xform); GetWorldTransform(surface->dc, &xform);
surface->ctm.xx = xform.eM11; surface->ctm.xx = xform.eM11;
@ -1427,6 +1430,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY)) if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform"); return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
SaveDC (surface->dc); /* Then save Cairo's known-good clip state, so the clip path can be reset */
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -1459,22 +1464,16 @@ cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc) cairo_win32_printing_surface_create (HDC hdc)
{ {
cairo_win32_surface_t *surface; cairo_win32_surface_t *surface;
RECT rect;
int xr, yr; int xr, yr;
RECT rect;
/* Try to figure out the drawing bounds for the Device context
*/
if (GetClipBox (hdc, &rect) == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
/* XXX: Can we make a more reasonable guess at the error cause here? */
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
}
surface = malloc (sizeof (cairo_win32_surface_t)); surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return NIL_SURFACE;
if (_cairo_win32_save_initial_clip (hdc, surface) != CAIRO_STATUS_SUCCESS) {
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
} }
surface->image = NULL; surface->image = NULL;
@ -1488,28 +1487,14 @@ cairo_win32_printing_surface_create (HDC hdc)
surface->brush = NULL; surface->brush = NULL;
surface->old_brush = NULL; surface->old_brush = NULL;
surface->clip_rect.x = (int16_t) rect.left; GetClipBox(hdc, &rect);
surface->clip_rect.y = (int16_t) rect.top; surface->extents.x = rect.left;
surface->clip_rect.width = (uint16_t) (rect.right - rect.left); surface->extents.y = rect.top;
surface->clip_rect.height = (uint16_t) (rect.bottom - rect.top); surface->extents.width = rect.right - rect.left;
surface->extents.height = rect.bottom - rect.top;
if (surface->clip_rect.width == 0 ||
surface->clip_rect.height == 0)
{
surface->saved_clip = NULL;
} else {
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
if (GetClipRgn (hdc, surface->saved_clip) == 0) {
DeleteObject(surface->saved_clip);
surface->saved_clip = NULL;
}
}
surface->extents = surface->clip_rect;
surface->flags = _cairo_win32_flags_for_dc (surface->dc); surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING; surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
surface->clip_saved_dc = 0;
_cairo_win32_printing_surface_init_ps_mode (surface); _cairo_win32_printing_surface_init_ps_mode (surface);
_cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend, _cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend,
@ -1521,8 +1506,8 @@ cairo_win32_printing_surface_create (HDC hdc)
return _cairo_paginated_surface_create (&surface->base, return _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
rect.right - rect.left, surface->extents.width,
rect.bottom - rect.top, surface->extents.height,
&cairo_win32_surface_paginated_backend); &cairo_win32_surface_paginated_backend);
} }

Просмотреть файл

@ -71,12 +71,17 @@ typedef struct _cairo_win32_surface {
cairo_surface_t *image; cairo_surface_t *image;
cairo_rectangle_int_t clip_rect;
HRGN saved_clip;
cairo_rectangle_int_t extents; cairo_rectangle_int_t extents;
/* Initial clip bits
* We need these kept around so that we maintain
* whatever clip was set on the original DC at creation
* time when cairo is asked to reset the surface clip.
*/
cairo_rectangle_int_t clip_rect;
HRGN initial_clip_rgn;
cairo_bool_t had_simple_clip;
/* Surface DC flags */ /* Surface DC flags */
uint32_t flags; uint32_t flags;
@ -86,7 +91,6 @@ typedef struct _cairo_win32_surface {
cairo_bool_t path_empty; cairo_bool_t path_empty;
cairo_bool_t has_ctm; cairo_bool_t has_ctm;
cairo_matrix_t ctm; cairo_matrix_t ctm;
int clip_saved_dc;
HBRUSH brush, old_brush; HBRUSH brush, old_brush;
} cairo_win32_surface_t; } cairo_win32_surface_t;
@ -168,4 +172,13 @@ _cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
xform->eDy = (FLOAT) m->y0; xform->eDy = (FLOAT) m->y0;
} }
cairo_int_status_t
_cairo_win32_save_initial_clip (HDC dc, cairo_win32_surface_t *surface);
cairo_int_status_t
_cairo_win32_restore_initial_clip (cairo_win32_surface_t *surface);
void
_cairo_win32_debug_dump_hrgn (HRGN rgn, char *header);
#endif /* CAIRO_WIN32_PRIVATE_H */ #endif /* CAIRO_WIN32_PRIVATE_H */

Просмотреть файл

@ -67,7 +67,6 @@
#endif #endif
#define PELS_72DPI ((LONG)(72. / 0.0254)) #define PELS_72DPI ((LONG)(72. / 0.0254))
#define NIL_SURFACE ((cairo_surface_t*)&_cairo_surface_nil)
static const cairo_surface_backend_t cairo_win32_surface_backend; static const cairo_surface_backend_t cairo_win32_surface_backend;
@ -333,10 +332,8 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
int rowstride; int rowstride;
surface = malloc (sizeof (cairo_win32_surface_t)); surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return NIL_SURFACE;
}
status = _create_dc_and_bitmap (surface, original_dc, format, status = _create_dc_and_bitmap (surface, original_dc, format,
width, height, width, height,
@ -346,10 +343,9 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->image = cairo_image_surface_create_for_data (bits, format, surface->image = cairo_image_surface_create_for_data (bits, format,
width, height, rowstride); width, height, rowstride);
if (surface->image->status) { status = surface->image->status;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY); if (status)
goto FAIL; goto FAIL;
}
surface->format = format; surface->format = format;
@ -358,14 +354,15 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->clip_rect.width = width; surface->clip_rect.width = width;
surface->clip_rect.height = height; surface->clip_rect.height = height;
surface->saved_clip = NULL; surface->initial_clip_rgn = NULL;
surface->had_simple_clip = FALSE;
surface->extents = surface->clip_rect; surface->extents = surface->clip_rect;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend, _cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format)); _cairo_content_from_format (format));
return (cairo_surface_t *)surface; return &surface->base;
FAIL: FAIL:
if (surface->bitmap) { if (surface->bitmap) {
@ -373,10 +370,9 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
DeleteObject (surface->bitmap); DeleteObject (surface->bitmap);
DeleteDC (surface->dc); DeleteDC (surface->dc);
} }
if (surface) free (surface);
free (surface);
return NIL_SURFACE; return _cairo_surface_create_in_error (status);
} }
static cairo_surface_t * static cairo_surface_t *
@ -478,26 +474,11 @@ _cairo_win32_surface_finish (void *abstract_surface)
DeleteObject (surface->bitmap); DeleteObject (surface->bitmap);
DeleteDC (surface->dc); DeleteDC (surface->dc);
} else { } else {
/* otherwise, restore the old clip region on the DC */ _cairo_win32_restore_initial_clip (surface);
SelectClipRgn (surface->dc, surface->saved_clip);
if (surface->saved_clip == NULL) {
/* We never had a clip region, so just restore the clip
* to the bounds. */
if (surface->clip_rect.width != 0 &&
surface->clip_rect.height != 0)
{
IntersectClipRect (surface->dc,
surface->clip_rect.x,
surface->clip_rect.y,
surface->clip_rect.x + surface->clip_rect.width,
surface->clip_rect.y + surface->clip_rect.height);
}
}
} }
if (surface->saved_clip) if (surface->initial_clip_rgn)
DeleteObject (surface->saved_clip); DeleteObject (surface->initial_clip_rgn);
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
@ -570,8 +551,8 @@ _cairo_win32_surface_acquire_source_image (void *abstract_sur
} }
status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
surface->clip_rect.width, surface->extents.width,
surface->clip_rect.height, &local); surface->extents.height, &local);
if (status) if (status)
return status; return status;
@ -610,8 +591,8 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
image_rect->x = 0; image_rect->x = 0;
image_rect->y = 0; image_rect->y = 0;
image_rect->width = surface->clip_rect.width; image_rect->width = surface->extents.width;
image_rect->height = surface->clip_rect.height; image_rect->height = surface->extents.height;
*image_out = (cairo_image_surface_t *)surface->image; *image_out = (cairo_image_surface_t *)surface->image;
*image_extra = NULL; *image_extra = NULL;
@ -1445,13 +1426,11 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
* save the original clip when first setting a clip on surface. * save the original clip when first setting a clip on surface.
*/ */
if (region == NULL) { /* Clear any clip set by cairo, return to the original first */
/* Clear any clip set by cairo, return to the original */ status = _cairo_win32_restore_initial_clip (surface);
if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
status = CAIRO_STATUS_SUCCESS; /* Then combine any new region with it */
} else { if (region) {
cairo_rectangle_int_t extents; cairo_rectangle_int_t extents;
cairo_box_int_t *boxes; cairo_box_int_t *boxes;
int num_boxes; int num_boxes;
@ -1485,6 +1464,13 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
_cairo_region_boxes_fini (region, boxes); _cairo_region_boxes_fini (region, boxes);
} else { } else {
/* XXX see notes in _cairo_win32_save_initial_clip --
* this code will interact badly with a HDC which had an initial
* world transform -- we should probably manually transform the
* region rects, because SelectClipRgn takes device units, not
* logical units (unlike IntersectClipRect).
*/
data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT); data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
data = malloc (data_size); data = malloc (data_size);
if (!data) { if (!data) {
@ -1517,17 +1503,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
if (!gdi_region) if (!gdi_region)
return _cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* Combine the new region with the original clip */ /* AND the new region into our DC */
if (surface->saved_clip) { if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR) status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
}
/* Then select the new clip region into our surface if everything went ok */
if (status == CAIRO_STATUS_SUCCESS) {
if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
}
DeleteObject (gdi_region); DeleteObject (gdi_region);
} }
@ -1709,20 +1687,10 @@ cairo_surface_t *
cairo_win32_surface_create (HDC hdc) cairo_win32_surface_create (HDC hdc)
{ {
cairo_win32_surface_t *surface; cairo_win32_surface_t *surface;
RECT rect;
int depth; int depth;
cairo_format_t format; cairo_format_t format;
int clipBoxType; RECT rect;
/* Try to figure out the drawing bounds for the Device context
*/
clipBoxType = GetClipBox (hdc, &rect);
if (clipBoxType == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
/* XXX: Can we make a more reasonable guess at the error cause here? */
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
}
if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) { if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
depth = GetDeviceCaps(hdc, BITSPIXEL); depth = GetDeviceCaps(hdc, BITSPIXEL);
@ -1738,17 +1706,19 @@ cairo_win32_surface_create (HDC hdc)
format = CAIRO_FORMAT_A1; format = CAIRO_FORMAT_A1;
else { else {
_cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)"); _cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
return NIL_SURFACE;
} }
} else { } else {
format = CAIRO_FORMAT_RGB24; format = CAIRO_FORMAT_RGB24;
} }
surface = malloc (sizeof (cairo_win32_surface_t)); surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return NIL_SURFACE;
if (_cairo_win32_save_initial_clip (hdc, surface) != CAIRO_STATUS_SUCCESS) {
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
} }
surface->image = NULL; surface->image = NULL;
@ -1761,26 +1731,13 @@ cairo_win32_surface_create (HDC hdc)
surface->brush = NULL; surface->brush = NULL;
surface->old_brush = NULL; surface->old_brush = NULL;
surface->clip_rect.x = (int16_t) rect.left; GetClipBox(hdc, &rect);
surface->clip_rect.y = (int16_t) rect.top; surface->extents.x = rect.left;
surface->clip_rect.width = (uint16_t) (rect.right - rect.left); surface->extents.y = rect.top;
surface->clip_rect.height = (uint16_t) (rect.bottom - rect.top); surface->extents.width = rect.right - rect.left;
surface->extents.height = rect.bottom - rect.top;
if (clipBoxType == COMPLEXREGION) {
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
if (GetClipRgn (hdc, surface->saved_clip) == 0) {
/* this should never happen */
DeleteObject(surface->saved_clip);
surface->saved_clip = NULL;
}
} else {
surface->saved_clip = NULL;
}
surface->extents = surface->clip_rect;
surface->flags = _cairo_win32_flags_for_dc (surface->dc); surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->clip_saved_dc = 0;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend, _cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format)); _cairo_content_from_format (format));
@ -1837,7 +1794,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
HBITMAP saved_dc_bitmap; HBITMAP saved_dc_bitmap;
if (format != CAIRO_FORMAT_RGB24) if (format != CAIRO_FORMAT_RGB24)
return NIL_SURFACE; return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
/* XXX handle these eventually /* XXX handle these eventually
format != CAIRO_FORMAT_A8 || format != CAIRO_FORMAT_A8 ||
format != CAIRO_FORMAT_A1) format != CAIRO_FORMAT_A1)
@ -1853,7 +1810,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
ddb_dc = CreateCompatibleDC (hdc); ddb_dc = CreateCompatibleDC (hdc);
if (ddb_dc == NULL) { if (ddb_dc == NULL) {
_cairo_win32_print_gdi_error("CreateCompatibleDC"); _cairo_win32_print_gdi_error("CreateCompatibleDC");
new_surf = (cairo_win32_surface_t*) NIL_SURFACE; new_surf = (cairo_win32_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto FINISH; goto FINISH;
} }
@ -1866,7 +1823,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
* video memory is probably exhausted. * video memory is probably exhausted.
*/ */
_cairo_win32_print_gdi_error("CreateCompatibleBitmap"); _cairo_win32_print_gdi_error("CreateCompatibleBitmap");
new_surf = (cairo_win32_surface_t*) NIL_SURFACE; new_surf = (cairo_win32_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto FINISH; goto FINISH;
} }
@ -2050,3 +2007,120 @@ DllMain (HINSTANCE hinstDLL,
#endif #endif
cairo_int_status_t
_cairo_win32_save_initial_clip (HDC hdc, cairo_win32_surface_t *surface)
{
RECT rect;
int clipBoxType;
int gm;
XFORM saved_xform;
/* GetClipBox/GetClipRgn and friends interact badly with a world transform
* set. GetClipBox returns values in logical (transformed) coordinates;
* it's unclear what GetClipRgn returns, because the region is empty in the
* case of a SIMPLEREGION clip, but I assume device (untransformed) coordinates.
* Similarily, IntersectClipRect works in logical units, whereas SelectClipRgn
* works in device units.
*
* So, avoid the whole mess and get rid of the world transform
* while we store our initial data and when we restore initial coordinates.
*
* XXX we may need to modify x/y by the ViewportOrg or WindowOrg
* here in GM_COMPATIBLE; unclear.
*/
gm = GetGraphicsMode (hdc);
if (gm == GM_ADVANCED) {
GetWorldTransform (hdc, &saved_xform);
ModifyWorldTransform (hdc, NULL, MWT_IDENTITY);
}
clipBoxType = GetClipBox (hdc, &rect);
if (clipBoxType == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
SetGraphicsMode (hdc, gm);
/* XXX: Can we make a more reasonable guess at the error cause here? */
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
surface->clip_rect.x = rect.left;
surface->clip_rect.y = rect.top;
surface->clip_rect.width = rect.right - rect.left;
surface->clip_rect.height = rect.bottom - rect.top;
surface->initial_clip_rgn = NULL;
surface->had_simple_clip = FALSE;
if (clipBoxType == COMPLEXREGION) {
surface->initial_clip_rgn = CreateRectRgn (0, 0, 0, 0);
if (GetClipRgn (hdc, surface->initial_clip_rgn) == -1) {
/* this should never happen */
DeleteObject(surface->initial_clip_rgn);
surface->initial_clip_rgn = NULL;
}
} else if (clipBoxType == SIMPLEREGION) {
surface->had_simple_clip = TRUE;
}
if (gm == GM_ADVANCED)
SetWorldTransform (hdc, &saved_xform);
return CAIRO_STATUS_SUCCESS;
}
cairo_int_status_t
_cairo_win32_restore_initial_clip (cairo_win32_surface_t *surface)
{
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
XFORM saved_xform;
int gm = GetGraphicsMode (surface->dc);
if (gm == GM_ADVANCED) {
GetWorldTransform (surface->dc, &saved_xform);
ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY);
}
/* initial_clip_rgn will either be a real region or NULL (which means reset to no clip region) */
SelectClipRgn (surface->dc, surface->initial_clip_rgn);
if (surface->had_simple_clip) {
/* then if we had a simple clip, intersect */
IntersectClipRect (surface->dc,
surface->clip_rect.x,
surface->clip_rect.y,
surface->clip_rect.x + surface->clip_rect.width,
surface->clip_rect.y + surface->clip_rect.height);
}
if (gm == GM_ADVANCED)
SetWorldTransform (surface->dc, &saved_xform);
return status;
}
void
_cairo_win32_debug_dump_hrgn (HRGN rgn, char *header)
{
RGNDATA *rd;
int z;
if (header)
fprintf (stderr, "%s\n", header);
if (rgn == NULL) {
fprintf (stderr, " NULL\n");
}
z = GetRegionData(rgn, 0, NULL);
rd = (RGNDATA*) malloc(z);
z = GetRegionData(rgn, z, rd);
fprintf (stderr, " %d rects, bounds: %d %d %d %d\n", rd->rdh.nCount, rd->rdh.rcBound.left, rd->rdh.rcBound.top, rd->rdh.rcBound.right - rd->rdh.rcBound.left, rd->rdh.rcBound.bottom - rd->rdh.rcBound.top);
for (z = 0; z < rd->rdh.nCount; z++) {
RECT r = ((RECT*)rd->Buffer)[z];
fprintf (stderr, " [%d]: [%d %d %d %d]\n", z, r.left, r.top, r.right - r.left, r.bottom - r.top);
}
free(rd);
fflush (stderr);
}

Просмотреть файл

@ -196,10 +196,8 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
cairo_xcb_surface_create_with_xrender_format (dpy, pixmap, src->screen, cairo_xcb_surface_create_with_xrender_format (dpy, pixmap, src->screen,
xrender_format, xrender_format,
width, height); width, height);
if (surface->base.status) { if (surface->base.status)
_cairo_error (CAIRO_STATUS_NO_MEMORY); return surface;
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface->owns_pixmap = TRUE; surface->owns_pixmap = TRUE;
@ -315,7 +313,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
y2 = surface->height; y2 = surface->height;
if (interest_rect) { if (interest_rect) {
cairo_rectangle_int16_t rect; cairo_rectangle_int_t rect;
rect.x = interest_rect->x; rect.x = interest_rect->x;
rect.y = interest_rect->y; rect.y = interest_rect->y;
@ -1730,10 +1728,8 @@ _cairo_xcb_surface_create_internal (xcb_connection_t *dpy,
const xcb_render_query_version_reply_t *r; const xcb_render_query_version_reply_t *r;
surface = malloc (sizeof (cairo_xcb_surface_t)); surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL) { if (surface == NULL)
_cairo_error (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (xrender_format) { if (xrender_format) {
depth = xrender_format->depth; depth = xrender_format->depth;
@ -1873,10 +1869,8 @@ cairo_xcb_surface_create (xcb_connection_t *c,
{ {
xcb_screen_t *screen = _cairo_xcb_screen_from_visual (c, visual); xcb_screen_t *screen = _cairo_xcb_screen_from_visual (c, visual);
if (screen == NULL) { if (screen == NULL)
_cairo_error (CAIRO_STATUS_INVALID_VISUAL); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
return (cairo_surface_t*) &_cairo_surface_nil;
}
return _cairo_xcb_surface_create_internal (c, drawable, screen, return _cairo_xcb_surface_create_internal (c, drawable, screen,
visual, NULL, visual, NULL,

Просмотреть файл

@ -125,9 +125,6 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
cairo_xlib_display_t * cairo_xlib_display_t *
_cairo_xlib_display_reference (cairo_xlib_display_t *display) _cairo_xlib_display_reference (cairo_xlib_display_t *display)
{ {
if (display == NULL)
return NULL;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count)); assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
_cairo_reference_count_inc (&display->ref_count); _cairo_reference_count_inc (&display->ref_count);
@ -138,9 +135,6 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *display)
void void
_cairo_xlib_display_destroy (cairo_xlib_display_t *display) _cairo_xlib_display_destroy (cairo_xlib_display_t *display)
{ {
if (display == NULL)
return;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count)); assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
if (! _cairo_reference_count_dec_and_test (&display->ref_count)) if (! _cairo_reference_count_dec_and_test (&display->ref_count))
@ -213,6 +207,7 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
} }
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
assert (display != NULL);
_cairo_xlib_display_destroy (display); _cairo_xlib_display_destroy (display);
/* Return value in accordance with requirements of /* Return value in accordance with requirements of

Просмотреть файл

@ -244,9 +244,6 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in
cairo_xlib_screen_info_t * cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info) _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
{ {
if (info == NULL)
return NULL;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
_cairo_reference_count_inc (&info->ref_count); _cairo_reference_count_inc (&info->ref_count);
@ -273,9 +270,6 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
cairo_xlib_screen_info_t **prev; cairo_xlib_screen_info_t **prev;
cairo_xlib_screen_info_t *list; cairo_xlib_screen_info_t *list;
if (info == NULL)
return;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
if (! _cairo_reference_count_dec_and_test (&info->ref_count)) if (! _cairo_reference_count_dec_and_test (&info->ref_count))

Просмотреть файл

@ -176,10 +176,9 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen, cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
xrender_format, xrender_format,
width, height); width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) { if (surface->base.status) {
XFreePixmap (dpy, pix); XFreePixmap (dpy, pix);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return &surface->base;
return (cairo_surface_t*) &_cairo_surface_nil;
} }
surface->owns_pixmap = TRUE; surface->owns_pixmap = TRUE;
@ -258,8 +257,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
width, height); width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) { if (surface->base.status != CAIRO_STATUS_SUCCESS) {
XFreePixmap (src->dpy, pix); XFreePixmap (src->dpy, pix);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return &surface->base;
return (cairo_surface_t*) &_cairo_surface_nil;
} }
surface->owns_pixmap = TRUE; surface->owns_pixmap = TRUE;
@ -475,7 +473,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
y2 = surface->height; y2 = surface->height;
if (interest_rect) { if (interest_rect) {
cairo_rectangle_int16_t rect; cairo_rectangle_int_t rect;
rect.x = interest_rect->x; rect.x = interest_rect->x;
rect.y = interest_rect->y; rect.y = interest_rect->y;
@ -1949,24 +1947,20 @@ _cairo_xlib_surface_create_internal (Display *dpy,
cairo_xlib_screen_info_t *screen_info; cairo_xlib_screen_info_t *screen_info;
screen_info = _cairo_xlib_screen_info_get (dpy, screen); screen_info = _cairo_xlib_screen_info_get (dpy, screen);
if (screen_info == NULL) { if (screen_info == NULL)
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = malloc (sizeof (cairo_xlib_surface_t)); surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL) { if (surface == NULL) {
_cairo_xlib_screen_info_destroy (screen_info); _cairo_xlib_screen_info_destroy (screen_info);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
if (! _cairo_xlib_add_close_display_hook (dpy, if (! _cairo_xlib_add_close_display_hook (dpy,
_cairo_xlib_surface_detach_display, surface, surface)) { _cairo_xlib_surface_detach_display, surface, surface)) {
free (surface); free (surface);
_cairo_xlib_screen_info_destroy (screen_info); _cairo_xlib_screen_info_destroy (screen_info);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
if (xrender_format) { if (xrender_format) {
@ -2096,10 +2090,8 @@ cairo_xlib_surface_create (Display *dpy,
{ {
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual); Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
if (screen == NULL) { if (screen == NULL)
_cairo_error_throw (CAIRO_STATUS_INVALID_VISUAL); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
return (cairo_surface_t*) &_cairo_surface_nil;
}
CAIRO_MUTEX_INITIALIZE (); CAIRO_MUTEX_INITIALIZE ();

Просмотреть файл

@ -1869,6 +1869,50 @@ cairo_close_path (cairo_t *cr)
} }
slim_hidden_def(cairo_close_path); slim_hidden_def(cairo_close_path);
/**
* cairo_path_extents:
* @cr: a cairo context
* @x1: left of the resulting extents
* @y1: top of the resulting extents
* @x2: right of the resulting extents
* @y2: bottom of the resulting extents
*
* Computes a bounding box in user-space coordinates covering the
* points on the current path. If the current path is empty, returns
* an empty rectangle ((0,0), (0,0)). Stroke parameters, fill rule,
* surface dimensions and clipping are not taken into account.
*
* Contrast with cairo_fill_extents() and cairo_stroke_extents() which
* return the extents of only the area that would be "inked" by
* the corresponding drawing operations.
*
* The result of cairo_path_extents() is defined as equivalent to the
* limit of cairo_stroke_extents() with CAIRO_LINE_CAP_ROUND as the
* line width approaches 0.0, (but never reaching the empty-rectangle
* returned by cairo_stroke_extents() for a line width of 0.0).
*
* Specifically, this means that zero-area sub-paths such as
* cairo_move_to();cairo_line_to() segments, (even degenerate cases
* where the coordinates to both calls are identical), will be
* considered as contributing to the extents. However, a lone
* cairo_move_to() will not contribute to the results of
* cairo_path_extents().
*
* Since: 1.6
**/
void
cairo_path_extents (cairo_t *cr,
double *x1, double *y1, double *x2, double *y2)
{
if (cr->status)
return;
_cairo_gstate_path_extents (cr->gstate,
cr->path,
x1, y1, x2, y2);
}
slim_hidden_def (cairo_path_extents);
/** /**
* cairo_paint: * cairo_paint:
* @cr: a cairo context * @cr: a cairo context
@ -2236,10 +2280,16 @@ cairo_in_fill (cairo_t *cr, double x, double y)
* @y2: bottom of the resulting extents * @y2: bottom of the resulting extents
* *
* Computes a bounding box in user coordinates covering the area that * Computes a bounding box in user coordinates covering the area that
* would be affected by a cairo_stroke() operation operation given the * would be affected, (the "inked" area), by a cairo_stroke()
* current path and stroke parameters. If the current path is empty, * operation operation given the current path and stroke
* returns an empty rectangle (0,0, 0,0). Surface dimensions and * parameters. If the current path is empty, returns an empty
* clipping are not taken into account. * rectangle ((0,0), (0,0)). Surface dimensions and clipping are not
* taken into account.
*
* Note that if the line width is set to exactly zero, then
* cairo_stroke_extents will return an empty rectangle. Contrast with
* cairo_path_extents() which can be used to compute the non-empty
* bounds as the line width approaches zero.
* *
* See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(), * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
* cairo_set_line_cap(), cairo_set_dash(), and * cairo_set_line_cap(), cairo_set_dash(), and
@ -2270,10 +2320,14 @@ cairo_stroke_extents (cairo_t *cr,
* @y2: bottom of the resulting extents * @y2: bottom of the resulting extents
* *
* Computes a bounding box in user coordinates covering the area that * Computes a bounding box in user coordinates covering the area that
* would be affected by a cairo_fill() operation given the current path * would be affected, (the "inked" area), by a cairo_fill() operation
* and fill parameters. If the current path is empty, returns an empty * given the current path and fill parameters. If the current path is
* rectangle (0,0, 0,0). Surface dimensions and clipping are not taken * empty, returns an empty rectangle ((0,0), (0,0)). Surface
* into account. * dimensions and clipping are not taken into account.
*
* Contrast with cairo_path_extents(), which is similar, but returns
* non-zero extents for some paths no inked area, (such as a simple
* line segment).
* *
* See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve(). * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
**/ **/
@ -2666,10 +2720,12 @@ cairo_set_font_options (cairo_t *cr,
if (cr->status) if (cr->status)
return; return;
status = cairo_font_options_status ((cairo_font_options_t *) options); if (options != NULL) {
if (status) { status = cairo_font_options_status ((cairo_font_options_t *) options);
_cairo_set_error (cr, status); if (status) {
return; _cairo_set_error (cr, status);
return;
}
} }
_cairo_gstate_set_font_options (cr->gstate, options); _cairo_gstate_set_font_options (cr->gstate, options);
@ -2812,18 +2868,18 @@ cairo_text_extents (cairo_t *cr,
int num_glyphs; int num_glyphs;
double x, y; double x, y;
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
if (cr->status) if (cr->status)
return; return;
if (utf8 == NULL) { if (utf8 == NULL)
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
return; return;
}
cairo_get_current_point (cr, &x, &y); cairo_get_current_point (cr, &x, &y);
@ -2831,14 +2887,10 @@ cairo_text_extents (cairo_t *cr,
x, y, x, y,
&glyphs, &num_glyphs); &glyphs, &num_glyphs);
if (status) { if (status == CAIRO_STATUS_SUCCESS)
if (glyphs) status = _cairo_gstate_glyph_extents (cr->gstate,
free (glyphs); glyphs, num_glyphs,
_cairo_set_error (cr, status); extents);
return;
}
status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
if (glyphs) if (glyphs)
free (glyphs); free (glyphs);
@ -2872,6 +2924,13 @@ cairo_glyph_extents (cairo_t *cr,
{ {
cairo_status_t status; cairo_status_t status;
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
if (cr->status) if (cr->status)
return; return;
@ -3323,7 +3382,7 @@ cairo_surface_t *
cairo_get_target (cairo_t *cr) cairo_get_target (cairo_t *cr)
{ {
if (cr->status) if (cr->status)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (cr->status);
return _cairo_gstate_get_original_target (cr->gstate); return _cairo_gstate_get_original_target (cr->gstate);
} }
@ -3352,7 +3411,7 @@ cairo_surface_t *
cairo_get_group_target (cairo_t *cr) cairo_get_group_target (cairo_t *cr)
{ {
if (cr->status) if (cr->status)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (cr->status);
return _cairo_gstate_get_target (cr->gstate); return _cairo_gstate_get_target (cr->gstate);
} }

Просмотреть файл

@ -584,6 +584,11 @@ cairo_stroke_to_path (cairo_t *cr);
cairo_public void cairo_public void
cairo_close_path (cairo_t *cr); cairo_close_path (cairo_t *cr);
cairo_public void
cairo_path_extents (cairo_t *cr,
double *x1, double *y1,
double *x2, double *y2);
/* Painting functions */ /* Painting functions */
cairo_public void cairo_public void
cairo_paint (cairo_t *cr); cairo_paint (cairo_t *cr);

Просмотреть файл

@ -68,17 +68,6 @@
#include "cairo-compiler-private.h" #include "cairo-compiler-private.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#undef inline
#define inline __inline
#endif
#ifdef __STRICT_ANSI__
#undef inline
#define inline __inline__
#endif
CAIRO_BEGIN_DECLS CAIRO_BEGIN_DECLS
#ifdef _WIN32 #ifdef _WIN32
@ -112,6 +101,10 @@ _cairo_win32_tmpfile (void);
__FILE__, __LINE__, #expr); } while (0) __FILE__, __LINE__, #expr); } while (0)
#endif #endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#undef ARRAY_LENGTH #undef ARRAY_LENGTH
#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) #define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
@ -1023,6 +1016,12 @@ _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
double *x2, double *y2, double *x2, double *y2,
cairo_bool_t *is_tight); cairo_bool_t *is_tight);
cairo_private void
_cairo_gstate_path_extents (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2);
cairo_private cairo_status_t cairo_private cairo_status_t
_cairo_gstate_paint (cairo_gstate_t *gstate); _cairo_gstate_paint (cairo_gstate_t *gstate);
@ -1268,13 +1267,6 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
cairo_private unsigned char * cairo_private unsigned char *
_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out); _cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out);
/* cairo_operator.c */
cairo_private cairo_bool_t
_cairo_operator_always_opaque (cairo_operator_t op);
cairo_private cairo_bool_t
_cairo_operator_always_translucent (cairo_operator_t op);
/* cairo_path.c */ /* cairo_path.c */
cairo_private void cairo_private void
_cairo_path_fixed_init (cairo_path_fixed_t *path); _cairo_path_fixed_init (cairo_path_fixed_t *path);
@ -1365,10 +1357,20 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
cairo_path_fixed_close_path_func_t *close_path, cairo_path_fixed_close_path_func_t *close_path,
void *closure); void *closure);
cairo_private cairo_status_t
_cairo_path_fixed_interpret_flat (cairo_path_fixed_t *path,
cairo_direction_t dir,
cairo_path_fixed_move_to_func_t *move_to,
cairo_path_fixed_line_to_func_t *line_to,
cairo_path_fixed_close_path_func_t *close_path,
void *closure,
double tolerance);
cairo_private void cairo_private void
_cairo_path_fixed_bounds (cairo_path_fixed_t *path, _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1, double *x1, double *y1,
double *x2, double *y2); double *x2, double *y2,
double tolerance);
cairo_private void cairo_private void
_cairo_path_fixed_device_transform (cairo_path_fixed_t *path, _cairo_path_fixed_device_transform (cairo_path_fixed_t *path,
@ -1483,10 +1485,8 @@ _cairo_stroke_style_fini (cairo_stroke_style_t *style);
/* cairo-surface.c */ /* cairo-surface.c */
extern const cairo_private cairo_surface_t _cairo_surface_nil; cairo_private cairo_surface_t *
extern const cairo_private cairo_surface_t _cairo_surface_nil_read_error; _cairo_surface_create_in_error (cairo_status_t status);
extern const cairo_private cairo_surface_t _cairo_surface_nil_write_error;
extern const cairo_private cairo_surface_t _cairo_surface_nil_file_not_found;
cairo_private cairo_status_t cairo_private cairo_status_t
_cairo_surface_set_error (cairo_surface_t *surface, _cairo_surface_set_error (cairo_surface_t *surface,
@ -2230,6 +2230,7 @@ slim_hidden_proto (cairo_matrix_translate);
slim_hidden_proto (cairo_move_to); slim_hidden_proto (cairo_move_to);
slim_hidden_proto (cairo_new_path); slim_hidden_proto (cairo_new_path);
slim_hidden_proto (cairo_paint); slim_hidden_proto (cairo_paint);
slim_hidden_proto (cairo_path_extents);
slim_hidden_proto (cairo_pattern_create_for_surface); slim_hidden_proto (cairo_pattern_create_for_surface);
slim_hidden_proto (cairo_pattern_create_rgb); slim_hidden_proto (cairo_pattern_create_rgb);
slim_hidden_proto (cairo_pattern_create_rgba); slim_hidden_proto (cairo_pattern_create_rgba);
@ -2287,6 +2288,7 @@ slim_hidden_proto (cairo_surface_write_to_png_stream);
CAIRO_END_DECLS CAIRO_END_DECLS
#include "cairo-mutex-private.h" #include "cairo-mutex-private.h"
#include "cairo-fixed-private.h"
#include "cairo-wideint-private.h" #include "cairo-wideint-private.h"
#include "cairo-malloc-private.h" #include "cairo-malloc-private.h"
#include "cairo-hash-private.h" #include "cairo-hash-private.h"

Просмотреть файл

@ -76,13 +76,12 @@ _cairo_test_fallback_surface_create (cairo_content_t content,
backing = _cairo_image_surface_create_with_content (content, width, height); backing = _cairo_image_surface_create_with_content (content, width, height);
if (cairo_surface_status (backing)) if (cairo_surface_status (backing))
return (cairo_surface_t*) &_cairo_surface_nil; return backing;
surface = malloc (sizeof (test_fallback_surface_t)); surface = malloc (sizeof (test_fallback_surface_t));
if (surface == NULL) { if (surface == NULL) {
cairo_surface_destroy (backing); cairo_surface_destroy (backing);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t*) &_cairo_surface_nil;
} }
_cairo_surface_init (&surface->base, &test_fallback_surface_backend, _cairo_surface_init (&surface->base, &test_fallback_surface_backend,

Просмотреть файл

@ -74,21 +74,26 @@ _cairo_test_meta_surface_create (cairo_content_t content,
int height) int height)
{ {
test_meta_surface_t *surface; test_meta_surface_t *surface;
cairo_status_t status;
surface = malloc (sizeof (test_meta_surface_t)); surface = malloc (sizeof (test_meta_surface_t));
if (surface == NULL) if (surface == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL; goto FAIL;
}
_cairo_surface_init (&surface->base, &test_meta_surface_backend, _cairo_surface_init (&surface->base, &test_meta_surface_backend,
content); content);
surface->meta = _cairo_meta_surface_create (content, width, height); surface->meta = _cairo_meta_surface_create (content, width, height);
if (cairo_surface_status (surface->meta)) status = cairo_surface_status (surface->meta);
if (status)
goto FAIL_CLEANUP_SURFACE; goto FAIL_CLEANUP_SURFACE;
surface->image = _cairo_image_surface_create_with_content (content, surface->image = _cairo_image_surface_create_with_content (content,
width, height); width, height);
if (cairo_surface_status (surface->image)) status = cairo_surface_status (surface->image);
if (status)
goto FAIL_CLEANUP_META; goto FAIL_CLEANUP_META;
surface->image_reflects_meta = FALSE; surface->image_reflects_meta = FALSE;
@ -100,8 +105,7 @@ _cairo_test_meta_surface_create (cairo_content_t content,
FAIL_CLEANUP_SURFACE: FAIL_CLEANUP_SURFACE:
free (surface); free (surface);
FAIL: FAIL:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (status);
return (cairo_surface_t*) &_cairo_surface_nil;
} }
static cairo_status_t static cairo_status_t
@ -309,7 +313,7 @@ _test_meta_surface_snapshot (void *abstract_other)
status = _cairo_surface_get_extents (other->image, &extents); status = _cairo_surface_get_extents (other->image, &extents);
if (status) if (status)
return (cairo_surface_t*) &_cairo_surface_nil; return _cairo_surface_create_in_error (status);
surface = cairo_surface_create_similar (other->image, surface = cairo_surface_create_similar (other->image,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
@ -319,7 +323,7 @@ _test_meta_surface_snapshot (void *abstract_other)
status = _cairo_meta_surface_replay (other->meta, surface); status = _cairo_meta_surface_replay (other->meta, surface);
if (status) { if (status) {
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
surface = (cairo_surface_t*) &_cairo_surface_nil; surface = _cairo_surface_create_in_error (status);
} }
return surface; return surface;

Просмотреть файл

@ -77,13 +77,12 @@ _cairo_test_paginated_surface_create_for_data (unsigned char *data,
stride); stride);
status = cairo_surface_status (target); status = cairo_surface_status (target);
if (status) if (status)
return (cairo_surface_t *) &_cairo_surface_nil; return target;
surface = malloc (sizeof (test_paginated_surface_t)); surface = malloc (sizeof (test_paginated_surface_t));
if (surface == NULL) { if (surface == NULL) {
cairo_surface_destroy (target); cairo_surface_destroy (target);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return (cairo_surface_t *) &_cairo_surface_nil;
} }
_cairo_surface_init (&surface->base, &test_paginated_surface_backend, _cairo_surface_init (&surface->base, &test_paginated_surface_backend,

Просмотреть файл

@ -1,12 +1,21 @@
diff --git a/gfx/cairo/cairo/src/cairo-fixed-private.h b/gfx/cairo/cairo/src/cairo-fixed-private.h --- /Users/vladimir/proj/cairo/src/cairo-fixed-type-private.h 2008-01-22 15:20:39.000000000 -0800
--- a/cairo/src/cairo-fixed-private.h +++ cairo/src/cairo-fixed-type-private.h 2008-01-24 11:49:15.000000000 -0800
+++ b/cairo/src/cairo-fixed-private.h @@ -54,17 +54,17 @@ typedef cairo_int128_t cairo_fixed_96_32
@@ -59,7 +59,7 @@ typedef cairo_int128_t cairo_fixed_96_32 * size of a fixed type. For now, it must be 32.
*/
#define CAIRO_FIXED_BITS 32
/* The number of fractional bits. Changing this involves
* making sure that you compute a double-to-fixed magic number. * making sure that you compute a double-to-fixed magic number.
* (see below). * (see below).
*/ */
-#define CAIRO_FIXED_FRAC_BITS 16 -#define CAIRO_FIXED_FRAC_BITS 16
+#define CAIRO_FIXED_FRAC_BITS 8 +#define CAIRO_FIXED_FRAC_BITS 24
/* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */ /* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */
typedef int32_t cairo_fixed_t; typedef int32_t cairo_fixed_t;
/* An unsigned type of the same size as cairo_fixed_t */
typedef uint32_t cairo_fixed_unsigned_t;
#endif /* CAIRO_FIXED_TYPE_PRIVATE_H */

Просмотреть файл

@ -3695,8 +3695,8 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin
stride = pict->rowstride; stride = pict->rowstride;
/* reference point is the center of the pixel */ /* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2; v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2; v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
v.vector[2] = pixman_fixed_1; v.vector[2] = pixman_fixed_1;
/* when using convolution filters one might get here without a transform */ /* when using convolution filters one might get here without a transform */

Просмотреть файл

@ -45,13 +45,28 @@ rasterizeEdges (pixman_image_t *image,
int lxi; int lxi;
int rxi; int rxi;
/* clip X */
lx = l->x; lx = l->x;
rx = r->x;
#if N_BITS == 1
/* For the non-antialiased case, round the coordinates up, in effect
* sampling the center of the pixel. (The AA case does a similar
* adjustment in RenderSamplesX) */
lx += X_FRAC_FIRST(1);
rx += X_FRAC_FIRST(1);
#endif
/* clip X */
if (lx < 0) if (lx < 0)
lx = 0; lx = 0;
rx = r->x;
if (pixman_fixed_to_int (rx) >= width) if (pixman_fixed_to_int (rx) >= width)
#if N_BITS == 1
rx = pixman_int_to_fixed (width); rx = pixman_int_to_fixed (width);
#else
/* Use the last pixel of the scanline, covered 100%.
* We can't use the first pixel following the scanline,
* because accessing it could result in a buffer overrun.
*/
rx = pixman_int_to_fixed (width) - 1;
#endif
/* Skip empty (or backwards) sections */ /* Skip empty (or backwards) sections */
if (rx > lx) if (rx > lx)
@ -109,12 +124,7 @@ rasterizeEdges (pixman_image_t *image,
AddAlpha (N_X_FRAC(N_BITS)); AddAlpha (N_X_FRAC(N_BITS));
StepAlpha; StepAlpha;
} }
/* Do not add in a 0 alpha here. This check is necessary AddAlpha (rxs);
* to avoid a buffer overrun when rx is exactly on a pixel
* boundary.
*/
if (rxs != 0)
AddAlpha (rxs);
} }
} }
#endif #endif

Просмотреть файл

@ -147,7 +147,11 @@ fbRasterizeEdges8 (pixman_image_t *image,
lx = 0; lx = 0;
rx = r->x; rx = r->x;
if (pixman_fixed_to_int (rx) >= width) if (pixman_fixed_to_int (rx) >= width)
rx = pixman_int_to_fixed (width); /* Use the last pixel of the scanline, covered 100%.
* We can't use the first pixel following the scanline,
* because accessing it could result in a buffer overrun.
*/
rx = pixman_int_to_fixed (width) - 1;
/* Skip empty (or backwards) sections */ /* Skip empty (or backwards) sections */
if (rx > lx) if (rx > lx)
@ -235,11 +239,7 @@ fbRasterizeEdges8 (pixman_image_t *image,
add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi); add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
} }
/* Do not add in a 0 alpha here. This check is WRITE(image, ap + rxi, clip255 (READ(image, ap + rxi) + rxs));
* necessary to avoid a buffer overrun, (when rx
* is exactly on a pixel boundary). */
if (rxs)
WRITE(image, ap + rxi, clip255 (READ(image, ap + rxi) + rxs));
} }
} }

Просмотреть файл

@ -750,7 +750,7 @@ union pixman_image
#define MAX_ALPHA(n) ((1 << (n)) - 1) #define MAX_ALPHA(n) ((1 << (n)) - 1)
#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1) #define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1)
#define N_X_FRAC(n) ((1 << ((n)/2)) + 1) #define N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) + 1)
#define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC(n)) #define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC(n))
#define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n)) #define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n))

Просмотреть файл

@ -57,3 +57,5 @@
#define pixman_add_traps _moz_pixman_add_traps #define pixman_add_traps _moz_pixman_add_traps
#define pixman_add_trapezoids _moz_pixman_add_trapezoids #define pixman_add_trapezoids _moz_pixman_add_trapezoids
#define pixman_rasterize_trapezoid _moz_pixman_rasterize_trapezoid #define pixman_rasterize_trapezoid _moz_pixman_rasterize_trapezoid
#define pixman_transform_point_3d _moz_pixman_transform_point_3d

Просмотреть файл

@ -165,6 +165,7 @@ struct pixman_transform
pixman_fixed_t matrix[3][3]; pixman_fixed_t matrix[3][3];
}; };
PIXMAN_EXPORT
pixman_bool_t pixman_transform_point_3d (pixman_transform_t *transform, pixman_bool_t pixman_transform_point_3d (pixman_transform_t *transform,
pixman_vector_t *vector); pixman_vector_t *vector);
@ -370,7 +371,7 @@ pixman_bool_t pixman_fill (uint32_t *bits,
int y, int y,
int width, int width,
int height, int height,
uint32_t xor); uint32_t _xor);
/* /*
* Images * Images
*/ */

Просмотреть файл

@ -1,120 +0,0 @@
diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -33,6 +33,8 @@
* Contributor(s):
* Vladimir Vukicevic <vladimir@mozilla.com>
*/
+
+#include <dlfcn.h>
#include "cairoint.h"
@@ -100,11 +102,12 @@ CG_EXTERN CGImageRef CGBitmapContextCrea
CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
#endif
-/* missing in 10.3.9 */
-extern void CGContextClipToMask (CGContextRef, CGRect, CGImageRef) __attribute__((weak_import));
+/* Only present in 10.4+ */
+static void (*CGContextClipToMaskPtr) (CGContextRef, CGRect, CGImageRef) = NULL;
+/* Only present in 10.5+ */
+static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
-/* 10.5-only optimization */
-extern void CGContextDrawTiledImage (CGContextRef, CGRect, CGImageRef) __attribute__((weak_import));
+static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
/*
* Utility functions
@@ -118,6 +121,18 @@ _cairo_quartz_surface_create_internal (C
cairo_content_t content,
unsigned int width,
unsigned int height);
+
+/* Load all extra symbols */
+static void quartz_ensure_symbols()
+{
+ if (_cairo_quartz_symbol_lookup_done)
+ return;
+
+ CGContextClipToMaskPtr = dlsym(RTLD_DEFAULT, "CGContextClipToMask");
+ CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
+
+ _cairo_quartz_symbol_lookup_done = TRUE;
+}
/* CoreGraphics limitation with flipped CTM surfaces: height must be less than signed 16-bit max */
@@ -761,7 +776,7 @@ _cairo_quartz_setup_source (cairo_quartz
return _cairo_quartz_setup_radial_source (surface, rpat);
} else if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
- (source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImage && source->extend == CAIRO_EXTEND_REPEAT)))
+ (source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT)))
{
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
cairo_surface_t *pat_surf = spat->surface;
@@ -1298,7 +1313,7 @@ _cairo_quartz_surface_paint (void *abstr
if (action == DO_IMAGE)
CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
else
- CGContextDrawTiledImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
+ CGContextDrawTiledImagePtr (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
CGContextRestoreGState (surface->cgContext);
} else if (action != DO_NOTHING) {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1388,7 +1403,7 @@ _cairo_quartz_surface_fill (void *abstra
if (action == DO_IMAGE)
CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
else
- CGContextDrawTiledImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
+ CGContextDrawTiledImagePtr (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
} else if (action != DO_NOTHING) {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -1496,7 +1511,7 @@ _cairo_quartz_surface_stroke (void *abst
if (action == DO_IMAGE)
CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
else
- CGContextDrawTiledImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
+ CGContextDrawTiledImagePtr (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
} else if (action == DO_SHADING) {
CGContextReplacePathWithStrokedPath (surface->cgContext);
CGContextClip (surface->cgContext);
@@ -1655,7 +1670,7 @@ _cairo_quartz_surface_show_glyphs (void
if (action == DO_IMAGE)
CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
else
- CGContextDrawTiledImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
+ CGContextDrawTiledImagePtr (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
} else if (action == DO_SHADING) {
CGContextDrawShading (surface->cgContext, surface->sourceShading);
}
@@ -1710,7 +1725,7 @@ _cairo_quartz_surface_mask_with_surface
rect = CGRectMake (-mask->base.matrix.x0, -mask->base.matrix.y0, extents.width, extents.height);
CGContextSaveGState (surface->cgContext);
- CGContextClipToMask (surface->cgContext, rect, img);
+ CGContextClipToMaskPtr (surface->cgContext, rect, img);
status = _cairo_quartz_surface_paint (surface, op, source);
CGContextRestoreGState (surface->cgContext);
@@ -1739,7 +1754,7 @@ _cairo_quartz_surface_mask (void *abstra
cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
CGContextSetAlpha (surface->cgContext, solid_mask->color.alpha);
- } else if (CGContextClipToMask &&
+ } else if (CGContextClipToMaskPtr &&
mask->type == CAIRO_PATTERN_TYPE_SURFACE &&
mask->extend == CAIRO_EXTEND_NONE) {
return _cairo_quartz_surface_mask_with_surface (surface, op, source, (cairo_surface_pattern_t *) mask);
@@ -1862,6 +1877,8 @@ _cairo_quartz_surface_create_internal (C
unsigned int height)
{
cairo_quartz_surface_t *surface;
+
+ quartz_ensure_symbols();
/* Init the base surface */
surface = malloc(sizeof(cairo_quartz_surface_t));