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:
cairo (1.5.x - 1.5.4-141-g57c2b75)
pixman (0.9.x - pixman-0.9.6-25-ge0af592)
cairo (1.5.x - 1.5.6-65-gea9afec)
pixman (0.9.x - pixman-0.9.6-34-g787cc57)
glitz 0.5.2 (cvs - 2006-01-10)
***** 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
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-meta-surface.c \
cairo-mutex.c \
cairo-operator.c \
cairo-output-stream.c \
cairo-paginated-surface.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.height = surface->height;
} 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.y = floor (y1);
@ -600,7 +600,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface = malloc (sizeof (cairo_analysis_surface_t));
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
* sure nothing will ever use this value. */
@ -625,9 +625,6 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface->current_clip.height = height;
return &surface->base;
FAIL:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
cairo_region_t *

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

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

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

@ -113,6 +113,9 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
{
cairo_base85_stream_t *stream;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_base85_stream_t));
if (stream == NULL) {
_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;
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;
if (n_boxes) {

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

@ -111,6 +111,16 @@ CAIRO_BEGIN_DECLS
#define __attribute__(x)
#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

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

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

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

@ -37,39 +37,11 @@
#ifndef CAIRO_FIXED_PRIVATE_H
#define CAIRO_FIXED_PRIVATE_H
#include "cairo-fixed-type-private.h"
#include "cairo-wideint-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;
/*
* No configurable bits below this.
*/
/* Implementation */
#if (CAIRO_FIXED_BITS != 32)
# 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)
return font_face->base.status;
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status)
return status;
if (options != NULL) {
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status)
return status;
}
return _cairo_font_face_set_error (&font_face->base,
backend->create_toy (font_face,

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

@ -52,7 +52,7 @@ static const cairo_font_options_t _cairo_font_options_nil = {
void
_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;
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
@ -65,10 +65,13 @@ void
_cairo_font_options_init_copy (cairo_font_options_t *options,
const cairo_font_options_t *other)
{
options->antialias = other->antialias;
options->subpixel_order = other->subpixel_order;
options->hint_style = other->hint_style;
options->hint_metrics = other->hint_metrics;
if (other != NULL) {
options->antialias = other->antialias;
options->subpixel_order = other->subpixel_order;
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));
if (!options) {
_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);
@ -118,13 +121,16 @@ cairo_font_options_copy (const cairo_font_options_t *original)
{
cairo_font_options_t *options;
if (original == &_cairo_font_options_nil)
return (cairo_font_options_t *)&_cairo_font_options_nil;
if (original != NULL &&
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));
if (!options) {
_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);
@ -142,7 +148,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
void
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;
free (options);
@ -161,7 +167,9 @@ slim_hidden_def (cairo_font_options_destroy);
cairo_status_t
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;
else
return CAIRO_STATUS_SUCCESS;
@ -182,7 +190,11 @@ void
cairo_font_options_merge (cairo_font_options_t *options,
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;
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
@ -209,6 +221,14 @@ cairo_bool_t
cairo_font_options_equal (const cairo_font_options_t *options,
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 &&
options->subpixel_order == other->subpixel_order &&
options->hint_style == other->hint_style &&
@ -231,6 +251,9 @@ slim_hidden_def (cairo_font_options_equal);
unsigned long
cairo_font_options_hash (const cairo_font_options_t *options)
{
if (options == NULL)
options = &_cairo_font_options_nil;
return ((options->antialias) |
(options->subpixel_order << 4) |
(options->hint_style << 8) |
@ -250,7 +273,7 @@ void
cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias)
{
if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
if (cairo_font_options_status (options))
return;
options->antialias = antialias;
@ -268,6 +291,9 @@ slim_hidden_def (cairo_font_options_set_antialias);
cairo_antialias_t
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;
}
@ -286,7 +312,7 @@ void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order)
{
if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
if (cairo_font_options_status (options))
return;
options->subpixel_order = subpixel_order;
@ -305,6 +331,9 @@ slim_hidden_def (cairo_font_options_set_subpixel_order);
cairo_subpixel_order_t
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;
}
@ -322,7 +351,7 @@ void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style)
{
if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
if (cairo_font_options_status (options))
return;
options->hint_style = hint_style;
@ -341,6 +370,9 @@ slim_hidden_def (cairo_font_options_set_hint_style);
cairo_hint_style_t
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;
}
@ -358,7 +390,7 @@ void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics)
{
if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
if (cairo_font_options_status (options))
return;
options->hint_metrics = hint_metrics;
@ -377,5 +409,8 @@ slim_hidden_def (cairo_font_options_set_hint_metrics);
cairo_hint_metrics_t
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;
}

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

@ -1365,7 +1365,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
if (!hinting) {
ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
}
#endif /* FC_FHINT_STYLE */
#endif /* FC_HINT_STYLE */
} else {
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->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
@ -1497,9 +1499,6 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
_cairo_unscaled_font_reference (&unscaled->base);
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_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);
_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);
goto FREE_PATTERN;
}
@ -1658,9 +1657,11 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
goto FREE_PATTERN;
}
status = _cairo_ft_font_options_substitute (font_options, pattern);
if (status)
goto FREE_PATTERN;
if (font_options != NULL) {
status = _cairo_ft_font_options_substitute (font_options, pattern);
if (status)
goto FREE_PATTERN;
}
FcDefaultSubstitute (pattern);
@ -2446,6 +2447,9 @@ void
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
FcPattern *pattern)
{
if (cairo_font_options_status ((cairo_font_options_t *) options))
return;
_cairo_ft_font_options_substitute (options, pattern);
}

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

