b=421017; upgrade cairo to 1.5.12-11-g2f93504 ; r=me

This commit is contained in:
vladimir@pobox.com 2008-03-04 21:44:55 -08:00
Родитель 96be9d6d7d
Коммит 52b19faf19
41 изменённых файлов: 1160 добавлений и 1438 удалений

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

@ -7,7 +7,7 @@ http://www.cairographics.org/.
VERSIONS:
cairo (1.5.x - 1.5.8-87-g21049a9)
cairo (1.5.x - 1.5.12-11-g2f93504)
pixman (0.9.x - pixman-0.9.6-37-g8d79c48)
glitz 0.5.2 (cvs - 2006-01-10)
@ -25,13 +25,9 @@ win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
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
quartz-get-image-surface.patch: Add cairo_quartz_get_image_surface API analogous to the win32 one
buggy-repeat.patch: Unconditionally turn on buggy-repeat handling to bandaid bug 413583.
windows-8bit.patch: Initial important bits to get something drawing on 8bpp win32
==== pixman patches ====
endian.patch: include cairo-platform.h for endian macros

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

@ -71,11 +71,28 @@ _cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *
cairo_status_t status;
cairo_bool_t old_has_ctm;
cairo_matrix_t old_ctm, p2d;
cairo_rectangle_int_t old_clip;
cairo_rectangle_int_t meta_extents;
int old_width;
int old_height;
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
surface_pattern = (cairo_surface_pattern_t *) pattern;
assert (_cairo_surface_is_meta (surface_pattern->surface));
old_width = surface->width;
old_height = surface->height;
old_clip = surface->current_clip;
status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents);
if (status)
return status;
surface->width = meta_extents.width;
surface->height = meta_extents.height;
surface->current_clip.x = 0;
surface->current_clip.y = 0;
surface->current_clip.width = surface->width;
surface->current_clip.height = surface->height;
old_ctm = surface->ctm;
old_has_ctm = surface->has_ctm;
p2d = pattern->matrix;
@ -93,6 +110,9 @@ _cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *
surface->ctm = old_ctm;
surface->has_ctm = old_has_ctm;
surface->current_clip = old_clip;
surface->width = old_width;
surface->height = old_height;
return status;
}
@ -228,7 +248,11 @@ _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, tolerance);
cairo_status_t status;
status = _cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2, tolerance);
if (status)
return status;
extent.x = floor (x1);
extent.y = floor (y1);
@ -242,7 +266,7 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
}
static cairo_int_status_t
_cairo_analysis_surface_get_extents (void *abstract_surface,
_cairo_analysis_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle)
{
cairo_analysis_surface_t *surface = abstract_surface;

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

@ -111,8 +111,11 @@ CAIRO_BEGIN_DECLS
#define __attribute__(x)
#endif
#ifdef _MSC_VER
#ifdef __WIN32__
#define snprintf _snprintf
#endif
#ifdef _MSC_VER
#undef inline
#define inline __inline
#endif

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

@ -675,7 +675,7 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
}
for (i = 0; i < height; i++) {
direct_memcpy (dst+src_x, src+src_x, len);
direct_memcpy (dst, src, len);
dst += pitch;
src += image_src->stride;
}

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

@ -186,7 +186,7 @@ _cairo_fixed_to_16_16 (cairo_fixed_t f)
#else
cairo_fixed_16_16_t x;
/* Handle overflow/underflow by claping to the lowest/highest
/* Handle overflow/underflow by clamping to the lowest/highest
* value representable as 16.16
*/
if ((f >> CAIRO_FIXED_FRAC_BITS) < INT16_MIN) {

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

@ -64,10 +64,6 @@
*/
#define MAX_OPEN_FACES 10
/* This is the maximum font size we allow to be passed to FT_Set_Char_Size
*/
#define MAX_FONT_SIZE 1000
/*
* The simple 2x2 matrix is converted into separate scale and shape
* factors so that hinting works right
@ -598,6 +594,7 @@ _compute_transform (cairo_ft_font_transform_t *sf,
cairo_matrix_t *scale)
{
cairo_status_t status;
double x_scale, y_scale;
cairo_matrix_t normalized = *scale;
/* The font matrix has x and y "scale" components which we extract and
@ -607,23 +604,30 @@ _compute_transform (cairo_ft_font_transform_t *sf,
* freetype's transformation.
*/
status = _cairo_matrix_compute_scale_factors (&normalized,
&sf->x_scale, &sf->y_scale,
status = _cairo_matrix_compute_scale_factors (scale,
&x_scale, &y_scale,
/* XXX */ 1);
if (status)
return status;
if (sf->x_scale != 0 && sf->y_scale != 0) {
cairo_matrix_scale (&normalized, 1.0 / sf->x_scale, 1.0 / sf->y_scale);
/* FreeType docs say this about x_scale and y_scale:
* "A character width or height smaller than 1pt is set to 1pt;"
* So, we cap them from below at 1.0 and let the FT transform
* take care of sub-1.0 scaling. */
if (x_scale < 1.0)
x_scale = 1.0;
if (y_scale < 1.0)
y_scale = 1.0;
_cairo_matrix_get_affine (&normalized,
&sf->shape[0][0], &sf->shape[0][1],
&sf->shape[1][0], &sf->shape[1][1],
NULL, NULL);
} else {
sf->shape[0][0] = sf->shape[1][1] = 1.0;
sf->shape[0][1] = sf->shape[1][0] = 0.0;
}
sf->x_scale = x_scale;
sf->y_scale = y_scale;
cairo_matrix_scale (&normalized, 1.0 / x_scale, 1.0 / y_scale);
_cairo_matrix_get_affine (&normalized,
&sf->shape[0][0], &sf->shape[0][1],
&sf->shape[1][0], &sf->shape[1][1],
NULL, NULL);
return CAIRO_STATUS_SUCCESS;
}
@ -678,18 +682,9 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
FT_Set_Transform(unscaled->face, &mat, NULL);
if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
double x_scale = sf.x_scale;
double y_scale = sf.y_scale;
if (x_scale > MAX_FONT_SIZE) {
x_scale = MAX_FONT_SIZE;
}
if (y_scale > MAX_FONT_SIZE) {
y_scale = MAX_FONT_SIZE;
}
error = FT_Set_Char_Size (unscaled->face,
x_scale * 64.0,
y_scale * 64.0,
sf.x_scale * 64.0 + .5,
sf.y_scale * 64.0 + .5,
0, 0);
if (error)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);

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