@ -88,20 +88,16 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
gformat =
glitz_find_standard_format (drawable,
_glitz_format_from_content (content));
if (!gformat) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (!gformat)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = glitz_surface_create (drawable, gformat,
width <= 0 ? 1 : width,
height <= 0 ? 1 : height,
0, NULL);
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
crsurface = cairo_glitz_surface_create (surface);
@ -150,36 +146,39 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
return FALSE;
}
static glitz_box_t *
_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
static cairo_status_t
_cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, int *nboxes)
{
cairo_box_int_t *cboxes;
glitz_box_t *gboxes;
cairo_status_t status;
int n, i;
if (_cairo_region_get_boxes (region, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
return NULL;
status = _cairo_region_get_boxes (region, &n, &cboxes);
if (status)
return status;
*nboxes = n;
if (n == 0)
return NULL;
if (n == 0) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto done;
}
gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
if (gboxes == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto done;
*boxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
if (*boxes == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto done;
}
for (i = 0; i < n; i++) {
gboxes[i].x1 = cboxes[i].p1.x;
gboxes[i].y1 = cboxes[i].p1.y;
gboxes[i].x2 = cboxes[i].p2.x;
gboxes[i].y2 = cboxes[i].p2.y;
(*boxes)[i].x1 = cboxes[i].p1.x;
(*boxes)[i].y1 = cboxes[i].p1.y;
(*boxes)[i].x2 = cboxes[i].p2.x;
(*boxes)[i].y2 = cboxes[i].p2.y;
}
*nboxes = n;
done:
_cairo_region_boxes_fini (region, cboxes);
return gboxes;
return status;
}
static cairo_status_t
@ -296,12 +295,13 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
/* restore the clip, if any */
if (surface->has_clip) {
glitz_box_t *box;
cairo_status_t status;
int n;
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
if (box == NULL && n != 0) {
status = _cairo_glitz_get_boxes_from_region (&surface->clip, &box, &n);
if (status) {
free (pixels);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return status;
}
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;
}
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
if (box == NULL && n != 0) {
status = _cairo_glitz_get_boxes_from_region (&surface->clip, &box, &n);
if (status) {
_cairo_region_fini (&surface->clip);
surface->has_clip = FALSE;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return status;
}
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;
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));
if (crsurface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (crsurface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
format = glitz_surface_get_format (surface);
_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
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
cairo_pattern_t *pattern,
@ -1365,7 +1376,7 @@ _cairo_gstate_set_font_options (cairo_gstate_t *gstate,
{
_cairo_gstate_unset_scaled_font (gstate);
gstate->font_options = *options;
_cairo_font_options_init_copy (&gstate->font_options, options);
}
void

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

@ -37,101 +37,6 @@
#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
_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;
surface = malloc (sizeof (cairo_image_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base, &cairo_image_surface_backend,
_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
_cairo_format_to_pixman_format_code (cairo_format_t format)
{
int ret = 0;
pixman_format_code_t ret;
switch (format) {
case CAIRO_FORMAT_A1:
ret = PIXMAN_a1;
@ -415,7 +318,6 @@ _cairo_format_to_pixman_format_code (cairo_format_t format)
ret = PIXMAN_a8r8g8b8;
break;
}
assert (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,
(uint32_t *) data, stride);
if (pixman_image == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (pixman_image == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
pixman_format);
if (cairo_surface_status (surface)) {
if (cairo_surface_status (surface))
pixman_image_unref (pixman_image);
}
return surface;
}
@ -473,10 +372,8 @@ cairo_image_surface_create (cairo_format_t format,
{
pixman_format_code_t pixman_format;
if (! CAIRO_FORMAT_VALID (format)) {
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
}
if (! CAIRO_FORMAT_VALID (format))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_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 height)
{
if (! CAIRO_CONTENT_VALID (content)) {
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
}
if (! CAIRO_CONTENT_VALID (content))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return cairo_image_surface_create (_cairo_format_from_content (content),
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
* attempting to create such surfaces will failure but we will interpret
* such failure as CAIRO_STATUS_NO_MEMORY. */
if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0) {
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
}
if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0)
return _cairo_surface_create_in_error (_cairo_error(CAIRO_STATUS_INVALID_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 stride)
{
if (! CAIRO_CONTENT_VALID (content)) {
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
}
if (! CAIRO_CONTENT_VALID (content))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return cairo_image_surface_create_for_data (data,
_cairo_format_from_content (content),
@ -1191,7 +1082,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
case CAIRO_ANTIALIAS_NONE:
format = PIXMAN_a1;
ret = 1;
assert (ret);
mask_stride = ((width + 31) / 8) & ~0x03;
mask_bpp = 1;
break;
@ -1201,7 +1091,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
default:
format = PIXMAN_a8;
ret = 1;
assert (ret);
mask_stride = (width + 3) & ~3;
mask_bpp = 8;
break;
@ -1382,7 +1271,7 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
if (status) {
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;

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

@ -753,6 +753,10 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
*pixman_transform = pixman_identity_transform;
}
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][1] = _cairo_fixed_16_16_from_double (matrix->xy);
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][1] = 0;
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;
meta = malloc (sizeof (cairo_meta_surface_t));
if (meta == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (meta == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
content);
@ -498,10 +496,8 @@ _cairo_meta_surface_snapshot (void *abstract_other)
cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t));
if (meta == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (meta == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
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)
{
cairo_os2_surface_t *local_os2_surface;
cairo_status_t status;
int rc;
/* Check the size of the window */
@ -729,15 +730,13 @@ cairo_os2_surface_create (HPS hps_client_window,
(height <= 0))
{
/* Invalid window size! */
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t));
if (!local_os2_surface) {
/* Not enough memory! */
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* Initialize the OS/2 specific parts of the surface! */
@ -749,8 +748,7 @@ cairo_os2_surface_create (HPS hps_client_window,
FALSE);
if (rc != NO_ERROR) {
/* Could not create mutex semaphore! */
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* Save PS handle */
@ -769,8 +767,7 @@ cairo_os2_surface_create (HPS hps_client_window,
/* Could not create event semaphore! */
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* 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);
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* Create image surface from pixel array */
@ -800,14 +796,14 @@ cairo_os2_surface_create (HPS hps_client_window,
height, /* Height */
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! */
_buffer_free (local_os2_surface->pixels);
DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (status);
}
/* Initialize base surface */

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

@ -87,6 +87,9 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
cairo_close_func_t close_func,
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
* before its last gasp. This final status value will capture any
* 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;
}
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_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;
if (stream == NULL)
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
assert (stream != NULL);
if (stream == &_cairo_output_stream_nil ||
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)
{
cairo_paginated_surface_t *surface;
cairo_status_t status;
surface = malloc (sizeof (cairo_paginated_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
@ -97,7 +98,8 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
surface->backend = backend;
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;
surface->page_num = 1;
@ -108,7 +110,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
FAIL_CLEANUP_SURFACE:
free (surface);
FAIL:
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (status);
}
cairo_bool_t
@ -292,9 +294,8 @@ _paint_page (cairo_paginated_surface_t *surface)
analysis = _cairo_analysis_surface_create (surface->target,
surface->width, surface->height);
if (analysis == NULL)
return _cairo_surface_set_error (surface->target,
CAIRO_STATUS_NO_MEMORY);
if (analysis->status)
return _cairo_surface_set_error (surface->target, analysis->status);
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
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);
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:
if (_cairo_analysis_surface_has_unsupported (analysis)) {
has_supported = FALSE;

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

@ -37,7 +37,9 @@
#include "cairoint.h"
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_y;
@ -60,25 +62,21 @@ _cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
static cairo_status_t
_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
_cairo_path_bounder_close_path (void *closure);
static void
_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
_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
@ -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_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_add_point (bounder, point);
bounder->move_to_point = *point;
bounder->has_move_to_point = TRUE;
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;
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);
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
_cairo_path_bounder_close_path (void *closure)
{
@ -151,7 +141,8 @@ _cairo_path_bounder_close_path (void *closure)
void
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2)
double *x2, double *y2,
double tolerance)
{
cairo_status_t status;
@ -159,21 +150,24 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
_cairo_path_bounder_init (&bounder);
status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD,
_cairo_path_bounder_move_to,
_cairo_path_bounder_line_to,
_cairo_path_bounder_curve_to,
_cairo_path_bounder_close_path,
&bounder);
status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD,
_cairo_path_bounder_move_to,
_cairo_path_bounder_line_to,
_cairo_path_bounder_close_path,
&bounder,
tolerance);
assert (status == CAIRO_STATUS_SUCCESS);
if (! bounder.has_point) {
*x1 = *y1 = *x2 = *y2 = 0.;
} else {
if (bounder.has_point) {
*x1 = _cairo_fixed_to_double (bounder.min_x);
*y1 = _cairo_fixed_to_double (bounder.min_y);
*x2 = _cairo_fixed_to_double (bounder.max_x);
*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);

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

@ -622,3 +622,102 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
}
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);
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);
if (status)
@ -966,7 +966,7 @@ _cairo_stroker_curve_to_dashed (void *closure,
status = _cairo_spline_init (&spline, a, b, c, d);
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
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;
if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER)
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)
return CAIRO_INT_STATUS_UNSUPPORTED;
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. */
typedef struct cairo_path_count {
int count;
double tolerance;
cairo_point_t current_point;
} cpc_t;
@ -87,39 +86,6 @@ _cpc_curve_to (void *closure,
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
_cpc_close_path (void *closure)
{
@ -140,19 +106,27 @@ _cairo_path_count (cairo_path_t *path,
cpc_t cpc;
cpc.count = 0;
cpc.tolerance = tolerance;
cpc.current_point.x = 0;
cpc.current_point.y = 0;
status = _cairo_path_fixed_interpret (path_fixed,
CAIRO_DIRECTION_FORWARD,
_cpc_move_to,
_cpc_line_to,
flatten ?
_cpc_curve_to_flatten :
_cpc_curve_to,
_cpc_close_path,
&cpc);
if (flatten) {
status = _cairo_path_fixed_interpret_flat (path_fixed,
CAIRO_DIRECTION_FORWARD,
_cpc_move_to,
_cpc_line_to,
_cpc_close_path,
&cpc,
tolerance);
} 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)
return -1;
@ -262,40 +236,6 @@ _cpp_curve_to (void *closure,
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
_cpp_close_path (void *closure)
{
@ -324,15 +264,25 @@ _cairo_path_populate (cairo_path_t *path,
cpp.current_point.x = 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,
_cpp_move_to,
_cpp_line_to,
flatten ?
_cpp_curve_to_flatten :
_cpp_curve_to,
_cpp_close_path,
&cpp);
}
if (status)
return status;

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

@ -164,7 +164,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
static void
_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_resource_t *resource,
cairo_bool_t compressed,
@ -234,14 +234,13 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
double height)
{
cairo_pdf_surface_t *surface;
cairo_status_t status;
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_pdf_surface_t));
if (surface == NULL) {
/* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
_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 ();
if (! surface->font_subsets) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL0;
}
surface->next_available_resource.id = 1;
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;
}
surface->compress_content = TRUE;
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,
width, height,
&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;
BAIL1:
@ -314,9 +316,9 @@ BAIL0:
free (surface);
/* 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 height_in_points)
{
cairo_status_t status;
cairo_output_stream_t *output;
output = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (output);
if (status)
return (cairo_surface_t*) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (output))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points,
@ -382,15 +382,11 @@ cairo_pdf_surface_create (const char *filename,
double width_in_points,
double height_in_points)
{
cairo_status_t status;
cairo_output_stream_t *output;
output = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (output);
if (status)
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t*) &_cairo_surface_nil_write_error :
(cairo_surface_t*) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (output))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
return _cairo_pdf_surface_create_for_stream_internal (output,
width_in_points,
@ -816,7 +812,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
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_resource_t *resource,
cairo_bool_t compressed,
@ -833,19 +829,17 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
} else {
self = _cairo_pdf_surface_new_object (surface);
if (self.id == 0)
return self;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
length = _cairo_pdf_surface_new_object (surface);
if (length.id == 0)
return length;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (compressed) {
output = _cairo_deflate_stream_create (surface->output);
if (_cairo_output_stream_get_status (output)) {
self.id = 0;
return self;
}
if (_cairo_output_stream_get_status (output))
return _cairo_output_stream_destroy (output);
}
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);
}
return surface->pdf_stream.self;
return _cairo_output_stream_get_status (surface->output);
}
static cairo_status_t
@ -919,6 +913,9 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
surface->pdf_stream.active = FALSE;
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_output_stream_get_status (surface->output);
return status;
}
@ -1049,7 +1046,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
if (group)
*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)
status = status2;
@ -1061,9 +1058,10 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
static cairo_status_t
_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource,
cairo_bool_t is_form)
{
cairo_status_t status;
assert (surface->pdf_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);
if (is_form) {
*resource =
status =
_cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
@ -1088,21 +1086,23 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
surface->width,
surface->height,
surface->content_resources.id);
if (resource->id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (status)
return status;
} else {
surface->content =
status =
_cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
NULL);
if (surface->content.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (status)
return status;
}
surface->content = surface->pdf_stream.self;
_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
@ -1126,7 +1126,7 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
_cairo_output_stream_printf (surface->output,
"endobj\r\n");
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
static cairo_surface_t *
@ -1233,7 +1233,7 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
surface->has_fallback_images = FALSE;
_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)
return status;
@ -1284,11 +1284,13 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
uint8_t a;
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 ||
image->format == CAIRO_FORMAT_A8 ||
image->format == CAIRO_FORMAT_A1 );
stream_ret->id = 0;
if (image->format == CAIRO_FORMAT_A1)
alpha_size = (image->height * image->width + 7)/8;
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. */
if (opaque) {
stream_ret->id = 0;
if (opaque)
goto CLEANUP_ALPHA;
}
alpha_compressed = compress_dup (alpha, alpha_size, &alpha_compressed_size);
if (alpha_compressed == NULL) {
@ -1356,22 +1356,22 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
goto CLEANUP_ALPHA;
}
*stream_ret = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
" /Type /XObject\r\n"
" /Subtype /Image\r\n"
" /Width %d\r\n"
" /Height %d\r\n"
" /ColorSpace /DeviceGray\r\n"
" /BitsPerComponent %d\r\n"
" /Filter /FlateDecode\r\n",
image->width, image->height,
image->format == CAIRO_FORMAT_A1 ? 1 : 8);
if (stream_ret->id == 0) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
" /Type /XObject\r\n"
" /Subtype /Image\r\n"
" /Width %d\r\n"
" /Height %d\r\n"
" /ColorSpace /DeviceGray\r\n"
" /BitsPerComponent %d\r\n"
" /Filter /FlateDecode\r\n",
image->width, image->height,
image->format == CAIRO_FORMAT_A1 ? 1 : 8);
if (status)
goto CLEANUP_ALPHA_COMPRESSED;
}
*stream_ret = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size);
_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"
if (need_smask)
*image_ret = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
IMAGE_DICTIONARY
" /SMask %d 0 R\r\n",
image->width, image->height,
smask.id);
status = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
IMAGE_DICTIONARY
" /SMask %d 0 R\r\n",
image->width, image->height,
smask.id);
else
*image_ret = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
IMAGE_DICTIONARY,
image->width, image->height);
if (image_ret->id == 0){
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_open_stream (surface,
NULL,
FALSE,
IMAGE_DICTIONARY,
image->width, image->height);
if (status)
goto CLEANUP_COMPRESSED;
}
#undef IMAGE_DICTIONARY
*image_ret = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, compressed, compressed_size);
_cairo_output_stream_printf (surface->output, "\r\n");
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 *height)
{
cairo_surface_t *pat_surface;
cairo_surface_attributes_t pat_attr;
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status;
status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern,
(cairo_surface_t *)surface,
0, 0, -1, -1,
&pat_surface, &pat_attr);
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
if (status)
return status;
status = _cairo_surface_acquire_source_image (pat_surface, &image, &image_extra);
if (status)
goto BAIL2;
goto BAIL;
status = _cairo_pdf_surface_emit_image (surface, image, resource);
if (status)
@ -1547,9 +1538,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
*height = image->height;
BAIL:
_cairo_surface_release_source_image (pat_surface, image, image_extra);
BAIL2:
_cairo_pattern_release_surface ((cairo_pattern_t *)pattern, pat_surface, &pat_attr);
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
return status;
}
@ -1562,7 +1551,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
double old_width, old_height;
cairo_matrix_t old_cairo_to_pdf;
cairo_paginated_mode_t old_paginated_mode;
cairo_rectangle_int16_t meta_extents;
cairo_rectangle_int_t meta_extents;
cairo_status_t status;
int alpha = 0;
@ -1586,7 +1575,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
surface->cairo_to_pdf);
_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)
return status;
@ -1627,19 +1616,20 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_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_matrix_t cairo_p2d, pdf_p2d;
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
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_height = 0; /* squelch bogus compiler warning */
int bbox_x, bbox_y;
char draw_surface[200];
if (_cairo_surface_is_meta (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,
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_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
if (_cairo_pdf_surface_open_stream (surface,
&pdf_pattern->pattern_res,
FALSE,
" /PatternType 1\r\n"
" /BBox [0 0 %d %d]\r\n"
" /XStep %f\r\n"
" /YStep %f\r\n"
" /TilingType 1\r\n"
" /PaintType 1\r\n"
" /Matrix [ %f %f %f %f %f %f ]\r\n"
" /Resources << /XObject << /x%d %d 0 R >> >>\r\n",
bbox_x, bbox_y,
xstep, ystep,
pdf_p2d.xx, pdf_p2d.yx,
pdf_p2d.xy, pdf_p2d.yy,
pdf_p2d.x0, pdf_p2d.y0,
pattern_resource.id,
pattern_resource.id).id == 0)
{
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
status = _cairo_pdf_surface_open_stream (surface,
&pdf_pattern->pattern_res,
FALSE,
" /PatternType 1\r\n"
" /BBox [0 0 %d %d]\r\n"
" /XStep %f\r\n"
" /YStep %f\r\n"
" /TilingType 1\r\n"
" /PaintType 1\r\n"
" /Matrix [ %f %f %f %f %f %f ]\r\n"
" /Resources << /XObject << /x%d %d 0 R >> >>\r\n",
bbox_x, bbox_y,
xstep, ystep,
pdf_p2d.xx, pdf_p2d.yx,
pdf_p2d.xy, pdf_p2d.yy,
pdf_p2d.x0, pdf_p2d.y0,
pattern_resource.id,
pattern_resource.id);
if (status)
return status;
if (_cairo_surface_is_meta (pattern->surface)) {
if (extend == CAIRO_EXTEND_REFLECT) {
_cairo_output_stream_printf (surface->output,
"q 0 0 %d %d re W n /x%d Do Q\r\n"
"q -1 0 0 1 %d 0 cm 0 0 %d %d re W n /x%d Do Q\r\n"
"q 1 0 0 -1 0 %d cm 0 0 %d %d re W n /x%d Do Q\r\n"
"q -1 0 0 -1 %d %d cm 0 0 %d %d re W n /x%d Do Q\r\n",
pattern_width, pattern_height,
pattern_resource.id,
pattern_width*2, pattern_width, pattern_height,
pattern_resource.id,
pattern_height*2, pattern_width, pattern_height,
pattern_resource.id,
pattern_width*2, pattern_height*2, pattern_width, pattern_height,
pattern_resource.id);
} else {
_cairo_output_stream_printf (surface->output,
"/x%d Do\r\n",
pattern_resource.id);
}
snprintf(draw_surface,
sizeof (draw_surface),
"/x%d Do\r\n",
pattern_resource.id);
} else {
snprintf(draw_surface,
sizeof (draw_surface),
"q %d 0 0 %d 0 0 cm /x%d Do Q",
pattern_width,
pattern_height,
pattern_resource.id);
}
if (extend == CAIRO_EXTEND_REFLECT) {
_cairo_output_stream_printf (surface->output,
"q 0 0 %d %d re W n %s Q\r\n"
"q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\r\n"
"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 {
_cairo_output_stream_printf (surface->output,
"q %d 0 0 %d 0 0 cm /x%d Do Q\r\n",
pattern_width, pattern_height,
pattern_resource.id);
" %s \r\n",
draw_surface);
}
status = _cairo_pdf_surface_close_stream (surface);
if (status)
return status;
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
typedef struct _cairo_pdf_color_stop {
@ -1995,7 +1991,7 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
*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;
}
} else {
/* multiple stops: stitch. XXX possible optimization: regulary spaced
/* multiple stops: stitch. XXX possible optimization: regularly spaced
* stops do not require stitching. XXX */
status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
n_stops,
@ -2172,7 +2168,7 @@ _cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface,
*function = res;
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
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 gradient_mask)
{
cairo_pdf_resource_t xobj_resource, smask_resource;
cairo_pdf_resource_t smask_resource;
cairo_status_t status;
xobj_resource = _cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
" /Type /XObject\r\n"
" /Subtype /Form\r\n"
" /FormType 1\r\n"
" /BBox [ 0 0 %f %f ]\r\n"
" /Resources\r\n"
" << /ExtGState\r\n"
" << /a0 << /ca 1 /CA 1 >>"
" >>\r\n"
" /Pattern\r\n"
" << /p%d %d 0 R >>\r\n"
" >>\r\n"
" /Group\r\n"
" << /Type /Group\r\n"
" /S /Transparency\r\n"
" /CS /DeviceGray\r\n"
" >>\r\n",
surface->width,
surface->height,
gradient_mask.id,
gradient_mask.id);
if (xobj_resource.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
" /Type /XObject\r\n"
" /Subtype /Form\r\n"
" /FormType 1\r\n"
" /BBox [ 0 0 %f %f ]\r\n"
" /Resources\r\n"
" << /ExtGState\r\n"
" << /a0 << /ca 1 /CA 1 >>"
" >>\r\n"
" /Pattern\r\n"
" << /p%d %d 0 R >>\r\n"
" >>\r\n"
" /Group\r\n"
" << /Type /Group\r\n"
" /S /Transparency\r\n"
" /CS /DeviceGray\r\n"
" >>\r\n",
surface->width,
surface->height,
gradient_mask.id,
gradient_mask.id);
if (status)
return status;
_cairo_output_stream_printf (surface->output,
"q\r\n"
@ -2236,7 +2232,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
">>\r\n"
"endobj\r\n",
smask_resource.id,
xobj_resource.id);
surface->pdf_stream.self.id);
/* Create GState which uses the transparency group as an SMask. */
_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,
smask_resource.id);
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
static cairo_status_t
@ -2453,7 +2449,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
return status;
}
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
static cairo_status_t
@ -2570,7 +2566,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
return status;
}
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (surface->output);
}
static cairo_status_t
@ -2686,7 +2682,7 @@ _cairo_pdf_surface_get_extents (void *abstract_surface,
rectangle->y = 0;
/* 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.
*/
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);
/* TODO: Figure out wich other defaults to be inherited by /Page
/* TODO: Figure out which other defaults to be inherited by /Page
* objects. */
_cairo_output_stream_printf (surface->output,
">>\r\n"
@ -2804,12 +2800,12 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
return status;
}
*stream = _cairo_pdf_surface_open_stream (surface,
status = _cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
NULL);
if (stream->id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (status)
return status;
_cairo_output_stream_printf (surface->output,
"/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");
*stream = surface->pdf_stream.self;
return _cairo_pdf_surface_close_stream (surface);
}
@ -3410,16 +3407,18 @@ _cairo_pdf_surface_emit_bitmap_glyph (cairo_pdf_surface_t *surface,
return status;
}
*glyph_ret = _cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
NULL);
if (glyph_ret->id == 0) {
status = _cairo_pdf_surface_open_stream (surface,
NULL,
surface->compress_content,
NULL);
if (status) {
if (image != scaled_glyph->surface)
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,
"%f 0 %f %f %f %f d1\r\n",
x_advance,
@ -3657,6 +3656,7 @@ _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_s
return status;
}
ASSERT_NOT_REACHED;
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)
return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS;
}
@ -4024,7 +4025,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
return status;
_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)
return status;
@ -4218,9 +4219,7 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
surface->has_fallback_images = TRUE;
_cairo_pdf_group_resources_clear (&surface->resources);
return _cairo_pdf_surface_open_content_stream (surface,
&surface->content,
TRUE);
return _cairo_pdf_surface_open_content_stream (surface, TRUE);
}
static cairo_int_status_t

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

@ -382,7 +382,7 @@ static cairo_surface_t *
read_png (png_rw_ptr read_func,
void *closure)
{
cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil;
cairo_surface_t *surface;
png_struct *png = NULL;
png_info *info;
png_byte *data = NULL;
@ -398,20 +398,23 @@ read_png (png_rw_ptr read_func,
&status,
png_simple_error_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;
}
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;
}
png_set_read_fn (png, closure, read_func);
status = CAIRO_STATUS_SUCCESS;
#ifdef PNG_SETJMP_SUPPORTED
if (setjmp (png_jmpbuf (png))) {
if (status != CAIRO_STATUS_NO_MEMORY)
surface = (cairo_surface_t*) &_cairo_surface_nil_read_error;
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
#endif
@ -460,12 +463,16 @@ read_png (png_rw_ptr read_func,
pixel_size = 4;
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;
}
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;
}
for (i = 0; i < png_height; i++)
row_pointers[i] = &data[i * png_width * pixel_size];
@ -490,9 +497,6 @@ read_png (png_rw_ptr read_func,
if (png)
png_destroy_read_struct (&png, &info, NULL);
if (surface->status)
_cairo_error_throw (surface->status);
return surface;
}
@ -538,17 +542,19 @@ cairo_image_surface_create_from_png (const char *filename)
fp = fopen (filename, "rb");
if (fp == NULL) {
cairo_status_t status;
switch (errno) {
case ENOMEM:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
break;
case ENOENT:
_cairo_error_throw (CAIRO_STATUS_FILE_NOT_FOUND);
return (cairo_surface_t*) &_cairo_surface_nil_file_not_found;
status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
break;
default:
_cairo_error_throw (CAIRO_STATUS_READ_ERROR);
return (cairo_surface_t*) &_cairo_surface_nil_read_error;
status = _cairo_error (CAIRO_STATUS_READ_ERROR);
break;
}
return _cairo_surface_create_in_error (status);
}
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;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (word_wrap_stream_t));
if (stream == NULL) {
_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);
status = _cairo_output_stream_get_status (word_wrap);
if (status)
return status;
return _cairo_output_stream_destroy (word_wrap);
path_info.surface = surface;
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)
return status;
ASSERT_NOT_REACHED;
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)
return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS;
}
@ -937,7 +942,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double width,
double height)
{
cairo_status_t status;
cairo_status_t status, status_ignored;
cairo_ps_surface_t *surface;
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);
status = _cairo_output_stream_get_status (surface->stream);
if (status)
goto CLEANUP_TMPFILE;
goto CLEANUP_OUTPUT_STREAM;
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;
}
surface->eps = FALSE;
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,
width, height,
&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;
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
CLEANUP_OUTPUT_STREAM:
status = _cairo_output_stream_destroy (surface->stream);
/* Ignore status---we're already on a failure path. */
CLEANUP_TMPFILE:
status_ignored = _cairo_output_stream_destroy (surface->stream);
fclose (surface->tmpfile);
CLEANUP_SURFACE:
free (surface);
CLEANUP:
/* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (stream);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
status_ignored = _cairo_output_stream_destroy (stream);
return _cairo_surface_create_in_error (status);
}
/**
@ -1042,15 +1048,11 @@ cairo_ps_surface_create (const char *filename,
double width_in_points,
double height_in_points)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (stream);
if (status)
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t*) &_cairo_surface_nil_write_error :
(cairo_surface_t*) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points,
@ -1088,13 +1090,11 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
double width_in_points,
double height_in_points)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (stream);
if (status)
return (cairo_surface_t*) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return _cairo_ps_surface_create_for_stream_internal (stream,
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);
status = _cairo_output_stream_get_status (string_array_stream);
if (status)
return status;
return _cairo_output_stream_destroy (string_array_stream);
base85_stream = _cairo_base85_stream_create (string_array_stream);
status = _cairo_output_stream_get_status (base85_stream);
if (status) {
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);
@ -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);
} else {
word_wrap = _word_wrap_stream_create (surface->stream, 79);
status = _cairo_output_stream_get_status (word_wrap);
if (status)
if (_cairo_output_stream_get_status (word_wrap)) {
status = _cairo_output_stream_destroy (word_wrap);
goto fail;
}
_cairo_output_stream_printf (word_wrap, "<");
for (j = i; j < last+1; j++)

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

@ -123,7 +123,7 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
unsigned int height);
/* Load all extra symbols */
static void quartz_ensure_symbols()
static void quartz_ensure_symbols(void)
{
if (_cairo_quartz_symbol_lookup_done)
return;
@ -882,27 +882,16 @@ _cairo_quartz_teardown_source (cairo_quartz_surface_t *surface,
* 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 */
static cairo_int_status_t
_cairo_quartz_get_image (cairo_quartz_surface_t *surface,
cairo_image_surface_t **image_out,
unsigned char **data_out)
cairo_image_surface_t **image_out)
{
unsigned char *imageData;
cairo_image_surface_t *isurf;
if (IS_EMPTY(surface)) {
*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;
}
@ -1016,12 +1005,12 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface,
//ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface));
*image_extra = NULL;
status = _cairo_quartz_get_image (surface, image_out, NULL);
status = _cairo_quartz_get_image (surface, image_out);
if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*image_extra = NULL;
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_int_status_t status;
unsigned char *data;
ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface));
*image_rect = surface->extents;
status = _cairo_quartz_get_image (surface, image_out, &data);
status = _cairo_quartz_get_image (surface, image_out);
if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*image_extra = data;
*image_rect = surface->extents;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -1065,48 +1052,10 @@ _cairo_quartz_surface_release_dest_image (void *abstract_surface,
cairo_rectangle_int_t *image_rect,
void *image_extra)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
unsigned char *imageData = (unsigned char *) image_extra;
//cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_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);
}
@ -1552,6 +1501,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
cairo_quartz_action_t action;
float xprev, yprev;
int i;
CGFontRef cgfref;
if (IS_EMPTY(surface))
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));
/* 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);
/* 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 */
surface = malloc(sizeof(cairo_quartz_surface_t));
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (surface == NULL)
return (cairo_quartz_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
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,
width, height);
if (!surf) {
if (surf->base.status) {
CGContextRelease (cgContext);
// create_internal will have set an error
return (cairo_surface_t*) &_cairo_surface_nil;
return (cairo_surface_t*) surf;
}
return (cairo_surface_t *) surf;
@ -1995,10 +1943,8 @@ cairo_quartz_surface_create (cairo_format_t format,
int bitsPerComponent;
// verify width and height of surface
if (!verify_surface_size(width, height)) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (!verify_surface_size(width, height))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
if (width == 0 || height == 0) {
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
* quantities.
*/
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
} else {
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
}
imageData = _cairo_malloc_ab (height, stride);
if (!imageData) {
CGColorSpaceRelease (cgColorspace);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* zero the memory to match the image surface behaviour */
memset (imageData, 0, height * stride);
@ -2054,9 +1997,8 @@ cairo_quartz_surface_create (cairo_format_t format,
CGColorSpaceRelease (cgColorspace);
if (!cgc) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
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 */
@ -2065,11 +2007,11 @@ cairo_quartz_surface_create (cairo_format_t format,
surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
width, height);
if (!surf) {
if (surf->base.status) {
CGContextRelease (cgc);
free (imageData);
// create_internal will have set an error
return (cairo_surface_t*) &_cairo_surface_nil;
return (cairo_surface_t*) surf;
}
surf->imageData = imageData;

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

@ -121,6 +121,7 @@
#define cairo_paint _moz_cairo_paint
#define cairo_paint_with_alpha _moz_cairo_paint_with_alpha
#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_rgba _moz_cairo_pattern_add_color_stop_rgba
#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_set_drawable _moz_cairo_xlib_surface_set_drawable
#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;
} 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
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
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_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));
if (sub_font == NULL) {
@ -246,9 +253,11 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
return NULL;
}
if (parent->type != CAIRO_SUBSETS_SCALED) {
/* Reserve first glyph in subset for the .notdef glyph */
sub_font->num_glyphs_in_current_subset++;
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, &subset_glyph);
if (status) {
_cairo_error_throw (status);
return NULL;
}
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_status_t status;
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);
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->num_glyphs_in_current_subset = 0;
if (sub_font->parent->type != CAIRO_SUBSETS_SCALED) {
/* Reserve first glyph in subset for the .notdef glyph */
sub_font->num_glyphs_in_current_subset++;
}
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, &tmp_subset_glyph);
if (status)
return status;
}
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++) {
collection->subset_id = i;
if (sub_font->parent->type == CAIRO_SUBSETS_SCALED) {
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;
}
collection->num_glyphs = 0;
collection->max_glyph = 0;
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_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 */
scaled_font->ctm.x0 = 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 */
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_status_t status;
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status)
return status;
if (options != NULL) {
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status)
return status;
}
/* Initialize scaled_font->scale early for easier bail out on an
* 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
* be used.
* @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
* 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)
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;
}
if (! _cairo_matrix_is_invertible (font_matrix))
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;
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);
if (status) {
status = _cairo_scaled_font_set_error (scaled_font, status);
return;
}
if (status)
goto ZERO_EXTENTS;
cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);
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) {
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_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)
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,
&image, &image_extra);
if (status != CAIRO_STATUS_SUCCESS)
return (cairo_surface_t *) &_cairo_surface_nil;
if (status)
return _cairo_surface_create_in_error (status);
snapshot = cairo_image_surface_create (image->format,
image->width,
@ -1068,7 +1068,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
if (status) {
cairo_surface_destroy (snapshot);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (status);
}
snapshot->device_transform = surface->device_transform;

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

@ -78,10 +78,14 @@ const cairo_surface_t name = { \
} /* font_options */ \
}
DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found);
DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
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
_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);
if (other->status)
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (other->status);
if (other->backend->create_similar) {
surface = other->backend->create_similar (other, content, width, height);
@ -289,12 +293,10 @@ cairo_surface_create_similar (cairo_surface_t *other,
int height)
{
if (other->status)
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (other->status);
if (! CAIRO_CONTENT_VALID (content)) {
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (! CAIRO_CONTENT_VALID (content))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return _cairo_surface_create_similar_solid (other, content,
width, height,
@ -317,17 +319,14 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
surface = _cairo_surface_create_similar_scratch (other, content,
width, height);
if (surface->status) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface->status)
return surface;
if (pattern == NULL) {
source = _cairo_pattern_create_solid (color, content);
if (source->status) {
cairo_surface_destroy (surface);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (source->status);
}
} else
source = pattern;
@ -342,8 +341,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
if (status) {
cairo_surface_destroy (surface);
_cairo_error_throw (status);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (status);
}
return surface;
@ -1141,7 +1139,7 @@ cairo_surface_t *
_cairo_surface_snapshot (cairo_surface_t *surface)
{
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)
return surface->backend->snapshot (surface);
@ -2191,12 +2189,9 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
has_drawn_region = TRUE;
has_clear_region = TRUE;
if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
!= CAIRO_STATUS_SUCCESS)
{
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_region_subtract (&clear_region, &clear_region, &drawn_region);
if (status)
goto CLEANUP_REGIONS;
}
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
CAIRO_COLOR_TRANSPARENT,
@ -2412,5 +2407,31 @@ _cairo_surface_set_resolution (cairo_surface_t *surface,
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
*/

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

@ -118,11 +118,12 @@ typedef struct {
cairo_meta_surface_t *meta;
} cairo_meta_snapshot_t;
static cairo_svg_document_t *
_cairo_svg_document_create (cairo_output_stream_t *stream,
double width,
double height,
cairo_svg_version_t version);
static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *stream,
double width,
double height,
cairo_svg_version_t version,
cairo_svg_document_t **document_out);
static cairo_status_t
_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 height)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (stream);
if (status)
return (cairo_surface_t *) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
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 height)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (stream);
if (status)
return (status == CAIRO_STATUS_WRITE_ERROR) ?
(cairo_surface_t *) &_cairo_surface_nil_write_error :
(cairo_surface_t *) &_cairo_surface_nil;
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
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_surface_t *paginated;
cairo_status_t status;
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_svg_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base, &cairo_svg_surface_backend,
content);
@ -355,8 +348,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->is_base_clip_emitted = FALSE;
surface->xml_node = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (surface->xml_node))
goto CLEANUP_DOCUMENT;
status = _cairo_output_stream_get_status (surface->xml_node);
if (status)
goto CLEANUP;
_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; "
"fill: rgb(0,0,0);\"/>\n",
width, height);
if (_cairo_output_stream_get_status (surface->xml_node))
goto CLEANUP_STREAM;
status = _cairo_output_stream_get_status (surface->xml_node);
if (status)
goto CLEANUP;
}
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->height,
&cairo_svg_surface_paginated_backend);
if (! paginated->status)
status = paginated->status;
if (status == CAIRO_STATUS_SUCCESS)
return paginated;
/* ignore status as we are on the error path */
CLEANUP_STREAM:
status = _cairo_output_stream_destroy (surface->xml_node);
CLEANUP_DOCUMENT:
status = _cairo_svg_document_destroy (document);
CLEANUP:
status_ignored = _cairo_output_stream_destroy (surface->xml_node);
status_ignored = _cairo_svg_document_destroy (document);
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 *
@ -399,23 +394,25 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double height,
cairo_svg_version_t version)
{
cairo_svg_document_t *document;
cairo_svg_document_t *document = NULL; /* silence compiler */
cairo_surface_t *surface;
cairo_status_t status;
document = _cairo_svg_document_create (stream, width, height, version);
if (document == NULL) {
status = _cairo_svg_document_create (stream,
width, height, version,
&document);
if (status) {
surface = _cairo_surface_create_in_error (status);
/* consume the output stream on behalf of caller */
status = _cairo_output_stream_destroy (stream);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return surface;
}
surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA,
width, height);
if (surface->status) {
status = _cairo_svg_document_destroy (document);
return (cairo_surface_t *) &_cairo_surface_nil;
return surface;
}
document->owner = surface;
@ -432,20 +429,21 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
unsigned int i;
cairo_svg_page_t page;
cairo_output_stream_t *stream;
cairo_status_t status;
stream = _cairo_memory_stream_create ();
if (stream->status)
if (_cairo_output_stream_get_status (stream)) {
status = _cairo_output_stream_destroy (stream);
return NULL;
}
page.surface_id = surface->id;
page.clip_level = surface->clip_level;
page.xml_node = surface->xml_node;
if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS)
{
cairo_status_t status = _cairo_output_stream_destroy (stream);
if (_cairo_array_append (&surface->page_set, &page)) {
status = _cairo_output_stream_destroy (stream);
return NULL;
(void) status;
}
surface->xml_node = stream;
@ -1960,8 +1958,8 @@ _cairo_svg_surface_paint (void *abstract_surface,
}
surface->xml_node = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (surface->xml_node);
if (status) {
if (_cairo_output_stream_get_status (surface->xml_node)) {
status = _cairo_output_stream_destroy (surface->xml_node);
surface->xml_node = NULL;
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
* a temporary stream and then copy that to xml_node_defs. */
mask_stream = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (mask_stream);
if (status)
return status;
if (_cairo_output_stream_get_status (mask_stream))
return _cairo_output_stream_destroy (mask_stream);
_cairo_output_stream_printf (mask_stream,
"<mask id=\"mask%d\">\n"
@ -2246,28 +2243,29 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
_cairo_svg_surface_fill_stroke
};
static cairo_svg_document_t *
_cairo_svg_document_create (cairo_output_stream_t *output_stream,
double width,
double height,
cairo_svg_version_t version)
static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *output_stream,
double width,
double height,
cairo_svg_version_t version,
cairo_svg_document_t **document_out)
{
cairo_svg_document_t *document;
cairo_status_t status;
cairo_status_t status, status_ignored;
if (output_stream->status)
return NULL;
return output_stream->status;
document = malloc (sizeof (cairo_svg_document_t));
if (document == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (document == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* The use of defs for font glyphs imposes no per-subset limit. */
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;
}
document->output_stream = output_stream;
document->refcount = 1;
@ -2285,12 +2283,14 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->mask_id = 0;
document->xml_node_defs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_defs))
goto CLEANUP_FONT_SUBSETS;
status = _cairo_output_stream_get_status (document->xml_node_defs);
if (status)
goto CLEANUP_NODE_DEFS;
document->xml_node_glyphs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_glyphs))
goto CLEANUP_NODE_DEFS;
status = _cairo_output_stream_get_status (document->xml_node_glyphs);
if (status)
goto CLEANUP_NODE_GLYPHS;
document->alpha_filter = FALSE;
@ -2299,15 +2299,17 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
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:
status = _cairo_output_stream_destroy (document->xml_node_defs);
CLEANUP_FONT_SUBSETS:
status_ignored = _cairo_output_stream_destroy (document->xml_node_defs);
_cairo_scaled_font_subsets_destroy (document->font_subsets);
CLEANUP_DOCUMENT:
free (document);
return NULL;
return status;
}
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,
NULL,
font);
if (encrypted_output == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
if (_cairo_output_stream_get_status (encrypted_output))
return _cairo_output_stream_destroy (encrypted_output);
/* Note: the first four spaces at the start of this private dict
* 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;
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);
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,
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;
}
@ -1126,9 +1129,10 @@ cairo_type1_font_subset_generate (void *abstract_font,
goto fail;
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
status = _cairo_output_stream_get_status (font->output);
if (status)
if (_cairo_output_stream_get_status (font->output)) {
status = _cairo_output_stream_destroy (font->output);
goto fail;
}
status = cairo_type1_font_subset_write (font, name);
if (status)

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

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

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

@ -37,42 +37,7 @@
#ifndef CAIRO_WIDEINT_H
#define CAIRO_WIDEINT_H
#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
#include "cairo-wideint-type-private.h"
#include "cairo-compiler-private.h"
@ -86,10 +51,6 @@
#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);
#define _cairo_uint64_to_uint32(a) ((a).lo)
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
typedef uint64_t cairo_uint64_t;
typedef int64_t cairo_int64_t;
#define _cairo_uint32_to_uint64(i) ((uint64_t) (i))
#define _cairo_uint64_to_uint32(i) ((uint32_t) (i))
#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
*/
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_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
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_uint64_to_uint128 (cairo_uint64_t i);
#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 */
typedef uint128_t cairo_uint128_t;
typedef int128_t cairo_int128_t;
#define _cairo_uint32_to_uint128(i) ((uint128_t) (i))
#define _cairo_uint64_to_uint128(i) ((uint128_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 */
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_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
* 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 ();
else {
switch (options->antialias) {
@ -300,7 +300,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
if (f->quality == logfont->lfQuality ||
(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
* own --- because the constraints on face_hfont mentioned above
* guarantee it was created in exactly the same way that

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

@ -70,8 +70,11 @@
# define FEATURESETTING_PSLEVEL 0x0002
#endif
#if !defined(GRADIENT_FILL_RECT_H)
# define GRADIENT_FILL_RECT_H 0x00
#endif
#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_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);
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);
/* Restore both the clip save and our earlier path SaveDC */
RestoreDC (surface->dc, -2);
if (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;
if (surface->clip_saved_dc != 0)
RestoreDC (surface->dc, surface->clip_saved_dc);
RestoreDC (surface->dc, -1);
/* Undo both SaveDC's that we did in start_page */
RestoreDC (surface->dc, -2);
return CAIRO_STATUS_SUCCESS;
}
@ -988,10 +993,9 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
return CAIRO_STATUS_SUCCESS;
if (path == NULL) {
if (surface->clip_saved_dc != 0) {
RestoreDC (surface->dc, surface->clip_saved_dc);
surface->clip_saved_dc = 0;
}
RestoreDC (surface->dc, -1);
SaveDC (surface->dc);
return CAIRO_STATUS_SUCCESS;
}
@ -1010,8 +1014,6 @@ _cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface
ASSERT_NOT_REACHED;
}
if (surface->clip_saved_dc == 0)
surface->clip_saved_dc = SaveDC (surface->dc);
SelectClipPath (surface->dc, RGN_AND);
return status;
@ -1326,9 +1328,9 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
color = _cairo_win32_printing_surface_flatten_transparency (surface,
&solid->color);
opaque = cairo_pattern_create_rgb (GetRValue (color),
GetGValue (color),
GetBValue (color));
opaque = cairo_pattern_create_rgb (GetRValue (color) / 255.0,
GetGValue (color) / 255.0,
GetBValue (color) / 255.0);
if (opaque->status)
return opaque->status;
source = opaque;
@ -1414,7 +1416,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
cairo_win32_surface_t *surface = abstract_surface;
XFORM xform;
SaveDC (surface->dc);
SaveDC (surface->dc); /* Save application context first, before doing MWT */
SetGraphicsMode (surface->dc, GM_ADVANCED);
GetWorldTransform(surface->dc, &xform);
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))
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;
}
@ -1459,22 +1464,16 @@ cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc)
{
cairo_win32_surface_t *surface;
RECT rect;
int xr, yr;
/* 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;
}
RECT rect;
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
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;
@ -1488,28 +1487,14 @@ cairo_win32_printing_surface_create (HDC hdc)
surface->brush = NULL;
surface->old_brush = NULL;
surface->clip_rect.x = (int16_t) rect.left;
surface->clip_rect.y = (int16_t) rect.top;
surface->clip_rect.width = (uint16_t) (rect.right - rect.left);
surface->clip_rect.height = (uint16_t) (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;
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;
surface->extents.y = rect.top;
surface->extents.width = rect.right - rect.left;
surface->extents.height = rect.bottom - rect.top;
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
surface->clip_saved_dc = 0;
_cairo_win32_printing_surface_init_ps_mode (surface);
_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,
CAIRO_CONTENT_COLOR_ALPHA,
rect.right - rect.left,
rect.bottom - rect.top,
surface->extents.width,
surface->extents.height,
&cairo_win32_surface_paginated_backend);
}

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

@ -71,12 +71,17 @@ typedef struct _cairo_win32_surface {
cairo_surface_t *image;
cairo_rectangle_int_t clip_rect;
HRGN saved_clip;
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 */
uint32_t flags;
@ -86,7 +91,6 @@ typedef struct _cairo_win32_surface {
cairo_bool_t path_empty;
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
int clip_saved_dc;
HBRUSH brush, old_brush;
} cairo_win32_surface_t;
@ -168,4 +172,13 @@ _cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
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 */

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

@ -67,7 +67,6 @@
#endif
#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;
@ -333,10 +332,8 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
int rowstride;
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
}
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
status = _create_dc_and_bitmap (surface, original_dc, format,
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,
width, height, rowstride);
if (surface->image->status) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = surface->image->status;
if (status)
goto FAIL;
}
surface->format = format;
@ -358,14 +354,15 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->clip_rect.width = width;
surface->clip_rect.height = height;
surface->saved_clip = NULL;
surface->initial_clip_rgn = NULL;
surface->had_simple_clip = FALSE;
surface->extents = surface->clip_rect;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format));
return (cairo_surface_t *)surface;
return &surface->base;
FAIL:
if (surface->bitmap) {
@ -373,10 +370,9 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
DeleteObject (surface->bitmap);
DeleteDC (surface->dc);
}
if (surface)
free (surface);
free (surface);
return NIL_SURFACE;
return _cairo_surface_create_in_error (status);
}
static cairo_surface_t *
@ -478,26 +474,11 @@ _cairo_win32_surface_finish (void *abstract_surface)
DeleteObject (surface->bitmap);
DeleteDC (surface->dc);
} else {
/* otherwise, restore the old clip region on the DC */
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);
}
}
_cairo_win32_restore_initial_clip (surface);
}
if (surface->saved_clip)
DeleteObject (surface->saved_clip);
if (surface->initial_clip_rgn)
DeleteObject (surface->initial_clip_rgn);
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,
surface->clip_rect.width,
surface->clip_rect.height, &local);
surface->extents.width,
surface->extents.height, &local);
if (status)
return status;
@ -610,8 +591,8 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
image_rect->x = 0;
image_rect->y = 0;
image_rect->width = surface->clip_rect.width;
image_rect->height = surface->clip_rect.height;
image_rect->width = surface->extents.width;
image_rect->height = surface->extents.height;
*image_out = (cairo_image_surface_t *)surface->image;
*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.
*/
if (region == NULL) {
/* Clear any clip set by cairo, return to the original */
if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
/* Clear any clip set by cairo, return to the original first */
status = _cairo_win32_restore_initial_clip (surface);
status = CAIRO_STATUS_SUCCESS;
} else {
/* Then combine any new region with it */
if (region) {
cairo_rectangle_int_t extents;
cairo_box_int_t *boxes;
int num_boxes;
@ -1485,6 +1464,13 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
_cairo_region_boxes_fini (region, boxes);
} 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 = malloc (data_size);
if (!data) {
@ -1517,17 +1503,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
if (!gdi_region)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* Combine the new region with the original clip */
if (surface->saved_clip) {
if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
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");
}
/* AND the new region into our DC */
if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
DeleteObject (gdi_region);
}
@ -1709,20 +1687,10 @@ cairo_surface_t *
cairo_win32_surface_create (HDC hdc)
{
cairo_win32_surface_t *surface;
RECT rect;
int depth;
cairo_format_t format;
int clipBoxType;
/* 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;
}
RECT rect;
if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
depth = GetDeviceCaps(hdc, BITSPIXEL);
@ -1738,17 +1706,19 @@ cairo_win32_surface_create (HDC hdc)
format = CAIRO_FORMAT_A1;
else {
_cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
}
} else {
format = CAIRO_FORMAT_RGB24;
}
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NIL_SURFACE;
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
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;
@ -1761,26 +1731,13 @@ cairo_win32_surface_create (HDC hdc)
surface->brush = NULL;
surface->old_brush = NULL;
surface->clip_rect.x = (int16_t) rect.left;
surface->clip_rect.y = (int16_t) rect.top;
surface->clip_rect.width = (uint16_t) (rect.right - rect.left);
surface->clip_rect.height = (uint16_t) (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;
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;
surface->extents.y = rect.top;
surface->extents.width = rect.right - rect.left;
surface->extents.height = rect.bottom - rect.top;
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->clip_saved_dc = 0;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format));
@ -1837,7 +1794,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
HBITMAP saved_dc_bitmap;
if (format != CAIRO_FORMAT_RGB24)
return NIL_SURFACE;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
/* XXX handle these eventually
format != CAIRO_FORMAT_A8 ||
format != CAIRO_FORMAT_A1)
@ -1853,7 +1810,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
ddb_dc = CreateCompatibleDC (hdc);
if (ddb_dc == NULL) {
_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;
}
@ -1866,7 +1823,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
* video memory is probably exhausted.
*/
_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;
}
@ -2050,3 +2007,120 @@ DllMain (HINSTANCE hinstDLL,
#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,
xrender_format,
width, height);
if (surface->base.status) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface->base.status)
return surface;
surface->owns_pixmap = TRUE;
@ -315,7 +313,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
y2 = surface->height;
if (interest_rect) {
cairo_rectangle_int16_t rect;
cairo_rectangle_int_t rect;
rect.x = interest_rect->x;
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;
surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
if (xrender_format) {
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);
if (screen == NULL) {
_cairo_error (CAIRO_STATUS_INVALID_VISUAL);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (screen == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
return _cairo_xcb_surface_create_internal (c, drawable, screen,
visual, NULL,

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

@ -125,9 +125,6 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
cairo_xlib_display_t *
_cairo_xlib_display_reference (cairo_xlib_display_t *display)
{
if (display == NULL)
return NULL;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
_cairo_reference_count_inc (&display->ref_count);
@ -138,9 +135,6 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *display)
void
_cairo_xlib_display_destroy (cairo_xlib_display_t *display)
{
if (display == NULL)
return;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&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);
assert (display != NULL);
_cairo_xlib_display_destroy (display);
/* 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_reference (cairo_xlib_screen_info_t *info)
{
if (info == NULL)
return NULL;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&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 *list;
if (info == NULL)
return;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&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,
xrender_format,
width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
if (surface->base.status) {
XFreePixmap (dpy, pix);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return &surface->base;
}
surface->owns_pixmap = TRUE;
@ -258,8 +257,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
XFreePixmap (src->dpy, pix);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return &surface->base;
}
surface->owns_pixmap = TRUE;
@ -475,7 +473,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
y2 = surface->height;
if (interest_rect) {
cairo_rectangle_int16_t rect;
cairo_rectangle_int_t rect;
rect.x = interest_rect->x;
rect.y = interest_rect->y;
@ -1949,24 +1947,20 @@ _cairo_xlib_surface_create_internal (Display *dpy,
cairo_xlib_screen_info_t *screen_info;
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
if (screen_info == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (screen_info == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL) {
_cairo_xlib_screen_info_destroy (screen_info);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
if (! _cairo_xlib_add_close_display_hook (dpy,
_cairo_xlib_surface_detach_display, surface, surface)) {
free (surface);
_cairo_xlib_screen_info_destroy (screen_info);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
if (xrender_format) {
@ -2096,10 +2090,8 @@ cairo_xlib_surface_create (Display *dpy,
{
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
if (screen == NULL) {
_cairo_error_throw (CAIRO_STATUS_INVALID_VISUAL);
return (cairo_surface_t*) &_cairo_surface_nil;
}
if (screen == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
CAIRO_MUTEX_INITIALIZE ();

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

@ -1869,6 +1869,50 @@ cairo_close_path (cairo_t *cr)
}
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:
* @cr: a cairo context
@ -2236,10 +2280,16 @@ cairo_in_fill (cairo_t *cr, double x, double y)
* @y2: bottom of the resulting extents
*
* Computes a bounding box in user coordinates covering the area that
* would be affected by a cairo_stroke() operation operation given the
* current path and stroke parameters. If the current path is empty,
* returns an empty rectangle (0,0, 0,0). Surface dimensions and
* clipping are not taken into account.
* would be affected, (the "inked" area), by a cairo_stroke()
* operation operation given the current path and stroke
* parameters. If the current path is empty, returns an empty
* 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(),
* cairo_set_line_cap(), cairo_set_dash(), and
@ -2270,10 +2320,14 @@ cairo_stroke_extents (cairo_t *cr,
* @y2: bottom of the resulting extents
*
* Computes a bounding box in user coordinates covering the area that
* would be affected by a cairo_fill() operation given the current path
* and fill parameters. If the current path is empty, returns an empty
* rectangle (0,0, 0,0). Surface dimensions and clipping are not taken
* into account.
* would be affected, (the "inked" area), by a cairo_fill() operation
* given the current path and fill parameters. If the current path is
* empty, returns an empty rectangle ((0,0), (0,0)). Surface
* 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().
**/
@ -2666,10 +2720,12 @@ cairo_set_font_options (cairo_t *cr,
if (cr->status)
return;
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status) {
_cairo_set_error (cr, status);
return;
if (options != NULL) {
status = cairo_font_options_status ((cairo_font_options_t *) options);
if (status) {
_cairo_set_error (cr, status);
return;
}
}
_cairo_gstate_set_font_options (cr->gstate, options);
@ -2812,18 +2868,18 @@ cairo_text_extents (cairo_t *cr,
int num_glyphs;
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)
return;
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;
if (utf8 == NULL)
return;
}
cairo_get_current_point (cr, &x, &y);
@ -2831,14 +2887,10 @@ cairo_text_extents (cairo_t *cr,
x, y,
&glyphs, &num_glyphs);
if (status) {
if (glyphs)
free (glyphs);
_cairo_set_error (cr, status);
return;
}
status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_gstate_glyph_extents (cr->gstate,
glyphs, num_glyphs,
extents);
if (glyphs)
free (glyphs);
@ -2872,6 +2924,13 @@ cairo_glyph_extents (cairo_t *cr,
{
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)
return;
@ -3323,7 +3382,7 @@ cairo_surface_t *
cairo_get_target (cairo_t *cr)
{
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);
}
@ -3352,7 +3411,7 @@ cairo_surface_t *
cairo_get_group_target (cairo_t *cr)
{
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);
}

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

@ -584,6 +584,11 @@ cairo_stroke_to_path (cairo_t *cr);
cairo_public void
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 */
cairo_public void
cairo_paint (cairo_t *cr);

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

@ -68,17 +68,6 @@
#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
#ifdef _WIN32
@ -112,6 +101,10 @@ _cairo_win32_tmpfile (void);
__FILE__, __LINE__, #expr); } while (0)
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#undef ARRAY_LENGTH
#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,
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_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_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_private void
_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,
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_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2);
double *x2, double *y2,
double tolerance);
cairo_private void
_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 */
extern const cairo_private cairo_surface_t _cairo_surface_nil;
extern const cairo_private cairo_surface_t _cairo_surface_nil_read_error;
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_surface_t *
_cairo_surface_create_in_error (cairo_status_t status);
cairo_private cairo_status_t
_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_new_path);
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_rgb);
slim_hidden_proto (cairo_pattern_create_rgba);
@ -2287,6 +2288,7 @@ slim_hidden_proto (cairo_surface_write_to_png_stream);
CAIRO_END_DECLS
#include "cairo-mutex-private.h"
#include "cairo-fixed-private.h"
#include "cairo-wideint-private.h"
#include "cairo-malloc-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);
if (cairo_surface_status (backing))
return (cairo_surface_t*) &_cairo_surface_nil;
return backing;
surface = malloc (sizeof (test_fallback_surface_t));
if (surface == NULL) {
cairo_surface_destroy (backing);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
_cairo_surface_init (&surface->base, &test_fallback_surface_backend,

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

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

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

@ -77,13 +77,12 @@ _cairo_test_paginated_surface_create_for_data (unsigned char *data,
stride);
status = cairo_surface_status (target);
if (status)
return (cairo_surface_t *) &_cairo_surface_nil;
return target;
surface = malloc (sizeof (test_paginated_surface_t));
if (surface == NULL) {
cairo_surface_destroy (target);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
_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
--- a/cairo/src/cairo-fixed-private.h
+++ b/cairo/src/cairo-fixed-private.h
@@ -59,7 +59,7 @@ typedef cairo_int128_t cairo_fixed_96_32
--- /Users/vladimir/proj/cairo/src/cairo-fixed-type-private.h 2008-01-22 15:20:39.000000000 -0800
+++ cairo/src/cairo-fixed-type-private.h 2008-01-24 11:49:15.000000000 -0800
@@ -54,17 +54,17 @@ 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.
* (see below).
*/
-#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 */
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;
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
v.vector[1] = pixman_int_to_fixed(y) + 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 - 1;
v.vector[2] = pixman_fixed_1;
/* when using convolution filters one might get here without a transform */

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

@ -45,13 +45,28 @@ rasterizeEdges (pixman_image_t *image,
int lxi;
int rxi;
/* clip 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)
lx = 0;
rx = r->x;
if (pixman_fixed_to_int (rx) >= width)
#if N_BITS == 1
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 */
if (rx > lx)
@ -109,12 +124,7 @@ rasterizeEdges (pixman_image_t *image,
AddAlpha (N_X_FRAC(N_BITS));
StepAlpha;
}
/* Do not add in a 0 alpha here. This check is necessary
* to avoid a buffer overrun when rx is exactly on a pixel
* boundary.
*/
if (rxs != 0)
AddAlpha (rxs);
AddAlpha (rxs);
}
}
#endif

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

@ -147,7 +147,11 @@ fbRasterizeEdges8 (pixman_image_t *image,
lx = 0;
rx = r->x;
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 */
if (rx > lx)
@ -235,11 +239,7 @@ fbRasterizeEdges8 (pixman_image_t *image,
add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
}
/* Do not add in a 0 alpha here. This check is
* 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));
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 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_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_trapezoids _moz_pixman_add_trapezoids
#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_EXPORT
pixman_bool_t pixman_transform_point_3d (pixman_transform_t *transform,
pixman_vector_t *vector);
@ -370,7 +371,7 @@ pixman_bool_t pixman_fill (uint32_t *bits,
int y,
int width,
int height,
uint32_t xor);
uint32_t _xor);
/*
* 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));