@ -42,7 +42,7 @@
#include "cairo-clip-private.h"
#include "cairo-gstate-private.h"
#if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE)
#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
#define ISFINITE(x) isfinite (x)
#else
#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
@ -206,9 +206,6 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
static void
_cairo_gstate_destroy (cairo_gstate_t *gstate)
{
if (gstate == NULL)
return;
_cairo_gstate_fini (gstate);
free (gstate);
}
@ -225,8 +222,8 @@ _cairo_gstate_destroy (cairo_gstate_t *gstate)
* Return value: a new #cairo_gstate_t or %NULL if there is insufficient
* memory.
**/
static cairo_gstate_t*
_cairo_gstate_clone (cairo_gstate_t *other)
static cairo_status_t
_cairo_gstate_clone (cairo_gstate_t *other, cairo_gstate_t **out)
{
cairo_status_t status;
cairo_gstate_t *gstate;
@ -234,18 +231,17 @@ _cairo_gstate_clone (cairo_gstate_t *other)
assert (other != NULL);
gstate = malloc (sizeof (cairo_gstate_t));
if (gstate == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (gstate == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_gstate_init_copy (gstate, other);
if (status) {
free (gstate);
return NULL;
return status;
}
return gstate;
*out = gstate;
return CAIRO_STATUS_SUCCESS;
}
/**
@ -260,10 +256,11 @@ cairo_status_t
_cairo_gstate_save (cairo_gstate_t **gstate)
{
cairo_gstate_t *top;
cairo_status_t status;
top = _cairo_gstate_clone (*gstate);
if (top == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_gstate_clone (*gstate, &top);
if (status)
return status;
top->next = *gstate;
*gstate = top;
@ -448,9 +445,6 @@ _cairo_gstate_set_source (cairo_gstate_t *gstate,
cairo_pattern_t *
_cairo_gstate_get_source (cairo_gstate_t *gstate)
{
if (gstate == NULL)
return NULL;
return gstate->source;
}
@ -818,15 +812,21 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate)
}
*/
void
cairo_status_t
_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_status_t status;
status = _cairo_path_fixed_bounds (path, x1, y1, x2, y2, gstate->tolerance);
if (status)
return status;
_cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t

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

@ -484,7 +484,7 @@ cairo_image_surface_create_for_data (unsigned char *data,
pixman_format_code_t pixman_format;
if (! CAIRO_FORMAT_VALID (format))
return _cairo_surface_create_in_error (_cairo_error(CAIRO_STATUS_INVALID_FORMAT));
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
if ((stride & (STRIDE_ALIGNMENT-1)) != 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
@ -528,7 +528,7 @@ cairo_image_surface_get_data (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
if (! _cairo_surface_is_image (surface)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return NULL;
}
@ -551,7 +551,7 @@ cairo_image_surface_get_format (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
if (! _cairo_surface_is_image (surface)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
@ -574,7 +574,7 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
if (! _cairo_surface_is_image (surface)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
@ -596,7 +596,7 @@ cairo_image_surface_get_height (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
if (! _cairo_surface_is_image (surface)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
@ -624,7 +624,7 @@ cairo_image_surface_get_stride (cairo_surface_t *surface)
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
if (! _cairo_surface_is_image (surface)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
@ -794,7 +794,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
_cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
if (!pixman_image_set_transform (surface->pixman_image, &pixman_transform))
if (! pixman_image_set_transform (surface->pixman_image, &pixman_transform))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
@ -974,7 +974,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
width, height);
}
if (!_cairo_operator_bounded_by_source (op))
if (! _cairo_operator_bounded_by_source (op))
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
&src_attr, src->width, src->height,
mask ? &mask_attr : NULL,
@ -1014,8 +1014,8 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
pixman_color.blue = color->blue_short;
pixman_color.alpha = color->alpha_short;
if (num_rects > ARRAY_LENGTH(stack_rects)) {
pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
if (num_rects > ARRAY_LENGTH (stack_rects)) {
pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t));
if (pixman_rects == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -1028,7 +1028,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
}
/* XXX: pixman_fill_rectangles() should be implemented */
if (!pixman_image_fill_rectangles (_pixman_operator(op),
if (! pixman_image_fill_rectangles (_pixman_operator (op),
surface->pixman_image,
&pixman_color,
num_rects,
@ -1073,8 +1073,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
return CAIRO_STATUS_SUCCESS;
/* Convert traps to pixman traps */
if (num_traps > ARRAY_LENGTH(stack_traps)) {
pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
if (num_traps > ARRAY_LENGTH (stack_traps)) {
pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t));
if (pixman_traps == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -1108,7 +1108,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
if (op == CAIRO_OPERATOR_ADD &&
_cairo_pattern_is_opaque_solid (pattern) &&
dst->base.content == CAIRO_CONTENT_ALPHA &&
!dst->has_clip &&
! dst->has_clip &&
antialias != CAIRO_ANTIALIAS_NONE)
{
pixman_add_trapezoids (dst->pixman_image, 0, 0,
@ -1134,7 +1134,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
ret = 1;
mask_stride = ((width + 31) / 8) & ~0x03;
mask_bpp = 1;
break;
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_DEFAULT:
@ -1143,7 +1143,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
ret = 1;
mask_stride = (width + 3) & ~3;
mask_bpp = 8;
break;
break;
}
/* The image must be initially transparent */
@ -1173,7 +1173,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
dst_x, dst_y,
width, height);
if (!_cairo_operator_bounded_by_mask (op))
if (! _cairo_operator_bounded_by_mask (op))
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
&attributes, src->width, src->height,
width, height,
@ -1201,7 +1201,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
{
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
if (!pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
if (! pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
surface->has_clip = region != NULL;

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

@ -38,7 +38,7 @@
#include "cairoint.h"
#if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE)
#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
#define ISFINITE(x) isfinite (x)
#else
#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */

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

@ -662,7 +662,6 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
cairo_matrix_t *device_transform = &target->device_transform;
cairo_path_fixed_t path_copy, *dev_path;
double tolerance_multiplier = _cairo_matrix_transformed_circle_major_axis (device_transform, 1.0);
if (surface->status)
return surface->status;
@ -735,7 +734,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
&command->stroke.style,
&dev_ctm,
&dev_ctm_inverse,
command->stroke.tolerance * tolerance_multiplier,
command->stroke.tolerance,
command->stroke.antialias);
break;
}
@ -772,7 +771,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
command->fill.op,
&command->fill.source.base,
command->fill.fill_rule,
command->fill.tolerance * tolerance_multiplier,
command->fill.tolerance,
command->fill.antialias,
dev_path,
stroke_command->stroke.op,
@ -780,7 +779,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
&stroke_command->stroke.style,
&dev_ctm,
&dev_ctm_inverse,
stroke_command->stroke.tolerance * tolerance_multiplier,
stroke_command->stroke.tolerance,
stroke_command->stroke.antialias);
i++;
if (type == CAIRO_META_CREATE_REGIONS) {
@ -797,7 +796,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
&command->fill.source.base,
dev_path,
command->fill.fill_rule,
command->fill.tolerance * tolerance_multiplier,
command->fill.tolerance,
command->fill.antialias);
break;
}
@ -840,7 +839,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
else
status = _cairo_clip_clip (&clip, dev_path,
command->intersect_clip_path.fill_rule,
command->intersect_clip_path.tolerance * tolerance_multiplier,
command->intersect_clip_path.tolerance,
command->intersect_clip_path.antialias,
target);
assert (status == 0);

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

@ -36,16 +36,13 @@
#include "cairoint.h"
#include "cairo-output-stream-private.h"
#include "cairo-compiler-private.h"
#include <stdio.h>
#include <locale.h>
#include <ctype.h>
#include <errno.h>
#ifdef _MSC_VER
#define snprintf _snprintf
#endif /* _MSC_VER */
void
_cairo_output_stream_init (cairo_output_stream_t *stream,

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

@ -334,6 +334,7 @@ _paint_page (cairo_paginated_surface_t *surface)
case CAIRO_SURFACE_TYPE_XCB:
case CAIRO_SURFACE_TYPE_GLITZ:
case CAIRO_SURFACE_TYPE_QUARTZ:
case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE:
case CAIRO_SURFACE_TYPE_WIN32:
case CAIRO_SURFACE_TYPE_BEOS:
case CAIRO_SURFACE_TYPE_DIRECTFB:

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

@ -138,15 +138,14 @@ _cairo_path_bounder_close_path (void *closure)
}
/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
void
cairo_status_t
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2,
double tolerance)
{
cairo_status_t status;
cairo_path_bounder_t bounder;
cairo_status_t status;
_cairo_path_bounder_init (&bounder);
@ -156,9 +155,8 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
_cairo_path_bounder_close_path,
&bounder,
tolerance);
assert (status == CAIRO_STATUS_SUCCESS);
if (bounder.has_point) {
if (status == CAIRO_STATUS_SUCCESS && 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);
@ -171,4 +169,6 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
}
_cairo_path_bounder_fini (&bounder);
return status;
}

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

@ -214,71 +214,9 @@ static cairo_int_status_t
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
cairo_traps_t *traps)
{
cairo_path_buf_t *buf = &path->buf_head.base;
int final;
/* Ensure the path has the operators we expect for a rectangular path.
*/
if (buf == NULL || buf->num_ops < 5)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (buf->op[0] != CAIRO_PATH_OP_MOVE_TO ||
buf->op[1] != CAIRO_PATH_OP_LINE_TO ||
buf->op[2] != CAIRO_PATH_OP_LINE_TO ||
buf->op[3] != CAIRO_PATH_OP_LINE_TO)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Now, there are choices. The rectangle might end with a LINE_TO
* (to the original point), but this isn't required. If it
* doesn't, then it must end with a CLOSE_PATH. */
if (buf->op[4] == CAIRO_PATH_OP_LINE_TO) {
if (buf->points[4].x != buf->points[0].x ||
buf->points[4].y != buf->points[0].y)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
} else if (buf->op[4] != CAIRO_PATH_OP_CLOSE_PATH) {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Finally, a trailing CLOSE_PATH or MOVE_TO after the rectangle
* is fine. But anything more than that means we must return
* unsupported. */
final = 5;
if (final < buf->num_ops &&
buf->op[final] == CAIRO_PATH_OP_CLOSE_PATH)
{
final++;
}
if (final < buf->num_ops &&
buf->op[final] == CAIRO_PATH_OP_MOVE_TO)
{
final++;
}
if (final < buf->num_ops)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Now that we've verified the operators, we must ensure that the
* path coordinates are consistent with a rectangle. There are two
* choices here. */
if (buf->points[0].y == buf->points[1].y &&
buf->points[1].x == buf->points[2].x &&
buf->points[2].y == buf->points[3].y &&
buf->points[3].x == buf->points[0].x)
{
if (_cairo_path_fixed_is_box (path, NULL)) {
return _cairo_traps_tessellate_convex_quad (traps,
buf->points);
}
if (buf->points[0].x == buf->points[1].x &&
buf->points[1].y == buf->points[2].y &&
buf->points[2].x == buf->points[3].x &&
buf->points[3].y == buf->points[0].y)
{
return _cairo_traps_tessellate_convex_quad (traps,
buf->points);
path->buf_head.base.points);
}
return CAIRO_INT_STATUS_UNSUPPORTED;

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

@ -721,3 +721,108 @@ _cairo_path_fixed_interpret_flat (cairo_path_fixed_t *path,
_cpf_close_path,
&flattener);
}
cairo_bool_t
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path)
{
if (path->buf_head.base.num_ops == 0)
return TRUE;
return FALSE;
}
/**
* Check whether the given path contains a single rectangle.
*/
cairo_bool_t
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
cairo_box_t *box)
{
cairo_path_buf_t *buf = &path->buf_head.base;
/* We can't have more than one buf for this check */
if (buf->next != NULL)
return FALSE;
/* Do we have the right number of ops? */
if (buf->num_ops != 5 && buf->num_ops != 6)
return FALSE;
/* Check whether the ops are those that would be used for a rectangle */
if (buf->op[0] != CAIRO_PATH_OP_MOVE_TO ||
buf->op[1] != CAIRO_PATH_OP_LINE_TO ||
buf->op[2] != CAIRO_PATH_OP_LINE_TO ||
buf->op[3] != CAIRO_PATH_OP_LINE_TO)
{
return FALSE;
}
/* Now, there are choices. The rectangle might end with a LINE_TO
* (to the original point), but this isn't required. If it
* doesn't, then it must end with a CLOSE_PATH. */
if (buf->op[4] == CAIRO_PATH_OP_LINE_TO) {
if (buf->points[4].x != buf->points[0].x ||
buf->points[4].y != buf->points[0].y)
return FALSE;
} else if (buf->op[4] != CAIRO_PATH_OP_CLOSE_PATH) {
return FALSE;
}
if (buf->num_ops == 6) {
/* A trailing CLOSE_PATH or MOVE_TO is ok */
if (buf->op[5] != CAIRO_PATH_OP_MOVE_TO &&
buf->op[5] != CAIRO_PATH_OP_CLOSE_PATH)
return FALSE;
}
/* Ok, we may have a box, if the points line up */
if (buf->points[0].y == buf->points[1].y &&
buf->points[1].x == buf->points[2].x &&
buf->points[2].y == buf->points[3].y &&
buf->points[3].x == buf->points[0].x)
{
if (box) {
box->p1 = buf->points[0];
box->p2 = buf->points[2];
}
return TRUE;
}
if (buf->points[0].x == buf->points[1].x &&
buf->points[1].y == buf->points[2].y &&
buf->points[2].x == buf->points[3].x &&
buf->points[3].y == buf->points[0].y)
{
if (box) {
box->p1 = buf->points[0];
box->p2 = buf->points[2];
}
return TRUE;
}
return FALSE;
}
/**
* Check whether the given path contains a single rectangle
* that is logically equivalent to:
* cairo_move_to (cr, x, y);
* cairo_rel_line_to (cr, width, 0);
* cairo_rel_line_to (cr, 0, height);
* cairo_rel_line_to (cr, -width, 0);
* cairo_close_path (cr);
*/
cairo_bool_t
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
cairo_box_t *box)
{
cairo_path_buf_t *buf = &path->buf_head.base;
if (!_cairo_path_fixed_is_box (path, box))
return FALSE;
if (buf->points[0].y == buf->points[1].y)
return TRUE;
return FALSE;
}

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

@ -235,7 +235,7 @@ _cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out
_cairo_slope_init (&in_slope, &in->point, &in->cw);
_cairo_slope_init (&out_slope, &out->point, &out->cw);
return _cairo_slope_clockwise (&in_slope, &out_slope);
return _cairo_slope_compare (&in_slope, &out_slope) < 0;
}
/**

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

@ -97,7 +97,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule);
cairo_int_status_t
cairo_private cairo_int_status_t
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,

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

@ -323,7 +323,24 @@ _cairo_pdf_path_close_path (void *closure)
}
_cairo_output_stream_printf (info->output,
"h\r\n");
"h\n");
return _cairo_output_stream_get_status (info->output);
}
static cairo_status_t
_cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
{
double x1 = _cairo_fixed_to_double (box->p1.x);
double y1 = _cairo_fixed_to_double (box->p1.y);
double x2 = _cairo_fixed_to_double (box->p2.x);
double y2 = _cairo_fixed_to_double (box->p2.y);
cairo_matrix_transform_point (info->path_transform, &x1, &y1);
cairo_matrix_transform_point (info->path_transform, &x2, &y2);
_cairo_output_stream_printf (info->output,
"%f %f %f %f re ",
x1, y1, x2 - x1, y2 - y1);
return _cairo_output_stream_get_status (info->output);
}
@ -346,6 +363,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
cairo_output_stream_t *word_wrap;
cairo_status_t status, status2;
pdf_path_info_t info;
cairo_box_t box;
word_wrap = _word_wrap_stream_create (pdf_operators->stream, 79);
status = _cairo_output_stream_get_status (word_wrap);
@ -355,13 +373,17 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
info.output = word_wrap;
info.path_transform = path_transform;
info.line_cap = line_cap;
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
_cairo_pdf_path_move_to,
_cairo_pdf_path_line_to,
_cairo_pdf_path_curve_to,
_cairo_pdf_path_close_path,
&info);
if (_cairo_path_fixed_is_rectangle (path, &box)) {
status = _cairo_pdf_path_rectangle (&info, &box);
} else {
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
_cairo_pdf_path_move_to,
_cairo_pdf_path_line_to,
_cairo_pdf_path_curve_to,
_cairo_pdf_path_close_path,
&info);
}
status2 = _cairo_output_stream_destroy (word_wrap);
if (status == CAIRO_STATUS_SUCCESS)
@ -402,7 +424,7 @@ _cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
}
_cairo_output_stream_printf (pdf_operators->stream,
"%s n\r\n",
"%s n\n",
pdf_operator);
return _cairo_output_stream_get_status (pdf_operators->stream);
@ -512,15 +534,15 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
}
_cairo_output_stream_printf (pdf_operators->stream,
"%f w\r\n",
"%f w\n",
style->line_width);
_cairo_output_stream_printf (pdf_operators->stream,
"%d J\r\n",
"%d J\n",
_cairo_pdf_line_cap (style->line_cap));
_cairo_output_stream_printf (pdf_operators->stream,
"%d j\r\n",
"%d j\n",
_cairo_pdf_line_join (style->line_join));
if (num_dashes) {
@ -529,10 +551,10 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (pdf_operators->stream, "[");
for (d = 0; d < num_dashes; d++)
_cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d]);
_cairo_output_stream_printf (pdf_operators->stream, "] %f d\r\n",
_cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
dash_offset);
} else {
_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\r\n");
_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
}
if (dash != style->dash)
free (dash);
@ -563,7 +585,7 @@ _cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
_cairo_output_stream_printf (pdf_operators->stream,
"q %f %f %f %f %f %f cm\r\n",
"q %f %f %f %f %f %f cm\n",
m.xx, m.yx, m.xy, m.yy,
m.x0, m.y0);
@ -574,7 +596,7 @@ _cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
if (status)
return status;
_cairo_output_stream_printf (pdf_operators->stream, "S Q\r\n");
_cairo_output_stream_printf (pdf_operators->stream, "S Q\n");
return _cairo_output_stream_get_status (pdf_operators->stream);
}
@ -606,7 +628,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
}
_cairo_output_stream_printf (pdf_operators->stream,
"%s\r\n",
"%s\n",
pdf_operator);
return _cairo_output_stream_get_status (pdf_operators->stream);
@ -632,7 +654,7 @@ _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
_cairo_output_stream_printf (pdf_operators->stream,
"q %f %f %f %f %f %f cm\r\n",
"q %f %f %f %f %f %f cm\n",
m.xx, m.yx, m.xy, m.yy,
m.x0, m.y0);
@ -655,7 +677,7 @@ _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
}
_cairo_output_stream_printf (pdf_operators->stream,
"%s Q\r\n",
"%s Q\n",
pdf_operator);
return _cairo_output_stream_get_status (pdf_operators->stream);
@ -672,7 +694,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
unsigned int current_subset_id = (unsigned int)-1;
cairo_scaled_font_subsets_glyph_t subset_glyph;
cairo_bool_t diagonal, in_TJ;
cairo_status_t status;
cairo_status_t status, status_ignored;
double Tlm_x = 0, Tlm_y = 0;
double Tm_x = 0, y;
int i, hex_width;
@ -687,7 +709,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
return status;
_cairo_output_stream_printf (word_wrap_stream,
"BT\r\n");
"BT\n");
if (scaled_font->scale.xy == 0.0 &&
scaled_font->scale.yx == 0.0)
@ -700,8 +722,10 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
scaled_font, glyphs[i].index,
&subset_glyph);
if (status)
if (status) {
status_ignored = _cairo_output_stream_destroy (word_wrap_stream);
return status;
}
if (subset_glyph.is_composite)
hex_width = 4;
@ -717,25 +741,27 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
if (subset_glyph.subset_id != current_subset_id) {
if (in_TJ) {
_cairo_output_stream_printf (word_wrap_stream, ">] TJ\r\n");
_cairo_output_stream_printf (word_wrap_stream, ">] TJ\n");
in_TJ = FALSE;
}
_cairo_output_stream_printf (word_wrap_stream,
"/f-%d-%d 1 Tf\r\n",
"/f-%d-%d 1 Tf\n",
subset_glyph.font_id,
subset_glyph.subset_id);
if (pdf_operators->use_font_subset) {
status = pdf_operators->use_font_subset (subset_glyph.font_id,
subset_glyph.subset_id,
pdf_operators->use_font_subset_closure);
if (status)
if (status) {
status_ignored = _cairo_output_stream_destroy (word_wrap_stream);
return status;
}
}
}
if (subset_glyph.subset_id != current_subset_id || !diagonal) {
_cairo_output_stream_printf (word_wrap_stream,
"%f %f %f %f %f %f Tm\r\n",
"%f %f %f %f %f %f Tm\n",
scaled_font->scale.xx,
-scaled_font->scale.yx,
-scaled_font->scale.xy,
@ -756,7 +782,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
if (!in_TJ) {
if (i != 0) {
_cairo_output_stream_printf (word_wrap_stream,
"%f %f Td\r\n",
"%f %f Td\n",
(glyphs[i].x - Tlm_x)/scaled_font->scale.xx,
(glyphs[i].y - Tlm_y)/scaled_font->scale.yy);
@ -798,7 +824,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
Tm_x += delta;
}
_cairo_output_stream_printf (word_wrap_stream,
"%0*x>] TJ\r\n",
"%0*x>] TJ\n",
hex_width,
subset_glyph.subset_glyph_index);
Tm_x += subset_glyph.x_advance;
@ -822,14 +848,14 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
}
} else {
_cairo_output_stream_printf (word_wrap_stream,
"<%0*x> Tj\r\n",
"<%0*x> Tj\n",
hex_width,
subset_glyph.subset_glyph_index);
}
}
_cairo_output_stream_printf (word_wrap_stream,
"ET\r\n");
"ET\n");
status = _cairo_output_stream_destroy (word_wrap_stream);
if (status)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -302,13 +302,15 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
/*
* Find active pen vertex for clockwise edge of stroke at the given slope.
*
* Note: The behavior of this function is sensitive to the sense of
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
* The strictness of the inequalities here is delicate. The issue is
* that the slope_ccw member of one pen vertex will be equivalent to
* the slope_cw member of the next pen vertex in a counterclockwise
* order. However, for this function, we care strongly about which
* vertex is returned.
*
* The issue is that the slope_ccw member of one pen vertex will be
* equivalent to the slope_cw member of the next pen vertex in a
* counterclockwise order. However, for this function, we care
* strongly about which vertex is returned.
* [I think the "care strongly" above has to do with ensuring that the
* pen's "extra points" from the spline's initial and final slopes are
* properly found when beginning the spline stroking.]
*/
void
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
@ -318,8 +320,8 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
int i;
for (i=0; i < pen->num_vertices; i++) {
if (_cairo_slope_clockwise (slope, &pen->vertices[i].slope_ccw)
&& _cairo_slope_counter_clockwise (slope, &pen->vertices[i].slope_cw))
if ((_cairo_slope_compare (slope, &pen->vertices[i].slope_ccw) < 0) &&
(_cairo_slope_compare (slope, &pen->vertices[i].slope_cw) >= 0))
break;
}
@ -336,8 +338,8 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
/* Find active pen vertex for counterclockwise edge of stroke at the given slope.
*
* Note: The behavior of this function is sensitive to the sense of
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
* Note: See the comments for _cairo_pen_find_active_cw_vertex_index
* for some details about the strictness of the inequalities here.
*/
void
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
@ -352,8 +354,8 @@ _cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
slope_reverse.dy = -slope_reverse.dy;
for (i=pen->num_vertices-1; i >= 0; i--) {
if (_cairo_slope_counter_clockwise (&pen->vertices[i].slope_ccw, &slope_reverse)
&& _cairo_slope_clockwise (&pen->vertices[i].slope_cw, &slope_reverse))
if ((_cairo_slope_compare (&pen->vertices[i].slope_ccw, &slope_reverse) >= 0) &&
(_cairo_slope_compare (&pen->vertices[i].slope_cw, &slope_reverse) < 0))
break;
}
@ -415,10 +417,21 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
slope = final_slope;
else
_cairo_slope_init (&slope, &point[i], &point[i+step]);
if (_cairo_slope_counter_clockwise (&slope, &pen->vertices[active].slope_ccw)) {
/* The strict inequalities here ensure that if a spline slope
* compares identically with either of the slopes of the
* active vertex, then it remains the active vertex. This is
* very important since otherwise we can trigger an infinite
* loop in the case of a degenerate pen, (a line), where
* neither vertex considers itself active for the slope---one
* will consider it as equal and reject, and the other will
* consider it unequal and reject. This is due to the inherent
* ambiguity when comparing slopes that differ by exactly
* pi. */
if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_ccw) > 0) {
if (++active == pen->num_vertices)
active = 0;
} else if (_cairo_slope_clockwise (&slope, &pen->vertices[active].slope_cw)) {
} else if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_cw) < 0) {
if (--active == -1)
active = pen->num_vertices - 1;
} else {

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

@ -169,6 +169,8 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
"/l { lineto } bind def\n"
"/c { curveto } bind def\n"
"/h { closepath } bind def\n"
"/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto\n"
" 0 exch rlineto 0 rlineto closepath } bind def\n"
"/S { stroke } bind def\n"
"/f { fill } bind def\n"
"/f* { eofill } bind def\n"
@ -1323,7 +1325,7 @@ static void
_cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
{
_cairo_output_stream_printf (surface->stream,
"grestore\n");
"Q\n");
}
static cairo_int_status_t
@ -1626,16 +1628,16 @@ _string_array_stream_write (cairo_output_stream_t *base,
stream->column++;
stream->string_size++;
break;
/* Have to also be careful to never split the final ~> sequence. */
case '~':
_cairo_output_stream_write (stream->output, &c, 1);
stream->column++;
stream->string_size++;
length--;
c = *data++;
break;
}
}
/* Have to be careful to never split the final ~> sequence. */
if (c == '~') {
_cairo_output_stream_write (stream->output, &c, 1);
stream->column++;
stream->string_size++;
length--;
c = *data++;
}
_cairo_output_stream_write (stream->output, &c, 1);
stream->column++;
stream->string_size++;
@ -2080,7 +2082,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_ps);
_cairo_output_stream_printf (surface->stream,
" gsave\n"
" q\n"
" 0 0 %f %f rectclip\n",
surface->width,
surface->height);
@ -2100,7 +2102,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
return status;
_cairo_output_stream_printf (surface->stream,
" grestore\n");
" Q\n");
surface->content = old_content;
surface->width = old_width;
surface->height = old_height;
@ -2259,7 +2261,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
int pattern_height = 0; /* squelch bogus compiler warning */
double xstep, ystep;
cairo_matrix_t cairo_p2d, ps_p2d;
cairo_rectangle_int16_t surface_extents;
cairo_rectangle_int_t surface_extents;
cairo_bool_t old_use_string_datasource;
cairo_p2d = pattern->base.matrix;
@ -2958,7 +2960,7 @@ _cairo_ps_surface_stroke (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
_cairo_output_stream_printf (surface->stream,
"%% _cairo_ps_surface_stroke\n");
#endif
@ -2991,7 +2993,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
_cairo_output_stream_printf (surface->stream,
"%% _cairo_ps_surface_fill\n");
#endif
@ -3046,7 +3048,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
_cairo_output_stream_printf (surface->stream,
"%% _cairo_ps_surface_show_glyphs\n");
#endif
@ -3120,7 +3122,7 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
_cairo_output_stream_printf (surface->stream,
"%%%%EndPageSetup\n"
"gsave\n");
"q\n");
if (surface->num_pages == 1) {
surface->bbox_x1 = x1;

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

@ -77,11 +77,12 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
case CAIRO_FORMAT_RGB24:
if (colorSpace == NULL)
colorSpace = CGColorSpaceCreateDeviceRGB();
bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
bitsPerComponent = 8;
bitsPerPixel = 32;
break;
/* XXX -- should use CGImageMaskCreate! */
case CAIRO_FORMAT_A8:
if (colorSpace == NULL)
colorSpace = CGColorSpaceCreateDeviceGray();
@ -90,6 +91,7 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
bitsPerPixel = 8;
break;
case CAIRO_FORMAT_A1:
default:
return NULL;
}
@ -269,15 +271,12 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
* cairo_quartz_image_surface_create
* @surface: a cairo image surface to wrap with a quartz image surface
*
* Creates a Quartz surface backed by a CGImageRef that references
* the given image surface.
*
* Data is to be loaded into this surface by calling
* cairo_quartz_image_surface_get_image, and performing operations on the
* resulting image surface.
*
* The resulting surface can be rendered quickly when used as a source
* when rendering to a cairo_quartz_surface.
* Creates a Quartz surface backed by a CGImageRef that references the
* given image surface. The resulting surface can be rendered quickly
* when used as a source when rendering to a #cairo_quartz_surface. If
* the data in the image surface is ever updated, cairo_surface_flush()
* must be called on the #cairo_quartz_image_surface to ensure that the
* CGImageRef refers to the updated data.
*
* Return value: the newly created surface.
*
@ -324,8 +323,10 @@ cairo_quartz_image_surface_create (cairo_surface_t *surface)
memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t));
// ref this here; in case the create_cgimage fails, it will
// be released by the callback.
/* In case the create_cgimage fails, this ref will
* be released via the callback (which will be called in
* case of failure.)
*/
cairo_surface_reference (surface);
image = _cairo_quartz_create_cgimage (format,

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

@ -64,6 +64,8 @@ typedef struct cairo_quartz_surface {
CGShadingRef sourceShading;
CGPatternRef sourcePattern;
CGInterpolationQuality oldInterpolationQuality;
} cairo_quartz_surface_t;
typedef struct cairo_quartz_image_surface {

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

@ -34,12 +34,12 @@
* Vladimir Vukicevic <vladimir@mozilla.com>
*/
#include <dlfcn.h>
#include "cairoint.h"
#include "cairo-quartz-private.h"
#include <dlfcn.h>
/* The 10.5 SDK includes a funky new definition of FloatToFixed which
* causes all sorts of breakage; so reset to old-style definition
*/
@ -106,6 +106,7 @@ CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
static void (*CGContextClipToMaskPtr) (CGContextRef, CGRect, CGImageRef) = NULL;
/* Only present in 10.5+ */
static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
@ -130,10 +131,24 @@ static void quartz_ensure_symbols(void)
CGContextClipToMaskPtr = dlsym(RTLD_DEFAULT, "CGContextClipToMask");
CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetTypePtr");
_cairo_quartz_symbol_lookup_done = TRUE;
}
static inline cairo_bool_t
_cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc) {
if (CGContextGetTypePtr) {
/* 4 is the type value of a bitmap context */
if (CGContextGetTypePtr(cgc) == 4)
return TRUE;
return FALSE;
}
/* This will cause a (harmless) warning to be printed if called on a non-bitmap context */
return CGBitmapContextGetBitsPerPixel(surface->cgContext) != 0;
}
/* CoreGraphics limitation with flipped CTM surfaces: height must be less than signed 16-bit max */
#define CG_MAX_HEIGHT SHRT_MAX
@ -296,7 +311,7 @@ _cairo_quartz_cairo_operator_to_quartz (cairo_operator_t op)
return kPrivateCGCompositeCopy;
}
static CGLineCap
static inline CGLineCap
_cairo_quartz_cairo_line_cap_to_quartz (cairo_line_cap_t ccap)
{
switch (ccap) {
@ -308,7 +323,7 @@ _cairo_quartz_cairo_line_cap_to_quartz (cairo_line_cap_t ccap)
return kCGLineCapButt;
}
static CGLineJoin
static inline CGLineJoin
_cairo_quartz_cairo_line_join_to_quartz (cairo_line_join_t cjoin)
{
switch (cjoin) {
@ -320,9 +335,29 @@ _cairo_quartz_cairo_line_join_to_quartz (cairo_line_join_t cjoin)
return kCGLineJoinMiter;
}
static void
static inline CGInterpolationQuality
_cairo_quartz_filter_to_quartz (cairo_filter_t filter)
{
switch (filter) {
case CAIRO_FILTER_NEAREST:
return kCGInterpolationNone;
case CAIRO_FILTER_FAST:
return kCGInterpolationLow;
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BILINEAR:
case CAIRO_FILTER_GAUSSIAN:
return kCGInterpolationDefault;
}
return kCGInterpolationDefault;
}
static inline void
_cairo_quartz_cairo_matrix_to_quartz (const cairo_matrix_t *src,
CGAffineTransform *dst)
CGAffineTransform *dst)
{
dst->a = src->xx;
dst->b = src->yx;
@ -394,7 +429,7 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat)
&callbacks);
}
/* Obtain a CGImageRef from a cairo_surface_t * */
/* Obtain a CGImageRef from a #cairo_surface_t * */
static CGImageRef
_cairo_surface_to_cgimage (cairo_surface_t *target,
@ -443,7 +478,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
return image;
}
/* Generic cairo_pattern -> CGPattern function */
/* Generic #cairo_pattern_t -> CGPattern function */
typedef struct {
CGImageRef image;
@ -461,16 +496,27 @@ SurfacePatternDrawFunc (void *ainfo, CGContextRef context)
CGContextDrawImage (context, info->imageBounds, info->image);
if (info->do_reflect) {
/* draw 3 more copies of the image, flipped. */
CGContextTranslateCTM (context, 0, 2 * info->imageBounds.size.height);
/* draw 3 more copies of the image, flipped.
* DrawImage draws the image according to the current Y-direction into the rectangle given
* (imageBounds); at the time of the first DrawImage above, the origin is at the bottom left
* of the base image position, and the Y axis is extending upwards.
*/
/* Make the y axis extend downwards, and draw a flipped image below */
CGContextScaleCTM (context, 1, -1);
CGContextDrawImage (context, info->imageBounds, info->image);
/* Shift over to the right, and flip vertically (translation is 2x,
* since we'll be flipping and thus rendering the rectangle "backwards"
*/
CGContextTranslateCTM (context, 2 * info->imageBounds.size.width, 0);
CGContextScaleCTM (context, -1, 1);
CGContextDrawImage (context, info->imageBounds, info->image);
CGContextTranslateCTM (context, 0, 2 * info->imageBounds.size.height);
/* Then unflip the Y-axis again, and draw the image above the point. */
CGContextScaleCTM (context, 1, -1);
CGContextDrawImage (context, info->imageBounds, info->image);
}
}
@ -483,33 +529,6 @@ SurfacePatternReleaseInfoFunc (void *ainfo)
free (info);
}
/* Borrowed from cairo-meta-surface */
static cairo_status_t
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
cairo_status_t status;
status = _cairo_pattern_init_copy (pattern, other);
if (status)
return status;
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
(cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
surface_pattern->surface = _cairo_surface_snapshot (surface);
cairo_surface_destroy (surface);
if (surface_pattern->surface->status)
return surface_pattern->surface->status;
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t *dest,
cairo_pattern_t *apattern,
@ -562,14 +581,14 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
info->image = image;
info->imageBounds = CGRectMake (0, 0, extents.width, extents.height);
info->do_reflect = (spattern->base.extend == CAIRO_EXTEND_REFLECT);
pbounds.origin.x = 0;
pbounds.origin.y = 0;
if (spattern->base.extend == CAIRO_EXTEND_REFLECT) {
pbounds.size.width = 2 * extents.width;
pbounds.size.height = 2 * extents.height;
pbounds.size.width = 2.0 * extents.width;
pbounds.size.height = 2.0 * extents.height;
info->do_reflect = TRUE;
} else {
pbounds.size.width = extents.width;
pbounds.size.height = extents.height;
@ -734,6 +753,9 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
{
assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern));
surface->oldInterpolationQuality = CGContextGetInterpolationQuality (surface->cgContext);
CGContextSetInterpolationQuality (surface->cgContext, _cairo_quartz_filter_to_quartz (source->filter));
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
@ -871,6 +893,8 @@ static void
_cairo_quartz_teardown_source (cairo_quartz_surface_t *surface,
cairo_pattern_t *source)
{
CGContextSetInterpolationQuality (surface->cgContext, surface->oldInterpolationQuality);
if (surface->sourceImage) {
CGImageRelease(surface->sourceImage);
surface->sourceImage = NULL;
@ -915,7 +939,7 @@ _cairo_quartz_get_image (cairo_quartz_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
if (CGBitmapContextGetBitsPerPixel(surface->cgContext) != 0) {
if (_cairo_quartz_is_cgcontext_bitmap_context(surface->cgContext)) {
unsigned int stride;
unsigned int bitinfo;
unsigned int bpc, bpp;
@ -1260,6 +1284,7 @@ _cairo_quartz_surface_fill (void *abstract_surface,
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
cairo_quartz_action_t action;
quartz_stroke_t stroke;
cairo_box_t box;
ND((stderr, "%p _cairo_quartz_surface_fill op %d source->type %d\n", surface, op, source->type));
@ -1269,6 +1294,16 @@ _cairo_quartz_surface_fill (void *abstract_surface,
if (op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
/* Check whether the path would be a no-op */
/* XXX handle unbounded ops */
if (_cairo_path_fixed_is_empty(path) ||
(_cairo_path_fixed_is_box(path, &box) &&
box.p1.x == box.p2.x &&
box.p1.y == box.p2.y))
{
return CAIRO_STATUS_SUCCESS;
}
CGContextSaveGState (surface->cgContext);
CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
@ -1593,6 +1628,7 @@ _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
CGImageRef img;
cairo_surface_t *pat_surf = mask->surface;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
CGAffineTransform ctm, mask_matrix;
status = _cairo_surface_get_extents (pat_surf, &extents);
if (status)
@ -1608,9 +1644,23 @@ _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
goto BAIL;
}
rect = CGRectMake (-mask->base.matrix.x0, -mask->base.matrix.y0, extents.width, extents.height);
rect = CGRectMake (0.0f, 0.0f, extents.width, extents.height);
CGContextSaveGState (surface->cgContext);
/* ClipToMask is essentially drawing an image, so we need to flip the CTM
* to get the image to appear oriented the right way */
ctm = CGContextGetCTM (surface->cgContext);
_cairo_quartz_cairo_matrix_to_quartz (&mask->base.matrix, &mask_matrix);
CGContextConcatCTM (surface->cgContext, CGAffineTransformInvert(mask_matrix));
CGContextTranslateCTM (surface->cgContext, 0.0f, rect.size.height);
CGContextScaleCTM (surface->cgContext, 1.0f, -1.0f);
CGContextClipToMaskPtr (surface->cgContext, rect, img);
CGContextSetCTM (surface->cgContext, ctm);
status = _cairo_quartz_surface_paint (surface, op, source);
CGContextRestoreGState (surface->cgContext);
@ -1619,11 +1669,57 @@ _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
return status;
}
/* This is somewhat less than ideal, but it gets the job done;
* it would be better to avoid calling back into cairo. This
* creates a temporary surface to use as the mask.
*/
static cairo_int_status_t
_cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_pattern_t *mask)
{
int width = surface->extents.width - surface->extents.x;
int height = surface->extents.height - surface->extents.y;
cairo_surface_t *gradient_surf = NULL;
cairo_t *gradient_surf_cr = NULL;
cairo_pattern_union_t surface_pattern;
cairo_int_status_t status;
/* Render the gradient to a surface */
gradient_surf = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32,
width,
height);
gradient_surf_cr = cairo_create(gradient_surf);
cairo_set_source (gradient_surf_cr, mask);
cairo_set_operator (gradient_surf_cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (gradient_surf_cr);
status = cairo_status (gradient_surf_cr);
cairo_destroy (gradient_surf_cr);
if (status)
goto BAIL;
_cairo_pattern_init_for_surface (&surface_pattern.surface, gradient_surf);
status = _cairo_quartz_surface_mask_with_surface (surface, op, source, &surface_pattern.surface);
_cairo_pattern_fini (&surface_pattern.base);
BAIL:
if (gradient_surf)
cairo_surface_destroy (gradient_surf);
return status;
}
static cairo_int_status_t
_cairo_quartz_surface_mask (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_pattern_t *mask)
cairo_operator_t op,
cairo_pattern_t *source,
cairo_pattern_t *mask)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@ -1638,30 +1734,29 @@ _cairo_quartz_surface_mask (void *abstract_surface,
cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
CGContextSetAlpha (surface->cgContext, solid_mask->color.alpha);
} 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);
} else {
/* So, CGContextClipToMask is not present in 10.3.9, so we're
* doomed; if we have imageData, we can do fallback, otherwise
* just pretend success.
*/
if (surface->imageData)
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_STATUS_SUCCESS;
}
rv = _cairo_quartz_surface_paint (surface, op, source);
if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
rv = _cairo_quartz_surface_paint (surface, op, source);
CGContextSetAlpha (surface->cgContext, 1.0);
return rv;
}
ND((stderr, "-- mask\n"));
/* If we have CGContextClipToMask, we can do more complex masks */
if (CGContextClipToMaskPtr) {
/* For these, we can skip creating a temporary surface, since we already have one */
if (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);
return rv;
return _cairo_quartz_surface_mask_with_generic (surface, op, source, mask);
}
/* So, CGContextClipToMask is not present in 10.3.9, so we're
* doomed; if we have imageData, we can do fallback, otherwise
* just pretend success.
*/
if (surface->imageData)
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t

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

@ -51,6 +51,7 @@
#define cairo_font_options_set_hint_style _moz_cairo_font_options_set_hint_style
#define cairo_font_options_set_subpixel_order _moz_cairo_font_options_set_subpixel_order
#define cairo_font_options_status _moz_cairo_font_options_status
#define cairo_format_stride_for_width _moz_cairo_format_stride_for_width
#define cairo_ft_font_face_create_for_ft_face _moz_cairo_ft_font_face_create_for_ft_face
#define cairo_ft_font_face_create_for_pattern _moz_cairo_ft_font_face_create_for_pattern
#define cairo_ft_font_options_substitute _moz_cairo_ft_font_options_substitute
@ -80,6 +81,7 @@
#define cairo_glitz_surface_create _moz_cairo_glitz_surface_create
#define cairo_glyph_extents _moz_cairo_glyph_extents
#define cairo_glyph_path _moz_cairo_glyph_path
#define cairo_has_current_point _moz_cairo_has_current_point
#define cairo_identity_matrix _moz_cairo_identity_matrix
#define cairo_image_surface_create _moz_cairo_image_surface_create
#define cairo_image_surface_create_for_data _moz_cairo_image_surface_create_for_data
@ -166,11 +168,11 @@
#define cairo_ps_surface_set_size _moz_cairo_ps_surface_set_size
#define cairo_push_group _moz_cairo_push_group
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
#define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create
#define cairo_quartz_image_surface_get_image _moz_cairo_quartz_image_surface_get_image
#define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
#define cairo_quartz_surface_create_for_cg_context _moz_cairo_quartz_surface_create_for_cg_context
#define cairo_quartz_surface_get_cg_context _moz_cairo_quartz_surface_get_cg_context
#define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create
#define cairo_quartz_image_surface_get_image _moz_cairo_quartz_image_surface_get_image
#define cairo_rectangle _moz_cairo_rectangle
#define cairo_rectangle_list_destroy _moz_cairo_rectangle_list_destroy
#define cairo_reference _moz_cairo_reference
@ -289,6 +291,7 @@
#define cairo_xlib_surface_get_screen _moz_cairo_xlib_surface_get_screen
#define cairo_xlib_surface_get_visual _moz_cairo_xlib_surface_get_visual
#define cairo_xlib_surface_get_width _moz_cairo_xlib_surface_get_width
#define cairo_xlib_surface_get_xrender_format _moz_cairo_xlib_surface_get_xrender_format
#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

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

@ -217,23 +217,22 @@ _cairo_sub_font_init_key (cairo_sub_font_t *sub_font,
}
}
static cairo_sub_font_t *
static cairo_status_t
_cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_scaled_font_t *scaled_font,
unsigned int font_id,
int max_glyphs_per_subset,
cairo_bool_t is_scaled,
cairo_bool_t is_composite)
cairo_bool_t is_composite,
cairo_sub_font_t **sub_font_out)
{
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) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (sub_font == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
sub_font->is_scaled = is_scaled;
sub_font->is_composite = is_composite;
@ -248,19 +247,21 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
if (! sub_font->sub_font_glyphs) {
if (sub_font->sub_font_glyphs == NULL) {
free (sub_font);
return NULL;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
/* 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;
_cairo_hash_table_destroy (sub_font->sub_font_glyphs);
free (sub_font);
return status;
}
return sub_font;
*sub_font_out = sub_font;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -584,15 +585,16 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
subset_glyph->is_composite = FALSE;
}
sub_font = _cairo_sub_font_create (subsets,
unscaled_font,
subsets->num_sub_fonts,
max_glyphs,
subset_glyph->is_scaled,
subset_glyph->is_composite);
if (sub_font == NULL) {
status = _cairo_sub_font_create (subsets,
unscaled_font,
subsets->num_sub_fonts,
max_glyphs,
subset_glyph->is_scaled,
subset_glyph->is_composite,
&sub_font);
if (status) {
cairo_scaled_font_destroy (unscaled_font);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return status;
}
status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
@ -618,15 +620,16 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
else
max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT;
sub_font = _cairo_sub_font_create (subsets,
cairo_scaled_font_reference (scaled_font),
subsets->num_sub_fonts,
max_glyphs,
subset_glyph->is_scaled,
subset_glyph->is_composite);
if (sub_font == NULL) {
status = _cairo_sub_font_create (subsets,
cairo_scaled_font_reference (scaled_font),
subsets->num_sub_fonts,
max_glyphs,
subset_glyph->is_scaled,
subset_glyph->is_composite,
&sub_font);
if (status) {
cairo_scaled_font_destroy (scaled_font);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return status;
}
status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,

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

@ -1049,7 +1049,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
}
/* "Ink" extents should skip "invisible" glyphs */
if (scaled_glyph->metrics.width == 0 && scaled_glyph->metrics.height == 0)
if (scaled_glyph->metrics.width == 0 || scaled_glyph->metrics.height == 0)
continue;
left = scaled_glyph->metrics.x_bearing + glyphs[i].x;
@ -1089,7 +1089,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
x0 = glyphs[0].x;
y0 = glyphs[0].y;
/* scaled_glyphs contains the glyph for num_glyphs - 1 already. */
/* scaled_glyph contains the glyph for num_glyphs - 1 already. */
x1 = glyphs[num_glyphs - 1].x + scaled_glyph->metrics.x_advance;
y1 = glyphs[num_glyphs - 1].y + scaled_glyph->metrics.y_advance;

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

@ -47,8 +47,15 @@ _cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b)
positive X axis and increase in the direction of the positive Y
axis.
WARNING: This function only gives correct results if the angular
difference between a and b is less than PI.
This function always compares the slope vectors based on the
smaller angular difference between them, (that is based on an
angular difference that is strictly less than pi). To break ties
when comparing slope vectors with an angular difference of exactly
pi, the vector with a positive dx (or positive dy if dx's are zero)
is considered to be more positive than the other.
Also, all slope vectors with both dx==0 and dy==0 are considered
equal and more positive than any non-zero vector.
< 0 => a less positive than b
== 0 => a equal to b
@ -78,28 +85,24 @@ _cairo_slope_compare (cairo_slope_t *a, cairo_slope_t *b)
if (b->dx == 0 && b->dy ==0)
return -1;
/* Finally, we're looking at two vectors that are either equal or
* that differ by exactly pi. We can identify the "differ by pi"
* case by looking for a change in sign in either dx or dy between
* a and b.
*
* And in these cases, we eliminate the ambiguity by reducing the angle
* of b by an infinitesimally small amount, (that is, 'a' will
* always be considered less than 'b').
*/
if (((a->dx > 0) != (b->dx > 0)) ||
((a->dy > 0) != (b->dy > 0)))
{
if (a->dx > 0 || (a->dx == 0 && a->dy > 0))
return +1;
else
return -1;
}
/* Finally, for identical slopes, we obviously return 0. */
return 0;
}
/* XXX: It might be cleaner to move away from usage of
_cairo_slope_clockwise/_cairo_slope_counter_clockwise in favor of
directly using _cairo_slope_compare.
*/
/* Is a clockwise of b?
*
* Note: The strict equality here is not significant in and of itself,
* but there are functions up above that are sensitive to it,
* (cf. _cairo_pen_find_active_cw_vertex_index).
*/
int
_cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b)
{
return _cairo_slope_compare (a, b) < 0;
}
int
_cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b)
{
return ! _cairo_slope_clockwise (a, b);
}

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

@ -941,6 +941,9 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
{
assert (!surface->finished);
if (surface->status)
return surface->status;
if (surface->backend->acquire_source_image == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1007,6 +1010,9 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
{
assert (!surface->finished);
if (surface->status)
return surface->status;
if (surface->backend->acquire_dest_image == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1077,6 +1083,9 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
cairo_image_surface_t *image;
void *image_extra;
if (surface->status)
return surface->status;
if (surface->finished)
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
@ -1139,6 +1148,9 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
cairo_surface_t *
_cairo_surface_snapshot (cairo_surface_t *surface)
{
if (surface->status)
return _cairo_surface_create_in_error (surface->status);
if (surface->finished)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
@ -1298,6 +1310,9 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
num_boxes = _cairo_region_num_boxes (region);
if (num_boxes == 0)
@ -1398,6 +1413,9 @@ _cairo_surface_paint (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
if (status)
return _cairo_surface_set_error (surface, status);
@ -1428,6 +1446,9 @@ _cairo_surface_mask (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
if (status)
goto FINISH;
@ -1471,6 +1492,9 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
{
cairo_status_t status;
if (surface->status)
return surface->status;
if (surface->backend->fill_stroke) {
cairo_pattern_t *dev_stroke_source;
cairo_pattern_t *dev_fill_source;
@ -1534,6 +1558,9 @@ _cairo_surface_stroke (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
if (status)
return _cairo_surface_set_error (surface, status);
@ -1575,6 +1602,9 @@ _cairo_surface_fill (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
if (status)
return _cairo_surface_set_error (surface, status);
@ -1862,6 +1892,9 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface,
{
cairo_status_t status;
if (surface->status)
return surface->status;
if (clip_path == NULL)
return CAIRO_STATUS_SUCCESS;
@ -1933,6 +1966,9 @@ _cairo_surface_set_empty_clip_path (cairo_surface_t *surface,
cairo_path_fixed_t path;
cairo_status_t status;
if (surface->status)
return surface->status;
_cairo_path_fixed_init (&path);
status = surface->backend->intersect_clip_path (surface,
@ -2058,6 +2094,9 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
assert (! surface->is_snapshot);
if (surface->status)
return surface->status;
if (!num_glyphs)
return CAIRO_STATUS_SUCCESS;
@ -2263,6 +2302,9 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
assert (! dst->is_snapshot);
if (dst->status)
return dst->status;
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
* non-repeating sources and masks. Other sources and masks can be ignored.
*/
@ -2338,6 +2380,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
assert (! dst->is_snapshot);
if (dst->status)
return dst->status;
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
* non-repeating sources and masks. Other sources and masks can be ignored.
*/
@ -2413,6 +2458,9 @@ _cairo_surface_set_resolution (cairo_surface_t *surface,
double x_res,
double y_res)
{
if (surface->status)
return;
surface->x_resolution = x_res;
surface->y_resolution = y_res;
}

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

@ -743,31 +743,46 @@ _cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document)
static cairo_bool_t cairo_svg_force_fallbacks = FALSE;
static cairo_int_status_t
_cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
_cairo_svg_surface_analyze_operation (cairo_svg_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
cairo_svg_document_t *document = surface->document;
if (cairo_svg_force_fallbacks)
return FALSE;
if (document->svg_version < CAIRO_SVG_VERSION_1_2)
if (op != CAIRO_OPERATOR_OVER)
return FALSE;
/* SVG doesn't support extend reflect for image pattern */
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
pattern->extend == CAIRO_EXTEND_REFLECT)
return CAIRO_INT_STATUS_UNSUPPORTED;
return TRUE;
if (document->svg_version >= CAIRO_SVG_VERSION_1_2)
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_OVER)
return CAIRO_STATUS_SUCCESS;
/* The SOURCE operator is only supported if there is nothing
* painted underneath. */
if (op == CAIRO_OPERATOR_SOURCE)
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_svg_surface_analyze_operation (cairo_svg_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
_cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
if (_cairo_svg_surface_operation_supported (surface, op, pattern))
return CAIRO_STATUS_SUCCESS;
else
return CAIRO_INT_STATUS_UNSUPPORTED;
if (_cairo_svg_surface_analyze_operation (surface, op, pattern)
!= CAIRO_INT_STATUS_UNSUPPORTED)
{
return TRUE;
} else {
return FALSE;
}
}
static cairo_surface_t *
@ -1993,13 +2008,22 @@ _cairo_svg_surface_mask (void *abstract_surface,
cairo_svg_document_t *document = surface->document;
cairo_output_stream_t *mask_stream;
char buffer[64];
cairo_bool_t discard_filter = FALSE;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return _cairo_svg_surface_analyze_operation (surface, op, source);
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_svg_surface_emit_alpha_filter (document);
if (cairo_pattern_get_type (mask) == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t*) mask;
cairo_content_t content = cairo_surface_get_content (surface_pattern->surface);
if (content == CAIRO_CONTENT_ALPHA)
discard_filter = TRUE;
}
if (!discard_filter)
_cairo_svg_surface_emit_alpha_filter (document);
/* _cairo_svg_surface_emit_paint() will output a pattern definition to
* document->xml_node_defs so we need to write the mask element to
@ -2010,8 +2034,9 @@ _cairo_svg_surface_mask (void *abstract_surface,
_cairo_output_stream_printf (mask_stream,
"<mask id=\"mask%d\">\n"
" <g filter=\"url(#alpha)\">\n",
document->mask_id);
"%s",
document->mask_id,
discard_filter ? "" : " <g filter=\"url(#alpha)\">\n");
status = _cairo_svg_surface_emit_paint (mask_stream, surface, op, mask, NULL);
if (status) {
cairo_status_t ignore = _cairo_output_stream_destroy (mask_stream);
@ -2020,8 +2045,9 @@ _cairo_svg_surface_mask (void *abstract_surface,
}
_cairo_output_stream_printf (mask_stream,
" </g>\n"
"</mask>\n");
"%s"
"</mask>\n",
discard_filter ? "" : " </g>\n");
_cairo_memory_stream_copy (mask_stream, document->xml_node_defs);
status = _cairo_output_stream_destroy (mask_stream);

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

@ -1,3 +1,4 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
@ -183,51 +184,45 @@ typedef struct _cairo_trapezoid {
cairo_line_t left, right;
} cairo_trapezoid_t;
typedef struct _cairo_rectangle_int16 {
struct _cairo_rectangle_int16 {
int16_t x, y;
uint16_t width, height;
} cairo_rectangle_int16_t, cairo_glyph_size_t;
};
typedef struct _cairo_rectangle_int32 {
struct _cairo_rectangle_int32 {
int32_t x, y;
uint32_t width, height;
} cairo_rectangle_int32_t;
};
typedef struct _cairo_point_int16 {
typedef struct _cairo_rectangle_int16 cairo_glyph_size_t;
struct _cairo_point_int16 {
int16_t x, y;
} cairo_point_int16_t;
};
typedef struct _cairo_point_int32 {
struct _cairo_point_int32 {
int32_t x, y;
} cairo_point_int32_t;
typedef struct _cairo_box_int16 {
cairo_point_int16_t p1;
cairo_point_int16_t p2;
} cairo_box_int16_t;
typedef struct _cairo_box_int32 {
cairo_point_int32_t p1;
cairo_point_int32_t p2;
} cairo_box_int32_t;
};
#if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16
typedef cairo_rectangle_int16_t cairo_rectangle_int_t;
typedef cairo_point_int16_t cairo_point_int_t;
typedef cairo_box_int16_t cairo_box_int_t;
typedef struct _cairo_rectangle_int16 cairo_rectangle_int_t;
typedef struct _cairo_point_int16 cairo_point_int_t;
#define CAIRO_RECT_INT_MIN INT16_MIN
#define CAIRO_RECT_INT_MAX INT16_MAX
#elif CAIRO_FIXED_BITS == 32
typedef cairo_rectangle_int32_t cairo_rectangle_int_t;
typedef cairo_point_int32_t cairo_point_int_t;
typedef cairo_box_int32_t cairo_box_int_t;
typedef struct _cairo_rectangle_int32 cairo_rectangle_int_t;
typedef struct _cairo_point_int32 cairo_point_int_t;
#define CAIRO_RECT_INT_MIN INT32_MIN
#define CAIRO_RECT_INT_MAX INT32_MAX
#else
#error Not sure how to pick a cairo_rectangle_int_t for your CAIRO_FIXED_BITS!
#error Not sure how to pick a cairo_rectangle_int_t and cairo_point_int_t for your CAIRO_FIXED_BITS!
#endif
typedef struct _cairo_box_int {
cairo_point_int_t p1;
cairo_point_int_t p2;
} cairo_box_int_t;
typedef enum _cairo_direction {
CAIRO_DIRECTION_FORWARD,
CAIRO_DIRECTION_REVERSE

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

@ -46,7 +46,7 @@
#define SB_NONE 0
#endif
#define WIN32_FONT_LOGICAL_SCALE 1
#define WIN32_FONT_LOGICAL_SCALE 32
typedef struct _cairo_win32_surface {
cairo_surface_t base;

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

@ -765,8 +765,8 @@ _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
cairo_image_surface_t *src_image,
cairo_win32_surface_t *dst,
cairo_rectangle_int_t src_extents,
cairo_rectangle_int32_t src_r,
cairo_rectangle_int32_t dst_r,
cairo_rectangle_int_t src_r,
cairo_rectangle_int_t dst_r,
int alpha,
cairo_bool_t needs_alpha,
cairo_bool_t needs_scale)
@ -874,8 +874,8 @@ _cairo_win32_surface_composite (cairo_operator_t op,
cairo_format_t src_format;
cairo_rectangle_int_t src_extents;
cairo_rectangle_int32_t src_r = { src_x, src_y, width, height };
cairo_rectangle_int32_t dst_r = { dst_x, dst_y, width, height };
cairo_rectangle_int_t src_r = { src_x, src_y, width, height };
cairo_rectangle_int_t dst_r = { dst_x, dst_y, width, height };
#ifdef DEBUG_COMPOSITE
fprintf (stderr, "+++ composite: %d %p %p %p [%d %d] [%d %d] [%d %d] %dx%d\n",
@ -1123,7 +1123,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
* a bunch of piece-by-piece blits.
*/
if (needs_repeat) {
cairo_rectangle_int32_t piece_src_r, piece_dst_r;
cairo_rectangle_int_t piece_src_r, piece_dst_r;
uint32_t rendered_width = 0, rendered_height = 0;
uint32_t to_render_height, to_render_width;
int32_t piece_x, piece_y;
@ -1677,9 +1677,10 @@ _cairo_win32_surface_show_glyphs (void *surface,
*
* Creates a cairo surface that targets the given DC. The DC will be
* queried for its initial clip extents, and this will be used as the
* size of the cairo surface. The resulting surface will always
* be of format CAIRO_FORMAT_RGB24; should you need an ARGB32 surface,
* you will need to create one through cairo_win32_surface_create_with_dib.
* size of the cairo surface. The resulting surface will always be of
* format CAIRO_FORMAT_RGB24; should you need another surface format,
* you will need to create one through
* cairo_win32_surface_create_with_dib().
*
* Return value: the newly created surface
**/

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

@ -302,9 +302,6 @@ _cairo_xlib_display_get (Display *dpy)
display->buggy_repeat = TRUE;
}
/* XXX workaround; see https://bugzilla.mozilla.org/show_bug.cgi?id=413583 */
display->buggy_repeat = TRUE;
display->next = _cairo_xlib_display_list;
_cairo_xlib_display_list = display;

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

@ -1898,6 +1898,8 @@ void
cairo_path_extents (cairo_t *cr,
double *x1, double *y1, double *x2, double *y2)
{
cairo_status_t status;
if (cr->status) {
if (x1)
*x1 = 0.0;
@ -1911,9 +1913,11 @@ cairo_path_extents (cairo_t *cr,
return;
}
_cairo_gstate_path_extents (cr->gstate,
cr->path,
x1, y1, x2, y2);
status = _cairo_gstate_path_extents (cr->gstate,
cr->path,
x1, y1, x2, y2);
if (status)
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_path_extents);

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

@ -1491,6 +1491,7 @@ cairo_surface_status (cairo_surface_t *surface);
* @CAIRO_SURFACE_TYPE_SVG: The surface is of type svg
* @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2
* @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface
* @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: The surface is of type quartz_image
*
* #cairo_surface_type_t is used to describe the type of a given
* surface. The surface types are also known as "backends" or "surface

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

@ -94,13 +94,6 @@ _cairo_win32_tmpfile (void);
#define M_PI 3.14159265358979323846
#endif
#ifndef NDEBUG
#undef assert
#define assert(expr) \
do { if (!(expr)) fprintf(stderr, "Assertion failed at %s:%d: %s\n", \
__FILE__, __LINE__, #expr); } while (0)
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
@ -847,7 +840,7 @@ typedef struct _cairo_traps {
#define CAIRO_FONT_WEIGHT_DEFAULT CAIRO_FONT_WEIGHT_NORMAL
#define CAIRO_WIN32_FONT_FAMILY_DEFAULT "Arial"
#define CAIRO_ATSUI_FONT_FAMILY_DEFAULT "Monaco"
#define CAIRO_ATSUI_FONT_FAMILY_DEFAULT "Helvetica"
#define CAIRO_FT_FONT_FAMILY_DEFAULT ""
#if CAIRO_HAS_WIN32_FONT
@ -1034,7 +1027,7 @@ _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
double *x2, double *y2,
cairo_bool_t *is_tight);
cairo_private void
cairo_private cairo_status_t
_cairo_gstate_path_extents (cairo_gstate_t *gstate,
cairo_path_fixed_t *path,
double *x1, double *y1,
@ -1389,7 +1382,7 @@ _cairo_path_fixed_interpret_flat (cairo_path_fixed_t *path,
void *closure,
double tolerance);
cairo_private void
cairo_private cairo_status_t
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x1, double *y1,
double *x2, double *y2,
@ -1399,6 +1392,17 @@ cairo_private void
_cairo_path_fixed_device_transform (cairo_path_fixed_t *path,
cairo_matrix_t *device_transform);
cairo_private cairo_bool_t
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path);
cairo_private cairo_bool_t
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
cairo_box_t *box);
cairo_private cairo_bool_t
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
cairo_box_t *box);
/* cairo_path_fill.c */
cairo_private cairo_status_t
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
@ -2093,12 +2097,6 @@ _cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b);
cairo_private int
_cairo_slope_compare (cairo_slope_t *a, cairo_slope_t *b);
cairo_private int
_cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b);
cairo_private int
_cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b);
/* cairo_pattern.c */
cairo_private cairo_status_t

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

@ -37,8 +37,8 @@
* test suite to test a mythical backend that uses nothing but
* fallbacks.
*
* The defining feature of this backend is that it has as many NULL
* backend function entries as possible. The ones that aren't NULL are
* The defining feature of this backend is that it has as many %NULL
* backend function entries as possible. The ones that aren't %NULL are
* simply those that must be implemented to have working fallbacks.
* (Except for create_similar---fallbacks would work fine without
* that---I implemented it here in order to create as many surfaces as

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

@ -1,21 +0,0 @@
--- /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 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 */

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

@ -1,486 +0,0 @@
? gfx/cairo/quartz-get-image-surface.patch
Index: gfx/cairo/README
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/README,v
retrieving revision 1.70
diff -u -p -8 -r1.70 README
--- gfx/cairo/README 26 Jan 2008 00:25:22 -0000 1.70
+++ gfx/cairo/README 27 Jan 2008 23:52:34 -0000
@@ -23,8 +23,10 @@ max-font-size.patch: Clamp freetype font
win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
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
+
+quartz-get-image-surface.patch: Add cairo_quartz_get_image_surface API analogous to the win32 one
Index: gfx/cairo/cairo/src/cairo-quartz-private.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-quartz-private.h,v
retrieving revision 1.19
diff -u -p -8 -r1.19 cairo-quartz-private.h
--- gfx/cairo/cairo/src/cairo-quartz-private.h 8 Dec 2007 07:09:15 -0000 1.19
+++ gfx/cairo/cairo/src/cairo-quartz-private.h 27 Jan 2008 23:52:34 -0000
@@ -43,16 +43,18 @@
#ifdef CAIRO_HAS_QUARTZ_SURFACE
#include <cairo-quartz.h>
typedef struct cairo_quartz_surface {
cairo_surface_t base;
void *imageData;
+ cairo_surface_t *imageSurfaceEquiv;
+
CGContextRef cgContext;
CGAffineTransform cgContextBaseCTM;
cairo_rectangle_int_t extents;
/* These are stored while drawing operations are in place, set up
* by quartz_setup_source() and quartz_finish_source()
*/
Index: gfx/cairo/cairo/src/cairo-quartz-surface.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c,v
retrieving revision 1.37
diff -u -p -8 -r1.37 cairo-quartz-surface.c
--- gfx/cairo/cairo/src/cairo-quartz-surface.c 26 Jan 2008 00:25:15 -0000 1.37
+++ gfx/cairo/cairo/src/cairo-quartz-surface.c 27 Jan 2008 23:52:35 -0000
@@ -890,24 +890,30 @@ _cairo_quartz_get_image (cairo_quartz_su
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);
return CAIRO_STATUS_SUCCESS;
}
+ if (surface->imageSurfaceEquiv) {
+ *image_out = (cairo_image_surface_t*) cairo_surface_reference(surface->imageSurfaceEquiv);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
if (CGBitmapContextGetBitsPerPixel(surface->cgContext) != 0) {
unsigned int stride;
unsigned int bitinfo;
unsigned int bpc, bpp;
CGColorSpaceRef colorspace;
unsigned int color_comps;
imageData = (unsigned char *) CGBitmapContextGetData(surface->cgContext);
+
#ifdef USE_10_3_WORKAROUNDS
bitinfo = CGBitmapContextGetAlphaInfo (surface->cgContext);
#else
bitinfo = CGBitmapContextGetBitmapInfo (surface->cgContext);
#endif
stride = CGBitmapContextGetBytesPerRow (surface->cgContext);
bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext);
bpc = CGBitmapContextGetBitsPerComponent (surface->cgContext);
@@ -982,16 +988,21 @@ _cairo_quartz_surface_finish (void *abst
/* Restore our saved gstate that we use to reset clipping */
CGContextRestoreGState (surface->cgContext);
CGContextRelease (surface->cgContext);
surface->cgContext = NULL;
+ if (surface->imageSurfaceEquiv) {
+ cairo_surface_destroy (surface->imageSurfaceEquiv);
+ surface->imageSurfaceEquiv = NULL;
+ }
+
if (surface->imageData) {
free (surface->imageData);
surface->imageData = NULL;
}
return CAIRO_STATUS_SUCCESS;
}
@@ -1856,16 +1867,17 @@ _cairo_quartz_surface_create_internal (C
* required for proper behaviour of intersect_clip_path(NULL)
*/
CGContextSaveGState (cgContext);
surface->cgContext = cgContext;
surface->cgContextBaseCTM = CGContextGetCTM (cgContext);
surface->imageData = NULL;
+ surface->imageSurfaceEquiv = NULL;
return surface;
}
/**
* cairo_quartz_surface_create_for_cg_context
* @cgContext: the existing CGContext for which to create the surface
* @width: width of the surface, in pixels
@@ -2010,16 +2022,17 @@ cairo_quartz_surface_create (cairo_forma
if (surf->base.status) {
CGContextRelease (cgc);
free (imageData);
// create_internal will have set an error
return (cairo_surface_t*) surf;
}
surf->imageData = imageData;
+ surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride);
return (cairo_surface_t *) surf;
}
/**
* cairo_quartz_surface_get_cg_context
* @surface: the Cairo Quartz surface
*
@@ -2137,8 +2150,19 @@ quartz_surface_to_png (cairo_quartz_surf
}
ExportCGImageToPNGFile(imgref, dest);
CGImageRelease(imgref);
#endif
}
+cairo_surface_t *
+cairo_quartz_surface_get_image (cairo_surface_t *surface)
+{
+ cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t*)surface;
+
+ if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_QUARTZ)
+ return NULL;
+
+ return quartz->imageSurfaceEquiv;
+}
+
Index: gfx/cairo/cairo/src/cairo-quartz.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-quartz.h,v
retrieving revision 1.11
diff -u -p -8 -r1.11 cairo-quartz.h
--- gfx/cairo/cairo/src/cairo-quartz.h 4 Apr 2007 01:09:15 -0000 1.11
+++ gfx/cairo/cairo/src/cairo-quartz.h 27 Jan 2008 23:52:35 -0000
@@ -52,15 +52,18 @@ cairo_quartz_surface_create (cairo_forma
cairo_public cairo_surface_t *
cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
unsigned int width,
unsigned int height);
cairo_public CGContextRef
cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
+cairo_public cairo_surface_t *
+cairo_quartz_surface_get_image (cairo_surface_t *surface);
+
CAIRO_END_DECLS
#else /* CAIRO_HAS_QUARTZ_SURFACE */
# error Cairo was not compiled with support for the quartz backend
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
#endif /* CAIRO_QUARTZ_H */
Index: gfx/cairo/cairo/src/cairo-rename.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-rename.h,v
retrieving revision 1.21
diff -u -p -8 -r1.21 cairo-rename.h
--- gfx/cairo/cairo/src/cairo-rename.h 26 Jan 2008 00:25:15 -0000 1.21
+++ gfx/cairo/cairo/src/cairo-rename.h 27 Jan 2008 23:52:35 -0000
@@ -164,16 +164,17 @@
#define cairo_ps_surface_restrict_to_level _moz_cairo_ps_surface_restrict_to_level
#define cairo_ps_surface_set_eps _moz_cairo_ps_surface_set_eps
#define cairo_ps_surface_set_size _moz_cairo_ps_surface_set_size
#define cairo_push_group _moz_cairo_push_group
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
#define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
#define cairo_quartz_surface_create_for_cg_context _moz_cairo_quartz_surface_create_for_cg_context
#define cairo_quartz_surface_get_cg_context _moz_cairo_quartz_surface_get_cg_context
+#define cairo_quartz_surface_get_image _moz_cairo_quartz_surface_get_image
#define cairo_rectangle _moz_cairo_rectangle
#define cairo_rectangle_list_destroy _moz_cairo_rectangle_list_destroy
#define cairo_reference _moz_cairo_reference
#define cairo_rel_curve_to _moz_cairo_rel_curve_to
#define cairo_rel_line_to _moz_cairo_rel_line_to
#define cairo_rel_move_to _moz_cairo_rel_move_to
#define cairo_reset_clip _moz_cairo_reset_clip
#define cairo_restore _moz_cairo_restore
Index: gfx/src/thebes/nsThebesImage.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/thebes/nsThebesImage.cpp,v
retrieving revision 1.57
diff -u -p -8 -r1.57 nsThebesImage.cpp
--- gfx/src/thebes/nsThebesImage.cpp 10 Jan 2008 22:13:13 -0000 1.57
+++ gfx/src/thebes/nsThebesImage.cpp 27 Jan 2008 23:52:35 -0000
@@ -106,33 +106,42 @@ nsThebesImage::Init(PRInt32 aWidth, PRIn
default:
format = gfxImageSurface::ImageFormatRGB24;
mAlphaDepth = 0;
break;
}
mFormat = format;
-#ifdef XP_WIN
+#if defined(XP_WIN)
if (!ShouldUseImageSurfaces()) {
mWinSurface = new gfxWindowsSurface(gfxIntSize(mWidth, mHeight), format);
if (mWinSurface && mWinSurface->CairoStatus() == 0) {
// no error
mImageSurface = mWinSurface->GetImageSurface();
}
}
- if (!mImageSurface) {
+ if (!mImageSurface)
mWinSurface = nsnull;
- mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
+#elif defined(XP_MACOSX)
+ if (!ShouldUseImageSurfaces()) {
+ mQuartzSurface = new gfxQuartzSurface(gfxSize(mWidth, mHeight), format);
+ if (mQuartzSurface && mQuartzSurface->CairoStatus() == 0) {
+ mImageSurface = mQuartzSurface->GetImageSurface();
+ }
}
-#else
- mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
+
+ if (!mImageSurface)
+ mQuartzSurface = nsnull;
#endif
+ if (!mImageSurface)
+ mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
+
if (!mImageSurface || mImageSurface->CairoStatus()) {
mImageSurface = nsnull;
// guess
return NS_ERROR_OUT_OF_MEMORY;
}
mStride = mImageSurface->Stride();
@@ -293,24 +302,32 @@ nsThebesImage::Optimize(nsIDeviceContext
}
if (!mOptSurface && !mFormatChanged) {
// just use the DIB if the format has not changed
mOptSurface = mWinSurface;
}
}
#endif
+#ifdef XP_MACOSX
+ if (mQuartzSurface && !mFormatChanged)
+ mOptSurface = mQuartzSurface;
+#endif
+
if (mOptSurface == nsnull)
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
if (mOptSurface) {
mImageSurface = nsnull;
#ifdef XP_WIN
mWinSurface = nsnull;
#endif
+#ifdef XP_MACOSX
+ mQuartzSurface = nsnull;
+#endif
}
return NS_OK;
}
nsColorMap *
nsThebesImage::GetColorMap()
{
Index: gfx/src/thebes/nsThebesImage.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/thebes/nsThebesImage.h,v
retrieving revision 1.17
diff -u -p -8 -r1.17 nsThebesImage.h
--- gfx/src/thebes/nsThebesImage.h 27 Nov 2007 09:35:18 -0000 1.17
+++ gfx/src/thebes/nsThebesImage.h 27 Jan 2008 23:52:35 -0000
@@ -39,18 +39,20 @@
#ifndef _NSTHEBESIMAGE_H_
#define _NSTHEBESIMAGE_H_
#include "nsIImage.h"
#include "gfxColor.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
-#ifdef XP_WIN
+#if defined(XP_WIN)
#include "gfxWindowsSurface.h"
+#elif defined(XP_MACOSX)
+#include "gfxQuartzSurface.h"
#endif
class nsThebesImage : public nsIImage
{
public:
nsThebesImage();
~nsThebesImage();
@@ -92,17 +94,23 @@ public:
*aSurface = ThebesSurface();
NS_ADDREF(*aSurface);
return NS_OK;
}
gfxASurface* ThebesSurface() {
if (mOptSurface)
return mOptSurface;
-
+#if defined(XP_WIN)
+ if (mWinSurface)
+ return mWinSurface;
+#elif defined(XP_MACOSX)
+ if (mQuartzSurface)
+ return mQuartzSurface;
+#endif
return mImageSurface;
}
void SetHasNoAlpha();
protected:
static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight) {
NS_ASSERTION(aWidth > 0, "invalid image width");
@@ -146,18 +154,20 @@ protected:
#ifdef XP_WIN
PRPackedBool mIsDDBSurface;
#endif
gfxRGBA mSinglePixelColor;
nsRefPtr<gfxImageSurface> mImageSurface;
nsRefPtr<gfxASurface> mOptSurface;
-#ifdef XP_WIN
+#if defined(XP_WIN)
nsRefPtr<gfxWindowsSurface> mWinSurface;
+#elif defined(XP_MACOSX)
+ nsRefPtr<gfxQuartzSurface> mQuartzSurface;
#endif
PRUint8 mAlphaDepth;
// this function should return true if
// we should (temporarily) not allocate any
// platform native surfaces and instead use
// image surfaces for everything.
Index: gfx/thebes/public/gfxQuartzSurface.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/thebes/public/gfxQuartzSurface.h,v
retrieving revision 1.11
diff -u -p -8 -r1.11 gfxQuartzSurface.h
--- gfx/thebes/public/gfxQuartzSurface.h 7 Jan 2008 00:50:18 -0000 1.11
+++ gfx/thebes/public/gfxQuartzSurface.h 27 Jan 2008 23:52:36 -0000
@@ -35,16 +35,17 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_QUARTZSURFACE_H
#define GFX_QUARTZSURFACE_H
#include "gfxASurface.h"
+#include "gfxImageSurface.h"
#include <Carbon/Carbon.h>
class THEBES_API gfxQuartzSurface : public gfxASurface {
public:
gfxQuartzSurface(const gfxSize& size, gfxImageFormat format, PRBool aForPrinting = PR_FALSE);
gfxQuartzSurface(CGContextRef context, const gfxSize& size, PRBool aForPrinting = PR_FALSE);
gfxQuartzSurface(cairo_surface_t *csurf, PRBool aForPrinting = PR_FALSE);
@@ -52,15 +53,17 @@ public:
virtual ~gfxQuartzSurface();
const gfxSize& GetSize() const { return mSize; }
CGContextRef GetCGContext() { return mCGContext; }
virtual PRInt32 GetDefaultContextFlags() const;
+ already_AddRefed<gfxImageSurface> GetImageSurface();
+
protected:
CGContextRef mCGContext;
gfxSize mSize;
PRPackedBool mForPrinting;
};
#endif /* GFX_QUARTZSURFACE_H */
Index: gfx/thebes/src/gfxQuartzSurface.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/thebes/src/gfxQuartzSurface.cpp,v
retrieving revision 1.12
diff -u -p -8 -r1.12 gfxQuartzSurface.cpp
--- gfx/thebes/src/gfxQuartzSurface.cpp 7 Jan 2008 00:50:18 -0000 1.12
+++ gfx/thebes/src/gfxQuartzSurface.cpp 27 Jan 2008 23:52:36 -0000
@@ -89,8 +89,28 @@ PRInt32 gfxQuartzSurface::GetDefaultCont
return 0;
}
gfxQuartzSurface::~gfxQuartzSurface()
{
CGContextRelease(mCGContext);
}
+
+already_AddRefed<gfxImageSurface>
+gfxQuartzSurface::GetImageSurface()
+{
+ if (!mSurfaceValid) {
+ NS_WARNING ("GetImageSurface on an invalid (null) surface; who's calling this without checking for surface errors?");
+ return nsnull;
+ }
+
+ NS_ASSERTION(CairoSurface() != nsnull, "CairoSurface() shouldn't be nsnull when mSurfaceValid is TRUE!");
+
+ cairo_surface_t *isurf = cairo_quartz_surface_get_image(CairoSurface());
+ if (!isurf)
+ return nsnull;
+
+ nsRefPtr<gfxASurface> asurf = gfxASurface::Wrap(isurf);
+ gfxImageSurface *imgsurf = (gfxImageSurface*) asurf.get();
+ NS_ADDREF(imgsurf);
+ return imgsurf;
+}
Index: gfx/thebes/src/gfxWindowsSurface.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/thebes/src/gfxWindowsSurface.cpp,v
retrieving revision 1.32
diff -u -p -8 -r1.32 gfxWindowsSurface.cpp
--- gfx/thebes/src/gfxWindowsSurface.cpp 7 Jan 2008 00:50:18 -0000 1.32
+++ gfx/thebes/src/gfxWindowsSurface.cpp 27 Jan 2008 23:52:36 -0000
@@ -120,16 +120,23 @@ gfxWindowsSurface::~gfxWindowsSurface()
else
::DeleteDC(mDC);
}
}
already_AddRefed<gfxImageSurface>
gfxWindowsSurface::GetImageSurface()
{
+ if (!mSurfaceValid) {
+ NS_WARNING ("GetImageSurface on an invalid (null) surface; who's calling this without checking for surface errors?");
+ return nsnull;
+ }
+
+ NS_ASSERTION(CairoSurface() != nsnull, "CairoSurface() shouldn't be nsnull when mSurfaceValid is TRUE!");
+
if (mForPrinting)
return nsnull;
cairo_surface_t *isurf = cairo_win32_surface_get_image(CairoSurface());
if (!isurf)
return nsnull;
nsRefPtr<gfxASurface> asurf = gfxASurface::Wrap(isurf);

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

@ -1,51 +0,0 @@
# HG changeset patch
# User Vladimir Vukicevic <vladimir@pobox.com>
# Date 1201565841 28800
# Node ID 114e54eaf3df3b8b8666d831ab48312735bb04b1
# Parent 86a787b2874770fa96503a7e513b362fd2c76ba4
b=367618, can't run in 8bpp mode on win32
diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
@@ -1677,9 +1677,9 @@ _cairo_win32_surface_show_glyphs (void
*
* Creates a cairo surface that targets the given DC. The DC will be
* queried for its initial clip extents, and this will be used as the
- * size of the cairo surface. Also, if the DC is a raster DC, it will
- * be queried for its pixel format and the cairo surface format will
- * be set appropriately.
+ * size of the cairo surface. The resulting surface will always
+ * be of format CAIRO_FORMAT_RGB24; should you need an ARGB32 surface,
+ * you will need to create one through cairo_win32_surface_create_with_dib.
*
* Return value: the newly created surface
**/
@@ -1692,25 +1692,8 @@ cairo_win32_surface_create (HDC hdc)
cairo_format_t format;
RECT rect;
- if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
- depth = GetDeviceCaps(hdc, BITSPIXEL);
- if (depth == 32)
- format = CAIRO_FORMAT_RGB24;
- else if (depth == 24)
- format = CAIRO_FORMAT_RGB24;
- else if (depth == 16)
- format = CAIRO_FORMAT_RGB24;
- else if (depth == 8)
- format = CAIRO_FORMAT_A8;
- else if (depth == 1)
- format = CAIRO_FORMAT_A1;
- else {
- _cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
- }
- } else {
- format = CAIRO_FORMAT_RGB24;
- }
+ /* Assume that everything coming in as a HDC is RGB24 */
+ format = CAIRO_FORMAT_RGB24;
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL)