clip: Rudimentary support for clip-polygon extraction

Step 1, fix the failings sighted recently by tracking clip-boxes as an
explicit property of the clipping and of composition.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-07-14 21:19:54 +01:00
parent f58ade7bac
commit b132fae5e8
88 changed files with 7500 additions and 3532 deletions

View file

@ -118,9 +118,14 @@ cairo_sources = \
cairo-bentley-ottmann-rectilinear.c \
cairo-botor-scan-converter.c \
cairo-boxes.c \
cairo-boxes-intersect.c \
cairo.c \
cairo-cache.c \
cairo-clip.c \
cairo-clip-boxes.c \
cairo-clip-polygon.c \
cairo-clip-region.c \
cairo-clip-surface.c \
cairo-color.c \
cairo-composite-rectangles.c \
cairo-debug.c \
@ -156,6 +161,8 @@ cairo_sources = \
cairo-pattern.c \
cairo-pen.c \
cairo-polygon.c \
cairo-polygon-intersect.c \
cairo-polygon-reduce.c \
cairo-recording-surface.c \
cairo-rectangle.c \
cairo-rectangular-scan-converter.c \

View file

@ -67,8 +67,8 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
cairo_int_status_t status_b)
{
/* fatal errors should be checked and propagated at source */
assert (! _cairo_status_is_error (status_a));
assert (! _cairo_status_is_error (status_b));
assert (! _cairo_int_status_is_error (status_a));
assert (! _cairo_int_status_is_error (status_b));
/* return the most important status */
if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
@ -88,10 +88,10 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
/* at this point we have checked all the valid internal codes, so... */
assert (status_a == CAIRO_STATUS_SUCCESS &&
status_b == CAIRO_STATUS_SUCCESS);
assert (status_a == CAIRO_INT_STATUS_SUCCESS &&
status_b == CAIRO_INT_STATUS_SUCCESS);
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_int_status_t
@ -144,10 +144,10 @@ _add_operation (cairo_analysis_surface_t *surface,
/* Even though the operation is not visible we must be careful
* to not allow unsupported operations to be replayed to the
* backend during CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_STATUS_SUCCESS ||
if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
{
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
else
{
@ -172,10 +172,10 @@ _add_operation (cairo_analysis_surface_t *surface,
* careful to not allow unsupported operations to be
* replayed to the backend during
* CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_STATUS_SUCCESS ||
if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
{
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
else
{
@ -217,10 +217,10 @@ _add_operation (cairo_analysis_surface_t *surface,
* transparency into the white background.
*/
if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
backend_status = CAIRO_STATUS_SUCCESS;
backend_status = CAIRO_INT_STATUS_SUCCESS;
}
if (backend_status == CAIRO_STATUS_SUCCESS) {
if (backend_status == CAIRO_INT_STATUS_SUCCESS) {
/* Add the operation to the supported region. Operations in
* this region will be emitted as native operations.
*/
@ -241,7 +241,7 @@ _add_operation (cairo_analysis_surface_t *surface,
* invoke the cairo-surface-fallback path then return
* CAIRO_STATUS_SUCCESS.
*/
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
else
return status;
@ -270,23 +270,17 @@ _cairo_analysis_surface_get_extents (void *abstract_surface,
}
static void
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, const cairo_clip_t *clip)
{
const cairo_rectangle_int_t *clip_extents;
clip_extents = NULL;
if (clip != NULL)
clip_extents = _cairo_clip_get_extents (clip);
if (clip_extents != NULL)
_cairo_rectangle_intersect (extents, clip_extents);
_cairo_rectangle_intersect (extents, _cairo_clip_get_extents (clip));
}
static void
_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip,
const cairo_clip_t *clip,
cairo_rectangle_int_t *extents)
{
cairo_bool_t is_empty;
@ -307,10 +301,10 @@ static cairo_int_status_t
_cairo_analysis_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t backend_status;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->paint == NULL) {
@ -319,7 +313,7 @@ _cairo_analysis_surface_paint (void *abstract_surface,
backend_status =
surface->target->backend->paint (surface->target,
op, source, clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
@ -338,7 +332,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t backend_status;
@ -350,7 +344,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
backend_status =
surface->target->backend->mask (surface->target,
op, source, mask, clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
@ -363,7 +357,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
if (_cairo_surface_is_recording (surface_pattern->surface)) {
backend_source_status =
_analyze_recording_surface_pattern (surface, source);
if (_cairo_status_is_error (backend_source_status))
if (_cairo_int_status_is_error (backend_source_status))
return backend_source_status;
}
}
@ -373,7 +367,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
if (_cairo_surface_is_recording (surface_pattern->surface)) {
backend_mask_status =
_analyze_recording_surface_pattern (surface, mask);
if (_cairo_status_is_error (backend_mask_status))
if (_cairo_int_status_is_error (backend_mask_status))
return backend_mask_status;
}
}
@ -401,16 +395,16 @@ static cairo_int_status_t
_cairo_analysis_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t backend_status;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->stroke == NULL) {
@ -422,7 +416,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
ctm, ctm_inverse,
tolerance, antialias,
clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
@ -435,7 +429,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t mask_extents;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_path_fixed_stroke_extents (path, style,
ctm, ctm_inverse,
@ -454,14 +448,14 @@ static cairo_int_status_t
_cairo_analysis_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t backend_status;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->fill == NULL) {
@ -472,7 +466,7 @@ _cairo_analysis_surface_fill (void *abstract_surface,
source, path, fill_rule,
tolerance, antialias,
clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
@ -502,11 +496,11 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_int_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
/* Adapted from _cairo_surface_show_glyphs */
@ -518,7 +512,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
scaled_font,
clip,
remaining_glyphs);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
else if (surface->target->backend->show_text_glyphs != NULL)
@ -532,7 +526,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
FALSE,
scaled_font,
clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
else
@ -582,10 +576,10 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
cairo_int_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
/* Adapted from _cairo_surface_show_glyphs */
@ -600,7 +594,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
cluster_flags,
scaled_font,
clip);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
@ -614,7 +608,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
scaled_font,
clip,
&remaining_glyphs);
if (_cairo_status_is_error (backend_status))
if (_cairo_int_status_is_error (backend_status))
return backend_status;
glyphs += num_glyphs - remaining_glyphs;
@ -803,36 +797,36 @@ typedef cairo_int_status_t
(*_paint_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_mask_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_stroke_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_fill_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_show_glyphs_func) (void *surface,
@ -841,7 +835,7 @@ typedef cairo_int_status_t
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs);
static const cairo_surface_backend_t cairo_null_surface_backend = {

View file

@ -320,7 +320,7 @@ edge_end_box (sweep_line_t *sweep_line,
box.p2.x = left->right->x;
box.p2.y = bot;
status = _cairo_boxes_add (container, &box);
status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box);
}
}
if (unlikely (status))
@ -746,7 +746,7 @@ _cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in,
box.p2.x = tmp;
}
status = _cairo_boxes_add (out, &box);
status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
assert (status == CAIRO_STATUS_SUCCESS);
return CAIRO_STATUS_SUCCESS;
}

View file

@ -237,7 +237,7 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t *left,
box.p1.y = trap->top;
box.p2.x = trap->right->edge.line.p1.x;
box.p2.y = bot;
status = _cairo_boxes_add (container, &box);
status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box);
}
}

666
src/cairo-boxes-intersect.c Normal file
View file

@ -0,0 +1,666 @@
/*
* Copyright © 2004 Carl Worth
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Carl Worth
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
/* Provide definitions for standalone compilation */
#include "cairoint.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
#include "cairo-combsort-private.h"
#include "cairo-list-private.h"
#include <setjmp.h>
typedef struct _rectangle rectangle_t;
typedef struct _edge edge_t;
struct _edge {
edge_t *next, *prev;
edge_t *right;
cairo_fixed_t x, top;
int a_or_b;
int dir;
};
struct _rectangle {
edge_t left, right;
int32_t top, bottom;
};
#define UNROLL3(x) x x x
/* the parent is always given by index/2 */
#define PQ_PARENT_INDEX(i) ((i) >> 1)
#define PQ_FIRST_ENTRY 1
/* left and right children are index * 2 and (index * 2) +1 respectively */
#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
typedef struct _pqueue {
int size, max_size;
rectangle_t **elements;
rectangle_t *elements_embedded[1024];
} pqueue_t;
typedef struct _sweep_line {
rectangle_t **rectangles;
pqueue_t pq;
edge_t head, tail;
edge_t *insert_left, *insert_right;
int32_t current_y;
int32_t last_y;
jmp_buf unwind;
} sweep_line_t;
#define DEBUG_TRAPS 0
#if DEBUG_TRAPS
static void
dump_traps (cairo_traps_t *traps, const char *filename)
{
FILE *file;
int n;
if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
return;
file = fopen (filename, "a");
if (file != NULL) {
for (n = 0; n < traps->num_traps; n++) {
fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n",
traps->traps[n].top,
traps->traps[n].bottom,
traps->traps[n].left.p1.x,
traps->traps[n].left.p1.y,
traps->traps[n].left.p2.x,
traps->traps[n].left.p2.y,
traps->traps[n].right.p1.x,
traps->traps[n].right.p1.y,
traps->traps[n].right.p2.x,
traps->traps[n].right.p2.y);
}
fprintf (file, "\n");
fclose (file);
}
}
#else
#define dump_traps(traps, filename)
#endif
static inline int
rectangle_compare_start (const rectangle_t *a,
const rectangle_t *b)
{
return a->top - b->top;
}
static inline int
rectangle_compare_stop (const rectangle_t *a,
const rectangle_t *b)
{
return a->bottom - b->bottom;
}
static inline void
pqueue_init (pqueue_t *pq)
{
pq->max_size = ARRAY_LENGTH (pq->elements_embedded);
pq->size = 0;
pq->elements = pq->elements_embedded;
pq->elements[PQ_FIRST_ENTRY] = NULL;
}
static inline void
pqueue_fini (pqueue_t *pq)
{
if (pq->elements != pq->elements_embedded)
free (pq->elements);
}
static cairo_bool_t
pqueue_grow (pqueue_t *pq)
{
rectangle_t **new_elements;
pq->max_size *= 2;
if (pq->elements == pq->elements_embedded) {
new_elements = _cairo_malloc_ab (pq->max_size,
sizeof (rectangle_t *));
if (unlikely (new_elements == NULL))
return FALSE;
memcpy (new_elements, pq->elements_embedded,
sizeof (pq->elements_embedded));
} else {
new_elements = _cairo_realloc_ab (pq->elements,
pq->max_size,
sizeof (rectangle_t *));
if (unlikely (new_elements == NULL))
return FALSE;
}
pq->elements = new_elements;
return TRUE;
}
static inline void
pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
{
rectangle_t **elements;
int i, parent;
if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)) {
if (unlikely (! pqueue_grow (&sweep->pq))) {
longjmp (sweep->unwind,
_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
}
elements = sweep->pq.elements;
for (i = ++sweep->pq.size;
i != PQ_FIRST_ENTRY &&
rectangle_compare_stop (rectangle,
elements[parent = PQ_PARENT_INDEX (i)]) < 0;
i = parent)
{
elements[i] = elements[parent];
}
elements[i] = rectangle;
}
static inline void
pqueue_pop (pqueue_t *pq)
{
rectangle_t **elements = pq->elements;
rectangle_t *tail;
int child, i;
tail = elements[pq->size--];
if (pq->size == 0) {
elements[PQ_FIRST_ENTRY] = NULL;
return;
}
for (i = PQ_FIRST_ENTRY;
(child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size;
i = child)
{
if (child != pq->size &&
rectangle_compare_stop (elements[child+1],
elements[child]) < 0)
{
child++;
}
if (rectangle_compare_stop (elements[child], tail) >= 0)
break;
elements[i] = elements[child];
}
elements[i] = tail;
}
static inline rectangle_t *
rectangle_pop_start (sweep_line_t *sweep_line)
{
return *sweep_line->rectangles++;
}
static inline rectangle_t *
rectangle_peek_stop (sweep_line_t *sweep_line)
{
return sweep_line->pq.elements[PQ_FIRST_ENTRY];
}
CAIRO_COMBSORT_DECLARE (_rectangle_sort,
rectangle_t *,
rectangle_compare_start)
static void
sweep_line_init (sweep_line_t *sweep_line,
rectangle_t **rectangles,
int num_rectangles)
{
_rectangle_sort (rectangles, num_rectangles);
rectangles[num_rectangles] = NULL;
sweep_line->rectangles = rectangles;
sweep_line->head.x = INT32_MIN;
sweep_line->head.right = NULL;
sweep_line->head.dir = 0;
sweep_line->head.next = &sweep_line->tail;
sweep_line->tail.x = INT32_MAX;
sweep_line->tail.right = NULL;
sweep_line->tail.dir = 0;
sweep_line->tail.prev = &sweep_line->head;
sweep_line->insert_left = &sweep_line->tail;
sweep_line->insert_right = &sweep_line->tail;
sweep_line->current_y = INT32_MIN;
sweep_line->last_y = INT32_MIN;
pqueue_init (&sweep_line->pq);
}
static void
sweep_line_fini (sweep_line_t *sweep_line)
{
pqueue_fini (&sweep_line->pq);
}
static void
end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot, cairo_boxes_t *out)
{
if (likely (left->top < bot)) {
cairo_status_t status;
cairo_box_t box;
box.p1.x = left->x;
box.p1.y = left->top;
box.p2.x = left->right->x;
box.p2.y = bot;
status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
if (unlikely (status))
longjmp (sweep_line->unwind, status);
}
left->right = NULL;
}
/* Start a new trapezoid at the given top y coordinate, whose edges
* are `edge' and `edge->next'. If `edge' already has a trapezoid,
* then either add it to the traps in `traps', if the trapezoid's
* right edge differs from `edge->next', or do nothing if the new
* trapezoid would be a continuation of the existing one. */
static inline void
start_or_continue_box (sweep_line_t *sweep_line,
edge_t *left,
edge_t *right,
int top,
cairo_boxes_t *out)
{
if (left->right == right)
return;
if (left->right != NULL) {
if (right != NULL && left->right->x == right->x) {
/* continuation on right, so just swap edges */
left->right = right;
return;
}
end_box (sweep_line, left, top, out);
}
if (right != NULL && left->x != right->x) {
left->top = top;
left->right = right;
}
}
static inline int is_zero(const int *winding)
{
return winding[0] == 0 || winding[1] == 0;
}
static inline void
active_edges (sweep_line_t *sweep, cairo_boxes_t *out)
{
int top = sweep->current_y;
int winding[2] = { 0 };
edge_t *pos;
if (sweep->last_y == sweep->current_y)
return;
pos = sweep->head.next;
if (pos == &sweep->tail)
return;
do {
edge_t *left, *right;
left = pos;
do {
winding[left->a_or_b] += left->dir;
if (!is_zero (winding))
break;
if (left->next == &sweep->tail)
goto out;
if (unlikely (left->right != NULL))
end_box (sweep, left, top, out);
left = left->next;
} while (1);
right = left->next;
do {
if (unlikely (right->right != NULL))
end_box (sweep, right, top, out);
winding[right->a_or_b] += right->dir;
if (is_zero (winding)) {
/* skip co-linear edges */
if (likely (right->x != right->next->x))
break;
}
right = right->next;
} while (TRUE);
start_or_continue_box (sweep, left, right, top, out);
pos = right->next;
} while (pos != &sweep->tail);
out:
sweep->last_y = sweep->current_y;
}
static inline void
sweep_line_delete_edge (sweep_line_t *sweep_line, edge_t *edge, cairo_boxes_t *out)
{
if (edge->right != NULL) {
edge_t *next = edge->next;
if (next->x == edge->x) {
next->top = edge->top;
next->right = edge->right;
} else {
end_box (sweep_line, edge, sweep_line->current_y, out);
}
}
if (sweep_line->insert_left == edge)
sweep_line->insert_left = edge->next;
if (sweep_line->insert_right == edge)
sweep_line->insert_right = edge->next;
edge->prev->next = edge->next;
edge->next->prev = edge->prev;
}
static inline void
sweep_line_delete (sweep_line_t *sweep,
rectangle_t *rectangle,
cairo_boxes_t *out)
{
sweep_line_delete_edge (sweep, &rectangle->left, out);
sweep_line_delete_edge (sweep, &rectangle->right, out);
pqueue_pop (&sweep->pq);
}
static inline void
insert_edge (edge_t *edge, edge_t *pos)
{
if (pos->x != edge->x) {
if (pos->x > edge->x) {
do {
UNROLL3({
if (pos->prev->x <= edge->x)
break;
pos = pos->prev;
})
} while (TRUE);
} else {
do {
UNROLL3({
pos = pos->next;
if (pos->x >= edge->x)
break;
})
} while (TRUE);
}
}
pos->prev->next = edge;
edge->prev = pos->prev;
edge->next = pos;
pos->prev = edge;
}
static inline void
sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle)
{
edge_t *pos;
/* right edge */
pos = sweep->insert_right;
insert_edge (&rectangle->right, pos);
sweep->insert_right = &rectangle->right;
/* left edge */
pos = sweep->insert_left;
if (pos->x > sweep->insert_right->x)
pos = sweep->insert_right->prev;
insert_edge (&rectangle->left, pos);
sweep->insert_left = &rectangle->left;
pqueue_push (sweep, rectangle);
}
static cairo_status_t
intersect (rectangle_t **rectangles, int num_rectangles, cairo_boxes_t *out)
{
sweep_line_t sweep_line;
rectangle_t *rectangle;
cairo_status_t status;
sweep_line_init (&sweep_line, rectangles, num_rectangles);
if ((status = setjmp (sweep_line.unwind)))
goto unwind;
rectangle = rectangle_pop_start (&sweep_line);
do {
if (rectangle->top != sweep_line.current_y) {
rectangle_t *stop;
stop = rectangle_peek_stop (&sweep_line);
while (stop != NULL && stop->bottom < rectangle->top) {
if (stop->bottom != sweep_line.current_y) {
active_edges (&sweep_line, out);
sweep_line.current_y = stop->bottom;
}
sweep_line_delete (&sweep_line, stop, out);
stop = rectangle_peek_stop (&sweep_line);
}
active_edges (&sweep_line, out);
sweep_line.current_y = rectangle->top;
}
sweep_line_insert (&sweep_line, rectangle);
} while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL);
while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) {
if (rectangle->bottom != sweep_line.current_y) {
active_edges (&sweep_line, out);
sweep_line.current_y = rectangle->bottom;
}
sweep_line_delete (&sweep_line, rectangle, out);
}
unwind:
sweep_line_fini (&sweep_line);
return status;
}
static cairo_status_t
_cairo_boxes_intersect_with_box (const cairo_boxes_t *boxes,
const cairo_box_t *box,
cairo_boxes_t *out)
{
const struct _cairo_boxes_chunk *chunk;
cairo_status_t status;
int i;
_cairo_boxes_clear (out);
_cairo_boxes_limit (out, box, 1);
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
status = _cairo_boxes_add (out,
CAIRO_ANTIALIAS_DEFAULT,
&chunk->base[i]);
if (unlikely (status))
return status;
}
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_boxes_intersect (const cairo_boxes_t *a,
const cairo_boxes_t *b,
cairo_boxes_t *out)
{
rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
rectangle_t *rectangles;
rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
rectangle_t **rectangles_ptrs;
const struct _cairo_boxes_chunk *chunk;
cairo_status_t status;
int i, j, count;
if (unlikely (a->num_boxes == 0 || b->num_boxes == 0)) {
_cairo_boxes_clear (out);
return CAIRO_STATUS_SUCCESS;
}
if (unlikely (a->num_boxes == 1)) {
cairo_box_t box = a->chunks.base[0];
return _cairo_boxes_intersect_with_box (b, &box, out);
}
if (unlikely (b->num_boxes == 1)) {
cairo_box_t box = b->chunks.base[0];
return _cairo_boxes_intersect_with_box (a, &box, out);
/* XXX */
}
rectangles = stack_rectangles;
rectangles_ptrs = stack_rectangles_ptrs;
count = a->num_boxes + b->num_boxes;
if (count > ARRAY_LENGTH (stack_rectangles)) {
rectangles = _cairo_malloc_ab_plus_c (count,
sizeof (rectangle_t) +
sizeof (rectangle_t *),
sizeof (rectangle_t *));
if (unlikely (rectangles == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
rectangles_ptrs = (rectangle_t **) (rectangles + count);
}
j = 0;
for (chunk = &a->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
if (box[i].p1.x < box[i].p2.x) {
rectangles[j].left.x = box[i].p1.x;
rectangles[j].left.dir = 1;
rectangles[j].right.x = box[i].p2.x;
rectangles[j].right.dir = -1;
} else {
rectangles[j].right.x = box[i].p1.x;
rectangles[j].right.dir = 1;
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
rectangles[j].left.a_or_b = 0;
rectangles[j].left.right = NULL;
rectangles[j].right.a_or_b = 0;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
rectangles_ptrs[j] = &rectangles[j];
j++;
}
}
for (chunk = &b->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
if (box[i].p1.x < box[i].p2.x) {
rectangles[j].left.x = box[i].p1.x;
rectangles[j].left.dir = 1;
rectangles[j].right.x = box[i].p2.x;
rectangles[j].right.dir = -1;
} else {
rectangles[j].right.x = box[i].p1.x;
rectangles[j].right.dir = 1;
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
rectangles[j].left.a_or_b = 1;
rectangles[j].left.right = NULL;
rectangles[j].right.a_or_b = 1;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
rectangles_ptrs[j] = &rectangles[j];
j++;
}
}
assert (j == count);
_cairo_boxes_clear (out);
status = intersect (rectangles_ptrs, j, out);
if (rectangles != stack_rectangles)
free (rectangles);
return status;
}

View file

@ -57,6 +57,10 @@ struct _cairo_boxes_t {
cairo_private void
_cairo_boxes_init (cairo_boxes_t *boxes);
cairo_private void
_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
cairo_clip_t *clip);
cairo_private void
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
cairo_box_t *array,
@ -69,16 +73,39 @@ _cairo_boxes_limit (cairo_boxes_t *boxes,
cairo_private cairo_status_t
_cairo_boxes_add (cairo_boxes_t *boxes,
cairo_antialias_t antialias,
const cairo_box_t *box);
cairo_private void
_cairo_boxes_extents (const cairo_boxes_t *boxes,
cairo_rectangle_int_t *extents);
cairo_private cairo_box_t *
_cairo_boxes_to_array (const cairo_boxes_t *boxes,
int *num_boxes,
cairo_bool_t force_allocation);
static inline void
_cairo_boxes_free_array (const cairo_boxes_t *boxes,
cairo_box_t *box)
{
if (box != boxes->chunks.base)
free(box);
}
cairo_private cairo_status_t
_cairo_boxes_intersect (const cairo_boxes_t *a,
const cairo_boxes_t *b,
cairo_boxes_t *out);
cairo_private void
_cairo_boxes_clear (cairo_boxes_t *boxes);
cairo_private void
_cairo_boxes_fini (cairo_boxes_t *boxes);
cairo_private void
_cairo_debug_print_boxes (FILE *stream,
const cairo_boxes_t *boxes);
#endif /* CAIRO_BOXES_H */

View file

@ -52,6 +52,15 @@ _cairo_boxes_init (cairo_boxes_t *boxes)
boxes->is_pixel_aligned = TRUE;
}
void
_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
cairo_clip_t *clip)
{
_cairo_boxes_init (boxes);
if (clip)
_cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes);
}
void
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
cairo_box_t *array,
@ -156,8 +165,19 @@ _cairo_boxes_add_internal (cairo_boxes_t *boxes,
cairo_status_t
_cairo_boxes_add (cairo_boxes_t *boxes,
cairo_antialias_t antialias,
const cairo_box_t *box)
{
cairo_box_t b;
if (antialias == CAIRO_ANTIALIAS_NONE) {
b.p1.x = _cairo_fixed_round_down (box->p1.x);
b.p1.y = _cairo_fixed_round_down (box->p1.y);
b.p2.x = _cairo_fixed_round_down (box->p2.x);
b.p2.y = _cairo_fixed_round_down (box->p2.y);
box = &b;
}
if (box->p1.y == box->p2.y)
return CAIRO_STATUS_SUCCESS;
@ -247,6 +267,11 @@ _cairo_boxes_extents (const cairo_boxes_t *boxes,
cairo_box_t box;
int i;
if (boxes->num_boxes == 0) {
extents->x = extents->y = extents->width = extents->height = 0;
return;
}
box.p1.y = box.p1.x = INT_MAX;
box.p2.y = box.p2.x = INT_MIN;
@ -283,11 +308,41 @@ _cairo_boxes_clear (cairo_boxes_t *boxes)
boxes->tail = &boxes->chunks;
boxes->chunks.next = 0;
boxes->chunks.count = 0;
boxes->chunks.base = boxes->boxes_embedded;
boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
boxes->num_boxes = 0;
boxes->is_pixel_aligned = TRUE;
}
cairo_box_t *
_cairo_boxes_to_array (const cairo_boxes_t *boxes,
int *num_boxes,
cairo_bool_t force_allocation)
{
const struct _cairo_boxes_chunk *chunk;
cairo_box_t *box;
int i, j;
*num_boxes = boxes->num_boxes;
if (boxes->chunks.next == NULL && ! force_allocation)
return boxes->chunks.base;
box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t));
if (box == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
j = 0;
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++)
box[j++] = chunk->base[i];
}
return box;
}
void
_cairo_boxes_fini (cairo_boxes_t *boxes)
{
@ -298,3 +353,26 @@ _cairo_boxes_fini (cairo_boxes_t *boxes)
free (chunk);
}
}
void
_cairo_debug_print_boxes (FILE *stream, const cairo_boxes_t *boxes)
{
cairo_rectangle_int_t extents;
const struct _cairo_boxes_chunk *chunk;
int i;
_cairo_boxes_extents (boxes, &extents);
fprintf (stream, "boxes x %d: (%d, %d) x (%d, %d)\n",
boxes->num_boxes,
extents.x, extents.y, extents.width, extents.height);
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
fprintf (stderr, " box[%d]: (%f, %f), (%f, %f)\n", i,
_cairo_fixed_to_double (chunk->base[i].p1.x),
_cairo_fixed_to_double (chunk->base[i].p1.y),
_cairo_fixed_to_double (chunk->base[i].p2.x),
_cairo_fixed_to_double (chunk->base[i].p2.y));
}
}
}

View file

@ -1373,12 +1373,12 @@ cairo_cff_find_subroutines_used (cairo_cff_font_t *font,
return cairo_cff_parse_charstring (font, charstring, length, glyph_id);
}
static cairo_status_t
static cairo_int_status_t
cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t *font)
{
cff_index_element_t *element;
unsigned int i;
cairo_status_t status;
cairo_int_status_t status;
unsigned long glyph;
font->subset_subroutines = TRUE;
@ -1758,23 +1758,23 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t *font)
byte = 3;
status = _cairo_array_append (&font->output, &byte);
assert (status == CAIRO_STATUS_SUCCESS);
assert (status == CAIRO_INT_STATUS_SUCCESS);
word = cpu_to_be16 (1);
status = _cairo_array_append_multiple (&font->output, &word, 2);
assert (status == CAIRO_STATUS_SUCCESS);
assert (status == CAIRO_INT_STATUS_SUCCESS);
word = cpu_to_be16 (0);
status = _cairo_array_append_multiple (&font->output, &word, 2);
assert (status == CAIRO_STATUS_SUCCESS);
assert (status == CAIRO_INT_STATUS_SUCCESS);
byte = 0;
status = _cairo_array_append (&font->output, &byte);
assert (status == CAIRO_STATUS_SUCCESS);
assert (status == CAIRO_INT_STATUS_SUCCESS);
word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
status = _cairo_array_append_multiple (&font->output, &word, 2);
assert (status == CAIRO_STATUS_SUCCESS);
assert (status == CAIRO_INT_STATUS_SUCCESS);
}
return CAIRO_STATUS_SUCCESS;

559
src/cairo-clip-boxes.c Normal file
View file

@ -0,0 +1,559 @@
/* -*- 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
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static inline int
pot (int v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
static cairo_bool_t
_cairo_clip_contains_rectangle_box (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect,
const cairo_box_t *box)
{
int i;
/* clip == NULL means no clip, so the clip contains everything */
if (clip == NULL)
return TRUE;
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
/* If we have a non-trivial path, just say no */
if (clip->path)
return FALSE;
if (clip->extents.x > rect->x ||
clip->extents.y > rect->y ||
clip->extents.x + clip->extents.width < rect->x + rect->width ||
clip->extents.y + clip->extents.height < rect->y + rect->height)
{
return FALSE;
}
/* Check for a clip-box that wholly contains the rectangle */
assert (clip->num_boxes);
for (i = 0; i < clip->num_boxes; i++) {
if (box->p1.x >= clip->boxes[i].p1.x &&
box->p1.y >= clip->boxes[i].p1.y &&
box->p2.x <= clip->boxes[i].p2.x &&
box->p2.y <= clip->boxes[i].p2.y)
{
return TRUE;
}
}
return FALSE;
}
cairo_bool_t
_cairo_clip_contains_box (const cairo_clip_t *clip,
const cairo_box_t *box)
{
cairo_rectangle_int_t rect;
_cairo_box_round_to_rectangle (box, &rect);
return _cairo_clip_contains_rectangle_box(clip, &rect, box);
}
cairo_bool_t
_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect)
{
cairo_box_t box;
box.p1.x = _cairo_fixed_from_int (rect->x);
box.p1.y = _cairo_fixed_from_int (rect->y);
box.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
box.p2.y = _cairo_fixed_from_int (rect->y + rect->height);
return _cairo_clip_contains_rectangle_box (clip, rect, &box);
}
cairo_clip_t *
_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias)
{
cairo_status_t status;
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
fill_rule,
antialias,
&boxes);
if (likely (status == CAIRO_STATUS_SUCCESS))
clip = _cairo_clip_intersect_boxes (clip, &boxes);
else
clip = _cairo_clip_set_all_clipped (clip);
_cairo_boxes_fini (&boxes);
return clip;
}
static cairo_clip_t *
_cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
const cairo_rectangle_int_t *r,
const cairo_box_t *box)
{
cairo_box_t extents_box;
int i, j;
if (clip == NULL) {
clip = _cairo_clip_create ();
if (clip == NULL)
return _cairo_clip_set_all_clipped (clip);
clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
clip->extents = *r;
clip->num_boxes = 1;
clip->boxes[0] = *box;
return clip;
}
if (clip->num_boxes == 0) {
clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
j = 1;
clip->boxes[0] = *box;
} else for (i = j = 0; i < clip->num_boxes; i++) {
cairo_box_t *b = &clip->boxes[j];
if (j != i)
*b = clip->boxes[i];
if (box->p1.x > b->p1.x)
b->p1.x = box->p1.x;
if (box->p2.x < b->p2.x)
b->p2.x = box->p2.x;
if (box->p1.y > b->p1.y)
b->p1.y = box->p1.y;
if (box->p2.y < b->p2.y)
b->p2.y = box->p2.y;
j += b->p2.x > b->p1.x && b->p2.y > b->p1.y;
}
clip->num_boxes = j;
if (clip->num_boxes == 0)
return _cairo_clip_set_all_clipped (clip);
extents_box = clip->boxes[0];
for (i = 1; i < clip->num_boxes; i++) {
if (clip->boxes[i].p1.x < extents_box.p1.x)
extents_box.p1.x = clip->boxes[i].p1.x;
if (clip->boxes[i].p1.y < extents_box.p1.y)
extents_box.p1.y = clip->boxes[i].p1.y;
if (clip->boxes[i].p2.x > extents_box.p2.x)
extents_box.p2.x = clip->boxes[i].p2.x;
if (clip->boxes[i].p2.y > extents_box.p2.y)
extents_box.p2.y = clip->boxes[i].p2.y;
}
if (clip->path == NULL) {
_cairo_box_round_to_rectangle (&extents_box, &clip->extents);
} else {
cairo_rectangle_int_t extents_rect;
_cairo_box_round_to_rectangle (&extents_box, &extents_rect);
if (! _cairo_rectangle_intersect (&clip->extents, &extents_rect))
return _cairo_clip_set_all_clipped (clip);
}
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
return clip;
}
cairo_clip_t *
_cairo_clip_intersect_box (cairo_clip_t *clip,
const cairo_box_t *box)
{
cairo_rectangle_int_t r;
_cairo_box_round_to_rectangle (box, &r);
if (r.width == 0 || r.height == 0)
return _cairo_clip_set_all_clipped (clip);
return _cairo_clip_intersect_rectangle_box (clip, &r, box);
}
cairo_clip_t *
_cairo_clip_intersect_boxes (cairo_clip_t *clip,
const cairo_boxes_t *boxes)
{
cairo_boxes_t clip_boxes;
cairo_rectangle_int_t extents;
if (boxes->num_boxes == 0)
return clip;
if (clip == NULL)
clip = _cairo_clip_create ();
if (clip->num_boxes == 0) {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
_cairo_boxes_extents (boxes, &extents);
} else {
_cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes);
if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes)))
return _cairo_clip_set_all_clipped (clip);
free (clip->boxes);
clip->boxes = _cairo_boxes_to_array (&clip_boxes, &clip->num_boxes, TRUE);
_cairo_boxes_extents (&clip_boxes, &extents);
}
if (clip->path == NULL)
clip->extents = extents;
else if (! _cairo_rectangle_intersect (&clip->extents, &extents))
clip = _cairo_clip_set_all_clipped (clip);
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
return clip;
}
cairo_clip_t *
_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
cairo_box_t box;
if (_cairo_clip_is_all_clipped (clip))
return clip;
if (r->width == 0 || r->height == 0)
return _cairo_clip_set_all_clipped (clip);
box.p1.x = _cairo_fixed_from_int (r->x);
box.p1.y = _cairo_fixed_from_int (r->y);
box.p2.x = _cairo_fixed_from_int (r->x + r->width);
box.p2.y = _cairo_fixed_from_int (r->y + r->height);
return _cairo_clip_intersect_rectangle_box (clip, r, &box);
}
struct reduce {
cairo_clip_t *clip;
cairo_box_t limit;
cairo_box_t extents;
cairo_bool_t inside;
cairo_point_t current_point;
cairo_point_t last_move_to;
};
static void
_add_clipped_edge (struct reduce *r,
const cairo_point_t *p1,
const cairo_point_t *p2,
int y1, int y2)
{
cairo_fixed_t x;
x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y1);
if (x < r->extents.p1.x)
r->extents.p1.x = x;
x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y2);
if (x > r->extents.p2.x)
r->extents.p2.x = x;
if (y1 < r->extents.p1.y)
r->extents.p1.y = y1;
if (y2 > r->extents.p2.y)
r->extents.p2.y = y2;
r->inside = TRUE;
}
static void
_add_edge (struct reduce *r,
const cairo_point_t *p1,
const cairo_point_t *p2)
{
int top, bottom;
int top_y, bot_y;
int n;
if (p1->y < p2->y) {
top = p1->y;
bottom = p2->y;
} else {
top = p2->y;
bottom = p1->y;
}
if (bottom < r->limit.p1.y || top > r->limit.p2.y)
return;
if (p1->x > p2->x) {
const cairo_point_t *t = p1;
p1 = p2;
p2 = t;
}
if (p2->x <= r->limit.p1.x || p1->x >= r->limit.p2.x)
return;
for (n = 0; n < r->clip->num_boxes; n++) {
const cairo_box_t *limits = &r->clip->boxes[n];
if (bottom < limits->p1.y || top > limits->p2.y)
continue;
if (p2->x <= limits->p1.x || p1->x >= limits->p2.x)
continue;
if (p1->x >= limits->p1.x && p2->x <= limits->p1.x) {
top_y = top;
bot_y = bottom;
} else {
int p1_y, p2_y;
p1_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
limits->p1.x);
p2_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
limits->p2.x);
if (p1_y < p2_y) {
top_y = p1_y;
bot_y = p2_y;
} else {
top_y = p2_y;
bot_y = p1_y;
}
if (top_y < top)
top_y = top;
if (bot_y > bottom)
bot_y = bottom;
}
if (top_y < limits->p1.y)
top_y = limits->p1.y;
if (bot_y > limits->p2.y)
bot_y = limits->p2.y;
if (bot_y > top_y)
_add_clipped_edge (r, p1, p2, top_y, bot_y);
}
}
static cairo_status_t
_reduce_line_to (void *closure,
const cairo_point_t *point)
{
struct reduce *r = closure;
_add_edge (r, &r->current_point, point);
r->current_point = *point;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_reduce_close (void *closure)
{
struct reduce *r = closure;
return _reduce_line_to (r, &r->last_move_to);
}
static cairo_status_t
_reduce_move_to (void *closure,
const cairo_point_t *point)
{
struct reduce *r = closure;
cairo_status_t status;
/* close current subpath */
status = _reduce_close (closure);
/* make sure that the closure represents a degenerate path */
r->current_point = *point;
r->last_move_to = *point;
return status;
}
static cairo_clip_t *
_cairo_clip_reduce_to_boxes (cairo_clip_t *clip)
{
struct reduce r;
cairo_clip_path_t *clip_path;
cairo_status_t status;
return clip;
if (clip->path == NULL)
return clip;
r.clip = clip;
r.extents.p1.x = r.extents.p1.y = INT_MAX;
r.extents.p2.x = r.extents.p2.y = INT_MIN;
r.inside = FALSE;
r.limit.p1.x = _cairo_fixed_from_int (clip->extents.x);
r.limit.p1.y = _cairo_fixed_from_int (clip->extents.y);
r.limit.p2.x = _cairo_fixed_from_int (clip->extents.x + clip->extents.width);
r.limit.p2.y = _cairo_fixed_from_int (clip->extents.y + clip->extents.height);
clip_path = clip->path;
do {
r.current_point.x = 0;
r.current_point.y = 0;
r.last_move_to = r.current_point;
status = _cairo_path_fixed_interpret_flat (&clip_path->path,
_reduce_move_to,
_reduce_line_to,
_reduce_close,
&r,
clip_path->tolerance);
assert (status == CAIRO_STATUS_SUCCESS);
_reduce_close (&r);
} while ((clip_path = clip_path->prev));
if (! r.inside) {
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
}
return _cairo_clip_intersect_box (clip, &r.extents);
}
cairo_clip_t *
_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
cairo_clip_t *copy;
if (_cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *) clip;
if (_cairo_clip_contains_rectangle (clip, r))
return _cairo_clip_intersect_rectangle (NULL, r);
copy = _cairo_clip_copy_intersect_rectangle (clip, r);
if (_cairo_clip_is_all_clipped (copy))
return copy;
return _cairo_clip_reduce_to_boxes (copy);
}
cairo_clip_t *
_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
cairo_composite_rectangles_t *extents)
{
const cairo_rectangle_int_t *r;
r = extents->is_bounded ? &extents->bounded : &extents->unbounded;
return _cairo_clip_reduce_to_rectangle (clip, r);
}
cairo_status_t
_cairo_clip_to_boxes (cairo_clip_t *clip,
cairo_boxes_t *boxes)
{
_cairo_boxes_init_for_array (boxes, clip->boxes, clip->num_boxes);
if (clip->path == NULL) {
cairo_box_t *src = clip->boxes;
int i;
clip->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (clip->boxes == NULL) {
clip->boxes = src;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
for (i = 0; i < clip->num_boxes; i++) {
clip->boxes[i].p1.x = _cairo_fixed_floor (src[i].p1.x);
clip->boxes[i].p1.y = _cairo_fixed_floor (src[i].p1.y);
clip->boxes[i].p2.x = _cairo_fixed_ceil (src[i].p2.x);
clip->boxes[i].p2.y = _cairo_fixed_ceil (src[i].p2.y);
}
}
return CAIRO_STATUS_SUCCESS;
}

127
src/cairo-clip-polygon.c Normal file
View file

@ -0,0 +1,127 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static cairo_bool_t
can_convert_to_polygon (const cairo_clip_t *clip)
{
cairo_clip_path_t *clip_path = clip->path;
cairo_antialias_t antialias = clip_path->antialias;
while ((clip_path = clip_path->prev) != NULL) {
if (clip_path->antialias != antialias)
return FALSE;
}
return TRUE;
}
cairo_int_status_t
_cairo_clip_get_polygon (const cairo_clip_t *clip,
cairo_polygon_t *polygon,
cairo_fill_rule_t *fill_rule,
cairo_antialias_t *antialias)
{
cairo_status_t status;
cairo_clip_path_t *clip_path;
if (_cairo_clip_is_all_clipped (clip)) {
_cairo_polygon_init (polygon, NULL, 0);
return CAIRO_INT_STATUS_SUCCESS;
}
/* If there is no clip, we need an infinite polygon */
assert (clip && (clip->path || clip->num_boxes));
if (clip->path == NULL) {
*fill_rule = CAIRO_FILL_RULE_WINDING;
*antialias = CAIRO_ANTIALIAS_DEFAULT;
return _cairo_polygon_init_box_array (polygon,
clip->boxes,
clip->num_boxes);
}
/* check that residual is all of the same type/tolerance */
if (! can_convert_to_polygon (clip))
return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_polygon_init_with_clip (polygon, clip);
clip_path = clip->path;
status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
clip_path->tolerance,
polygon);
if (unlikely (status)) {
_cairo_polygon_fini (polygon);
return status;
}
polygon->limits = NULL;
polygon->num_limits = 0;
*fill_rule = clip_path->fill_rule;
*antialias = clip_path->antialias;
while ((clip_path = clip_path->prev) != NULL) {
cairo_polygon_t next;
_cairo_polygon_init (&next, NULL, 0);
status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
clip_path->tolerance,
&next);
if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_polygon_intersect (polygon, *fill_rule,
&next, clip_path->fill_rule);
_cairo_polygon_fini (&next);
if (unlikely (status)) {
_cairo_polygon_fini (polygon);
return status;
}
*fill_rule = CAIRO_FILL_RULE_WINDING;
}
return CAIRO_STATUS_SUCCESS;
}

View file

@ -31,24 +31,21 @@
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_CLIP_PRIVATE_H
#define CAIRO_CLIP_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-boxes-private.h"
#include "cairo-compiler-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-reference-count-private.h"
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
enum {
CAIRO_CLIP_PATH_HAS_REGION = 0x1,
CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2,
CAIRO_CLIP_PATH_IS_BOX = 0x4
};
struct _cairo_clip_path {
cairo_reference_count_t ref_count;
cairo_path_fixed_t path;
@ -58,92 +55,124 @@ struct _cairo_clip_path {
cairo_clip_path_t *prev;
cairo_rectangle_int_t extents;
/* partial caches */
unsigned int flags;
cairo_region_t *region;
cairo_surface_t *surface;
};
struct _cairo_clip {
/* can be used as a cairo_hash_entry_t for live clips */
cairo_rectangle_int_t extents;
cairo_clip_path_t *path;
cairo_bool_t all_clipped;
cairo_box_t *boxes;
int num_boxes;
cairo_region_t *region;
cairo_bool_t is_region;
};
cairo_private void
_cairo_clip_init (cairo_clip_t *clip);
cairo_private_no_warn cairo_clip_t *
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
cairo_private cairo_status_t
_cairo_clip_init_copy_transformed (cairo_clip_t *clip,
cairo_clip_t *other,
const cairo_matrix_t *matrix);
cairo_private cairo_clip_t *
_cairo_clip_create (void);
cairo_private void
_cairo_clip_reset (cairo_clip_t *clip);
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
cairo_private void
_cairo_clip_destroy (cairo_clip_t *clip);
extern const cairo_clip_t __cairo_clip_all;
static inline cairo_bool_t _cairo_clip_is_all_clipped(const cairo_clip_t *clip)
{
return clip == &__cairo_clip_all;
}
static inline cairo_clip_t *
_cairo_clip_set_all_clipped (cairo_clip_t *clip)
{
_cairo_clip_destroy (clip);
return (cairo_clip_t *) &__cairo_clip_all;
}
cairo_private cairo_clip_t *
_cairo_clip_copy (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty);
cairo_private cairo_bool_t
_cairo_clip_equal (const cairo_clip_t *clip_a,
const cairo_clip_t *clip_b);
#define _cairo_clip_fini(clip) _cairo_clip_reset (clip)
cairo_private cairo_clip_t *
_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
const cairo_rectangle_int_t *rectangle);
cairo_private cairo_status_t
_cairo_clip_rectangle (cairo_clip_t *clip,
const cairo_rectangle_int_t *rectangle);
static inline cairo_clip_t *
_cairo_clip_copy_intersect_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
return _cairo_clip_intersect_rectangle (_cairo_clip_copy (clip), r);
}
cairo_private cairo_status_t
_cairo_clip_clip (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias);
cairo_private cairo_clip_t *
_cairo_clip_intersect_box (cairo_clip_t *clip,
const cairo_box_t *box);
cairo_private cairo_status_t
_cairo_clip_apply_clip (cairo_clip_t *clip,
const cairo_clip_t *other);
cairo_private cairo_clip_t *
_cairo_clip_intersect_boxes (cairo_clip_t *clip,
const cairo_boxes_t *boxes);
cairo_private cairo_clip_t *
_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias);
cairo_private cairo_clip_t *
_cairo_clip_intersect_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias);
cairo_private const cairo_rectangle_int_t *
_cairo_clip_get_extents (const cairo_clip_t *clip);
cairo_private cairo_surface_t *
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
_cairo_clip_get_surface (const cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
cairo_private cairo_status_t
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
cairo_surface_t *dst,
int dst_x, int dst_y);
cairo_private cairo_int_status_t
_cairo_clip_get_region (cairo_clip_t *clip,
cairo_region_t **region);
cairo_private cairo_int_status_t
_cairo_clip_get_boxes (cairo_clip_t *clip,
cairo_box_t **boxes,
int *count);
cairo_private cairo_status_t
_cairo_clip_to_boxes (cairo_clip_t **clip,
cairo_composite_rectangles_t *extents,
cairo_box_t **boxes,
int *num_boxes);
_cairo_clip_to_boxes (cairo_clip_t *clip,
cairo_boxes_t *boxes);
cairo_private cairo_region_t *
_cairo_clip_get_region (const cairo_clip_t *clip);
cairo_private cairo_bool_t
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
_cairo_clip_is_region (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r);
cairo_private cairo_clip_t *
_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
cairo_composite_rectangles_t *extents);
cairo_private cairo_bool_t
_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect);
cairo_private cairo_bool_t
_cairo_clip_contains_extents (cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents);
_cairo_clip_contains_box (const cairo_clip_t *clip,
const cairo_box_t *box);
cairo_private void
_cairo_clip_drop_cache (cairo_clip_t *clip);
cairo_private cairo_bool_t
_cairo_clip_contains_extents (const cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents);
cairo_private cairo_rectangle_list_t*
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
@ -151,4 +180,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
cairo_private cairo_rectangle_list_t *
_cairo_rectangle_list_create_in_error (cairo_status_t status);
cairo_private cairo_int_status_t
_cairo_clip_get_polygon (const cairo_clip_t *clip,
cairo_polygon_t *polygon,
cairo_fill_rule_t *fill_rule,
cairo_antialias_t *antialias);
#endif /* CAIRO_CLIP_PRIVATE_H */

117
src/cairo-clip-region.c Normal file
View file

@ -0,0 +1,117 @@
/* -*- 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
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static void
_cairo_clip_extract_region (cairo_clip_t *clip)
{
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
cairo_rectangle_int_t *r = stack_rects;
cairo_bool_t is_region;
int i;
if (clip->num_boxes == 0)
return;
if (clip->num_boxes > ARRAY_LENGTH (stack_rects)) {
r = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_rectangle_int_t));
if (r == NULL){
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return;
}
}
is_region = clip->path == NULL;
for (i = 0; i < clip->num_boxes; i++) {
cairo_box_t *b = &clip->boxes[i];
if (is_region)
is_region =
_cairo_fixed_is_integer (b->p1.x | b->p1.y | b->p2.x | b->p2.y);
r[i].x = _cairo_fixed_integer_floor (b->p1.x);
r[i].y = _cairo_fixed_integer_floor (b->p1.y);
r[i].width = _cairo_fixed_integer_ceil (b->p2.x) - r[i].x;
r[i].height = _cairo_fixed_integer_ceil (b->p2.y) - r[i].y;
}
clip->is_region = is_region;
clip->region = cairo_region_create_rectangles (r, i);
if (r != stack_rects)
free (r);
}
cairo_region_t *
_cairo_clip_get_region (const cairo_clip_t *clip)
{
if (clip == NULL)
return NULL;
if (clip->region == NULL)
_cairo_clip_extract_region ((cairo_clip_t *) clip);
return clip->region;
}
cairo_bool_t
_cairo_clip_is_region (const cairo_clip_t *clip)
{
if (clip == NULL)
return TRUE;
/* XXX Geometric reduction? */
if (clip->path)
return FALSE;
if (clip->region == NULL)
_cairo_clip_extract_region ((cairo_clip_t *) clip);
return clip->is_region;
}

142
src/cairo-clip-surface.c Normal file
View file

@ -0,0 +1,142 @@
/* -*- 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
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
cairo_status_t
_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
cairo_surface_t *dst,
int dst_x, int dst_y)
{
cairo_clip_path_t *clip_path;
cairo_clip_path_t *copy_path;
cairo_clip_t *copy;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
copy = _cairo_clip_copy_with_translation (clip, -dst_x, -dst_y);
copy_path = copy->path;
copy->path = NULL;
if (copy_path == NULL) {
assert (copy->num_boxes);
status = _cairo_surface_paint (dst,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
copy);
}
clip_path = copy_path;
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
status = _cairo_surface_fill (dst,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
copy);
clip_path = clip_path->prev;
}
copy->path = copy_path;
_cairo_clip_destroy (copy);
return status;
}
cairo_surface_t *
_cairo_clip_get_surface (const cairo_clip_t *clip,
cairo_surface_t *target,
int *tx, int *ty)
{
cairo_surface_t *surface;
cairo_status_t status;
cairo_clip_t *copy;
cairo_clip_path_t *copy_path, *clip_path;
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
clip->extents.width,
clip->extents.height,
CAIRO_COLOR_TRANSPARENT,
TRUE);
if (unlikely (surface->status))
return surface;
copy = _cairo_clip_copy_with_translation (clip,
-clip->extents.x,
-clip->extents.y);
copy_path = copy->path;
copy->path = NULL;
assert (copy->num_boxes);
status = _cairo_surface_paint (surface,
CAIRO_OPERATOR_ADD,
&_cairo_pattern_white.base,
copy);
clip_path = copy_path;
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
status = _cairo_surface_fill (surface,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
copy);
clip_path = clip_path->prev;
}
copy->path = copy_path;
_cairo_clip_destroy (copy);
*tx = clip->extents.x;
*ty = clip->extents.y;
return surface;
}

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,8 @@ struct _cairo_composite_rectangles {
cairo_rectangle_int_t bounded; /* dst */
cairo_rectangle_int_t unbounded; /* clip */
uint32_t is_bounded;
cairo_clip_t *clip;
};
cairo_private cairo_int_status_t
@ -63,7 +65,7 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
@ -71,25 +73,25 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_clip_t *clip);
const cairo_path_fixed_t *path,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
@ -99,7 +101,10 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip,
const cairo_clip_t *clip,
cairo_bool_t *overlap);
cairo_private void
_cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents);
#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */

View file

@ -41,25 +41,29 @@
/* A collection of routines to facilitate writing compositors. */
void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents)
{
_cairo_clip_destroy (extents->clip);
}
static inline cairo_bool_t
_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
int width, int height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
extents->unbounded.x = extents->unbounded.y = 0;
extents->unbounded.width = width;
extents->unbounded.height = height;
extents->clip = NULL;
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
if (clip != NULL) {
const cairo_rectangle_int_t *clip_extents;
clip_extents = _cairo_clip_get_extents (clip);
if (clip_extents == NULL)
return FALSE;
if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (clip)))
return FALSE;
}
@ -80,7 +84,7 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface_width, surface_height,
@ -90,11 +94,17 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
}
extents->mask = extents->bounded;
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
const cairo_clip_t *clip)
{
cairo_bool_t ret;
@ -102,6 +112,10 @@ _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
return CAIRO_STATUS_SUCCESS;
}
@ -111,7 +125,7 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface_width, surface_height,
@ -122,7 +136,7 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
_cairo_pattern_get_extents (mask, &extents->mask);
return _cairo_composite_rectangles_intersect (extents);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
@ -130,10 +144,10 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface_width, surface_height,
@ -144,7 +158,7 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
_cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
return _cairo_composite_rectangles_intersect (extents);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
@ -152,8 +166,8 @@ _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents
int surface_width, int surface_height,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_clip_t *clip)
const cairo_path_fixed_t *path,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface_width, surface_height,
@ -164,7 +178,7 @@ _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents
_cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
return _cairo_composite_rectangles_intersect (extents);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
@ -175,7 +189,7 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip,
const cairo_clip_t *clip,
cairo_bool_t *overlap)
{
cairo_status_t status;
@ -194,5 +208,5 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
if (unlikely (status))
return status;
return _cairo_composite_rectangles_intersect (extents);
return _cairo_composite_rectangles_intersect (extents, clip);
}

View file

@ -35,7 +35,6 @@
#include "cairoint.h"
/**
* cairo_debug_reset_static_data:
*
@ -234,8 +233,10 @@ void
_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
{
cairo_status_t status;
cairo_box_t box;
printf ("path: extents=(%f, %f), (%f, %f)\n",
fprintf (stream,
"path: extents=(%f, %f), (%f, %f)\n",
_cairo_fixed_to_double (path->extents.p1.x),
_cairo_fixed_to_double (path->extents.p1.y),
_cairo_fixed_to_double (path->extents.p2.x),
@ -249,5 +250,37 @@ _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
stream);
assert (status == CAIRO_STATUS_SUCCESS);
if (_cairo_path_fixed_is_box (path, &box)) {
fprintf (stream, "[box (%d, %d), (%d, %d)]",
box.p1.x, box.p1.y, box.p2.x, box.p2.y);
}
printf ("\n");
}
void
_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon)
{
int n;
fprintf (stream,
"polygon: extents=(%f, %f), (%f, %f)\n",
_cairo_fixed_to_double (polygon->extents.p1.x),
_cairo_fixed_to_double (polygon->extents.p1.y),
_cairo_fixed_to_double (polygon->extents.p2.x),
_cairo_fixed_to_double (polygon->extents.p2.y));
for (n = 0; n < polygon->num_edges; n++) {
cairo_edge_t *edge = &polygon->edges[n];
fprintf (stream,
" (%f, %f) -> (%f, %f), top=%f, bottom=%f, dir=%d\n",
_cairo_fixed_to_double (edge->line.p1.x),
_cairo_fixed_to_double (edge->line.p1.y),
_cairo_fixed_to_double (edge->line.p2.x),
_cairo_fixed_to_double (edge->line.p2.y),
_cairo_fixed_to_double (edge->top),
_cairo_fixed_to_double (edge->bottom),
edge->dir);
}
}

View file

@ -131,7 +131,7 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
cairo_status_t status;
clip = _cairo_gstate_get_clip (cr->gstate);
if (clip->all_clipped) {
if (_cairo_clip_is_all_clipped (clip)) {
group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
status = group_surface->status;
if (unlikely (status))
@ -276,7 +276,8 @@ _cairo_default_context_set_source_rgba (void *abstract_cr, double red, double gr
cairo_pattern_t *pattern;
cairo_status_t status;
if (_current_source_matches_solid (cr->gstate->source, red, green, blue, 1.))
if (_current_source_matches_solid (cr->gstate->source,
red, green, blue, alpha))
return CAIRO_STATUS_SUCCESS;
/* push the current pattern to the freed lists */

View file

@ -43,9 +43,63 @@
CAIRO_BEGIN_DECLS
enum _cairo_int_status {
CAIRO_INT_STATUS_SUCCESS = 0,
CAIRO_INT_STATUS_NO_MEMORY,
CAIRO_INT_STATUS_INVALID_RESTORE,
CAIRO_INT_STATUS_INVALID_POP_GROUP,
CAIRO_INT_STATUS_NO_CURRENT_POINT,
CAIRO_INT_STATUS_INVALID_MATRIX,
CAIRO_INT_STATUS_INVALID_STATUS,
CAIRO_INT_STATUS_NULL_POINTER,
CAIRO_INT_STATUS_INVALID_STRING,
CAIRO_INT_STATUS_INVALID_PATH_DATA,
CAIRO_INT_STATUS_READ_ERROR,
CAIRO_INT_STATUS_WRITE_ERROR,
CAIRO_INT_STATUS_SURFACE_FINISHED,
CAIRO_INT_STATUS_SURFACE_TYPE_MISMATCH,
CAIRO_INT_STATUS_PATTERN_TYPE_MISMATCH,
CAIRO_INT_STATUS_INVALID_CONTENT,
CAIRO_INT_STATUS_INVALID_FORMAT,
CAIRO_INT_STATUS_INVALID_VISUAL,
CAIRO_INT_STATUS_FILE_NOT_FOUND,
CAIRO_INT_STATUS_INVALID_DASH,
CAIRO_INT_STATUS_INVALID_DSC_COMMENT,
CAIRO_INT_STATUS_INVALID_INDEX,
CAIRO_INT_STATUS_CLIP_NOT_REPRESENTABLE,
CAIRO_INT_STATUS_TEMP_FILE_ERROR,
CAIRO_INT_STATUS_INVALID_STRIDE,
CAIRO_INT_STATUS_FONT_TYPE_MISMATCH,
CAIRO_INT_STATUS_USER_FONT_IMMUTABLE,
CAIRO_INT_STATUS_USER_FONT_ERROR,
CAIRO_INT_STATUS_NEGATIVE_COUNT,
CAIRO_INT_STATUS_INVALID_CLUSTERS,
CAIRO_INT_STATUS_INVALID_SLANT,
CAIRO_INT_STATUS_INVALID_WEIGHT,
CAIRO_INT_STATUS_INVALID_SIZE,
CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED,
CAIRO_INT_STATUS_DEVICE_TYPE_MISMATCH,
CAIRO_INT_STATUS_DEVICE_ERROR,
CAIRO_INT_STATUS_INVALID_MESH_CONSTRUCTION,
CAIRO_INT_STATUS_DEVICE_FINISHED,
CAIRO_INT_STATUS_LAST_STATUS,
CAIRO_INT_STATUS_UNSUPPORTED = 100,
CAIRO_INT_STATUS_DEGENERATE,
CAIRO_INT_STATUS_NOTHING_TO_DO,
CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
CAIRO_INT_STATUS_IMAGE_FALLBACK,
CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN,
};
#define _cairo_status_is_error(status) \
(status != CAIRO_STATUS_SUCCESS && status <= CAIRO_STATUS_LAST_STATUS)
#define _cairo_int_status_is_error(status) \
(status != CAIRO_INT_STATUS_SUCCESS && status <= CAIRO_INT_STATUS_LAST_STATUS)
cairo_private cairo_status_t
_cairo_error (cairo_status_t status);

View file

@ -39,7 +39,9 @@
#include "cairoint.h"
#include "cairo-private.h"
#include "cairo-compiler-private.h"
#include "cairo-error-private.h"
#include <assert.h>
/**
@ -67,3 +69,5 @@ _cairo_error (cairo_status_t status)
return status;
}
COMPILE_TIME_ASSERT ((int)CAIRO_INT_STATUS_LAST_STATUS == (int)CAIRO_STATUS_LAST_STATUS);

View file

@ -163,6 +163,12 @@ _cairo_fixed_floor (cairo_fixed_t f)
return f & ~CAIRO_FIXED_FRAC_MASK;
}
static inline cairo_fixed_t
_cairo_fixed_ceil (cairo_fixed_t f)
{
return _cairo_fixed_floor (f + CAIRO_FIXED_FRAC_MASK);
}
static inline cairo_fixed_t
_cairo_fixed_round (cairo_fixed_t f)
{

View file

@ -283,16 +283,14 @@ face_props_parse (twin_face_properties_t *props,
parse_field (props, start, end - start);
}
static cairo_status_t
twin_font_face_create_properties (cairo_font_face_t *twin_face,
twin_face_properties_t **props_out)
static twin_face_properties_t *
twin_font_face_create_properties (cairo_font_face_t *twin_face)
{
twin_face_properties_t *props;
cairo_status_t status;
props = malloc (sizeof (twin_face_properties_t));
if (unlikely (props == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
props->stretch = TWIN_STRETCH_NORMAL;
props->slant = CAIRO_FONT_SLANT_NORMAL;
@ -300,30 +298,25 @@ twin_font_face_create_properties (cairo_font_face_t *twin_face,
props->monospace = FALSE;
props->smallcaps = FALSE;
status = cairo_font_face_set_user_data (twin_face,
if (unlikely (cairo_font_face_set_user_data (twin_face,
&twin_properties_key,
props, free);
if (unlikely (status)) {
props, free))) {
free (props);
return status;
return NULL;
}
if (props_out)
*props_out = props;
return CAIRO_STATUS_SUCCESS;
return props;
}
static cairo_status_t
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
cairo_toy_font_face_t *toy_face)
{
cairo_status_t status;
twin_face_properties_t *props;
status = twin_font_face_create_properties (twin_face, &props);
if (unlikely (status))
return status;
props = twin_font_face_create_properties (twin_face);
if (unlikely (props == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
props->slant = toy_face->slant;
props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
@ -729,11 +722,9 @@ cairo_font_face_t *
_cairo_font_face_twin_create_fallback (void)
{
cairo_font_face_t *twin_font_face;
cairo_status_t status;
twin_font_face = _cairo_font_face_twin_create_internal ();
status = twin_font_face_create_properties (twin_font_face, NULL);
if (status) {
if (! twin_font_face_create_properties (twin_font_face)) {
cairo_font_face_destroy (twin_font_face);
return (cairo_font_face_t *) &_cairo_font_face_nil;
}

View file

@ -2573,27 +2573,28 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
/* #cairo_ft_font_face_t */
#if CAIRO_HAS_FC_FONT
static cairo_status_t
_cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
cairo_font_face_t **out);
static cairo_font_face_t *
_cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
static cairo_status_t
_cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
cairo_font_face_t **font_face)
_cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
cairo_font_face_t **font_face_out)
{
cairo_font_face_t *font_face = (cairo_font_face_t *) &_cairo_font_face_nil;
FcPattern *pattern;
int fcslant;
int fcweight;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
pattern = FcPatternCreate ();
if (!pattern)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (!pattern) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return font_face->status;
}
if (!FcPatternAddString (pattern,
FC_FAMILY, (unsigned char *) toy_face->family))
{
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto FREE_PATTERN;
}
@ -2612,7 +2613,7 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
}
if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto FREE_PATTERN;
}
@ -2628,16 +2629,17 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
}
if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto FREE_PATTERN;
}
status = _cairo_ft_font_face_create_for_pattern (pattern, font_face);
font_face = _cairo_ft_font_face_create_for_pattern (pattern);
FREE_PATTERN:
FcPatternDestroy (pattern);
return status;
*font_face_out = font_face;
return font_face->status;
}
#endif
@ -2776,15 +2778,16 @@ const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
};
#if CAIRO_HAS_FC_FONT
static cairo_status_t
_cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
cairo_font_face_t **out)
static cairo_font_face_t *
_cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
{
cairo_ft_font_face_t *font_face;
font_face = malloc (sizeof (cairo_ft_font_face_t));
if (unlikely (font_face == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (unlikely (font_face == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *) &_cairo_font_face_nil;
}
font_face->unscaled = NULL;
font_face->next = NULL;
@ -2792,7 +2795,8 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
font_face->pattern = FcPatternDuplicate (pattern);
if (unlikely (font_face->pattern == NULL)) {
free (font_face);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *) &_cairo_font_face_nil;
}
font_face->resolved_font_face = NULL;
@ -2800,8 +2804,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
_cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
*out = &font_face->base;
return CAIRO_STATUS_SUCCESS;
return &font_face->base;
}
#endif
@ -3156,12 +3159,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
if (unlikely (unscaled == NULL)) {
/* Store the pattern. We will resolve it and create unscaled
* font when creating scaled fonts */
status = _cairo_ft_font_face_create_for_pattern (pattern,
&font_face);
if (unlikely (status))
return (cairo_font_face_t *) &_cairo_font_face_nil;
return font_face;
return _cairo_ft_font_face_create_for_pattern (pattern);
}
_get_pattern_ft_options (pattern, &ft_options);

View file

@ -40,6 +40,7 @@
#include "cairo-gl-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-error-private.h"
#include "cairo-rtree-private.h"
@ -54,7 +55,7 @@ typedef struct _cairo_gl_glyph_private {
struct { float x, y; } p1, p2;
} cairo_gl_glyph_private_t;
static cairo_status_t
static cairo_int_status_t
_cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cairo_gl_glyph_cache_t *cache,
cairo_scaled_glyph_t *scaled_glyph)
@ -63,7 +64,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cairo_gl_surface_t *cache_surface;
cairo_gl_glyph_private_t *glyph_private;
cairo_rtree_node_t *node = NULL;
cairo_status_t status;
cairo_int_status_t status;
int width, height;
width = glyph_surface->width;
@ -79,7 +80,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
status = _cairo_rtree_evict_random (&cache->rtree,
width, height, &node);
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
status = _cairo_rtree_node_insert (&cache->rtree,
node, width, height, &node);
}
@ -148,6 +149,7 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
cache = &ctx->glyph_cache[1];
content = CAIRO_CONTENT_ALPHA;
break;
default:
case CAIRO_FORMAT_INVALID:
ASSERT_NOT_REACHED;
return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
@ -227,10 +229,9 @@ _render_glyphs (cairo_gl_surface_t *dst,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_rectangle_int_t *glyph_extents,
cairo_scaled_font_t *scaled_font,
const cairo_composite_rectangles_t *extents,
cairo_bool_t *has_component_alpha,
cairo_region_t *clip_region,
int *remaining_glyphs)
{
cairo_format_t last_format = CAIRO_FORMAT_INVALID;
@ -249,7 +250,7 @@ _render_glyphs (cairo_gl_surface_t *dst,
_cairo_scaled_font_freeze_cache (scaled_font);
status = _cairo_gl_composite_init (&setup, op, dst,
TRUE, glyph_extents);
TRUE, &extents->bounded);
if (unlikely (status))
goto FINISH;
@ -260,10 +261,11 @@ _render_glyphs (cairo_gl_surface_t *dst,
}
status = _cairo_gl_composite_set_source (&setup, source,
glyph_extents->x, glyph_extents->y,
extents->bounded.x,
extents->bounded.y,
dst_x, dst_y,
glyph_extents->width,
glyph_extents->height);
extents->bounded.width,
extents->bounded.height);
if (unlikely (status))
goto FINISH;
@ -273,7 +275,8 @@ _render_glyphs (cairo_gl_surface_t *dst,
cairo_list_add (&scaled_font->link, &ctx->fonts);
}
_cairo_gl_composite_set_clip_region (&setup, clip_region);
_cairo_gl_composite_set_clip_region (&setup,
_cairo_clip_get_region (extents->clip));
for (i = 0; i < num_glyphs; i++) {
cairo_scaled_glyph_t *scaled_glyph;
@ -374,35 +377,41 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t *dst,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_rectangle_int_t *glyph_extents,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
cairo_composite_rectangles_t *extents,
int *remaining_glyphs)
{
cairo_surface_t *mask;
cairo_status_t status;
cairo_bool_t has_component_alpha;
cairo_clip_t *saved_clip;
int i;
/* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
mask = cairo_gl_surface_create (dst->base.device,
CAIRO_CONTENT_COLOR_ALPHA,
glyph_extents->width,
glyph_extents->height);
extents->bounded.width,
extents->bounded.height);
if (unlikely (mask->status))
return mask->status;
for (i = 0; i < num_glyphs; i++) {
glyphs[i].x -= glyph_extents->x;
glyphs[i].y -= glyph_extents->y;
glyphs[i].x -= extents->bounded.x;
glyphs[i].y -= extents->bounded.y;
}
saved_clip = extents->clip;
extents->clip = NULL;
status = _render_glyphs ((cairo_gl_surface_t *) mask, 0, 0,
CAIRO_OPERATOR_ADD,
&_cairo_pattern_white.base,
glyphs, num_glyphs, glyph_extents,
scaled_font, &has_component_alpha,
NULL, remaining_glyphs);
glyphs, num_glyphs, scaled_font,
extents,
&has_component_alpha,
remaining_glyphs);
extents->clip = saved_clip;
if (likely (status == CAIRO_STATUS_SUCCESS)) {
cairo_surface_pattern_t mask_pattern;
@ -410,14 +419,15 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t *dst,
_cairo_pattern_init_for_surface (&mask_pattern, mask);
mask_pattern.base.has_component_alpha = has_component_alpha;
cairo_matrix_init_translate (&mask_pattern.base.matrix,
-glyph_extents->x, -glyph_extents->y);
-extents->bounded.x, -extents->bounded.y);
status = _cairo_surface_mask (&dst->base, op,
source, &mask_pattern.base, clip);
source, &mask_pattern.base,
extents->clip);
_cairo_pattern_fini (&mask_pattern.base);
} else {
for (i = 0; i < num_glyphs; i++) {
glyphs[i].x += glyph_extents->x;
glyphs[i].y += glyph_extents->y;
glyphs[i].x += extents->bounded.x;
glyphs[i].y += extents->bounded.y;
}
*remaining_glyphs = num_glyphs;
}
@ -434,13 +444,11 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_rectangle_int_t surface_extents;
cairo_rectangle_int_t extents;
cairo_region_t *clip_region = NULL;
cairo_composite_rectangles_t extents;
cairo_bool_t overlap, use_mask = FALSE;
cairo_bool_t has_component_alpha;
cairo_status_t status;
@ -526,60 +534,40 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
if (! _cairo_gl_surface_owns_font (dst, scaled_font))
return UNSUPPORTED ("do not control font");
/* If the glyphs overlap, we need to build an intermediate mask rather
* then perform the compositing directly.
*/
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs, num_glyphs,
&extents,
&overlap);
status = _cairo_composite_rectangles_init_for_glyphs (&extents,
dst->width,
dst->height,
op, source,
scaled_font,
glyphs, num_glyphs,
clip, &overlap);
if (unlikely (status))
return status;
/* If the glyphs overlap, we need to build an intermediate mask rather
* then perform the compositing directly.
*/
use_mask |= overlap;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
/* the empty clip should never be propagated this far */
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
if (unlikely (_cairo_status_is_error (status)))
return status;
use_mask |= status == CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_rectangle_intersect (&extents,
_cairo_clip_get_extents (clip)))
goto EMPTY;
}
surface_extents.x = surface_extents.y = 0;
surface_extents.width = dst->width;
surface_extents.height = dst->height;
if (! _cairo_rectangle_intersect (&extents, &surface_extents))
goto EMPTY;
use_mask |= ! _cairo_clip_is_region (extents.clip);
if (use_mask) {
return _cairo_gl_surface_show_glyphs_via_mask (dst, op,
source,
glyphs, num_glyphs,
&extents,
scaled_font,
clip,
remaining_glyphs);
status = _cairo_gl_surface_show_glyphs_via_mask (dst, op,
source,
glyphs, num_glyphs,
scaled_font,
&extents,
remaining_glyphs);
} else {
status = _render_glyphs (dst, extents.bounded.x, extents.bounded.y,
op, source,
glyphs, num_glyphs, scaled_font,
&extents,
&has_component_alpha,
remaining_glyphs);
}
return _render_glyphs (dst, extents.x, extents.y,
op, source,
glyphs, num_glyphs, &extents,
scaled_font, &has_component_alpha,
clip_region, remaining_glyphs);
EMPTY:
*remaining_glyphs = 0;
if (! _cairo_operator_bounded_by_mask (op))
return _cairo_surface_paint (&dst->base, op, source, clip);
else
return CAIRO_STATUS_SUCCESS;
_cairo_composite_rectangles_fini (&extents);
return status;
}
void

View file

@ -501,7 +501,7 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs);
static inline int

View file

@ -0,0 +1,601 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2009 Eric Anholt
* Copyright © 2009 Chris Wilson
* Copyright © 2005,2010 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Benjamin Otte <otte@gnome.org>
* Carl Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
* Eric Anholt <eric@anholt.net>
*/
#include "cairoint.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-default-context-private.h"
#include "cairo-error-private.h"
#include "cairo-gl-private.h"
cairo_status_t
_cairo_gl_surface_acquire_dest_image (void *abstract_surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t **image_out,
cairo_rectangle_int_t *image_rect_out,
void **image_extra)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_int_status_t status;
status = _cairo_gl_surface_deferred_clear (surface);
if (unlikely (status))
return status;
*image_extra = NULL;
return _cairo_gl_surface_get_image (surface, interest_rect, image_out,
image_rect_out);
}
void
_cairo_gl_surface_release_dest_image (void *abstract_surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t *image,
cairo_rectangle_int_t *image_rect,
void *image_extra)
{
cairo_status_t status;
status = _cairo_gl_surface_draw_image (abstract_surface, image,
0, 0,
image->width, image->height,
image_rect->x, image_rect->y);
/* as we created the image, its format should be directly applicable */
assert (status == CAIRO_STATUS_SUCCESS);
cairo_surface_destroy (&image->base);
}
cairo_status_t
_cairo_gl_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
int src_x,
int src_y,
int width,
int height,
int *clone_offset_x,
int *clone_offset_y,
cairo_surface_t **clone_out)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_int_status_t status;
/* XXX: Use GLCopyTexImage2D to clone non-texture-surfaces */
if (src->device == surface->base.device &&
_cairo_gl_surface_is_texture ((cairo_gl_surface_t *) src)) {
status = _cairo_gl_surface_deferred_clear ((cairo_gl_surface_t *)src);
if (unlikely (status))
return status;
*clone_offset_x = 0;
*clone_offset_y = 0;
*clone_out = cairo_surface_reference (src);
return CAIRO_STATUS_SUCCESS;
} else if (_cairo_surface_is_image (src)) {
cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
cairo_gl_surface_t *clone;
clone = (cairo_gl_surface_t *)
_cairo_gl_surface_create_similar (&surface->base,
src->content,
width, height);
if (clone == NULL)
return UNSUPPORTED ("create_similar failed");
if (clone->base.status)
return clone->base.status;
status = _cairo_gl_surface_draw_image (clone, image_src,
src_x, src_y,
width, height,
0, 0);
if (status) {
cairo_surface_destroy (&clone->base);
return status;
}
*clone_out = &clone->base;
*clone_offset_x = src_x;
*clone_offset_y = src_y;
return CAIRO_STATUS_SUCCESS;
}
return UNSUPPORTED ("unknown src surface type in clone_similar");
}
/** Creates a cairo-gl pattern surface for the given trapezoids */
static cairo_status_t
_cairo_gl_get_traps_pattern (cairo_gl_surface_t *dst,
int dst_x, int dst_y,
int width, int height,
cairo_trapezoid_t *traps,
int num_traps,
cairo_antialias_t antialias,
cairo_surface_pattern_t *pattern)
{
pixman_format_code_t pixman_format;
pixman_image_t *image;
cairo_surface_t *surface;
int i;
pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1,
image = pixman_image_create_bits (pixman_format, width, height, NULL, 0);
if (unlikely (image == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < num_traps; i++) {
pixman_trapezoid_t trap;
trap.top = _cairo_fixed_to_16_16 (traps[i].top);
trap.bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
trap.left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
trap.left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
trap.left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
trap.left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
trap.right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
trap.right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
trap.right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
trap.right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
pixman_rasterize_trapezoid (image, &trap, -dst_x, -dst_y);
}
surface = _cairo_image_surface_create_for_pixman_image (image,
pixman_format);
if (unlikely (surface->status)) {
pixman_image_unref (image);
return surface->status;
}
_cairo_pattern_init_for_surface (pattern, surface);
cairo_surface_destroy (surface);
return CAIRO_STATUS_SUCCESS;
}
cairo_int_status_t
_cairo_gl_surface_composite (cairo_operator_t op,
const cairo_pattern_t *src,
const cairo_pattern_t *mask,
void *abstract_dst,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height,
cairo_region_t *clip_region)
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_gl_context_t *ctx;
cairo_status_t status;
cairo_gl_composite_t setup;
cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
int dx, dy;
status = _cairo_gl_surface_deferred_clear (dst);
if (unlikely (status))
return status;
if (op == CAIRO_OPERATOR_SOURCE &&
mask == NULL &&
src->type == CAIRO_PATTERN_TYPE_SURFACE &&
_cairo_surface_is_image (((cairo_surface_pattern_t *) src)->surface) &&
_cairo_matrix_is_integer_translation (&src->matrix, &dx, &dy)) {
cairo_image_surface_t *image = (cairo_image_surface_t *)
((cairo_surface_pattern_t *) src)->surface;
dx += src_x;
dy += src_y;
if (dx >= 0 &&
dy >= 0 &&
dx + width <= (unsigned int) image->width &&
dy + height <= (unsigned int) image->height) {
status = _cairo_gl_surface_draw_image (dst, image,
dx, dy,
width, height,
dst_x, dst_y);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
}
}
status = _cairo_gl_composite_init (&setup, op, dst,
mask && mask->has_component_alpha,
&rect);
if (unlikely (status))
goto CLEANUP;
status = _cairo_gl_composite_set_source (&setup, src,
src_x, src_y,
dst_x, dst_y,
width, height);
if (unlikely (status))
goto CLEANUP;
status = _cairo_gl_composite_set_mask (&setup, mask,
mask_x, mask_y,
dst_x, dst_y,
width, height);
if (unlikely (status))
goto CLEANUP;
status = _cairo_gl_composite_begin (&setup, &ctx);
if (unlikely (status))
goto CLEANUP;
if (clip_region != NULL) {
int i, num_rectangles;
num_rectangles = cairo_region_num_rectangles (clip_region);
for (i = 0; i < num_rectangles; i++) {
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (clip_region, i, &rect);
_cairo_gl_composite_emit_rect (ctx,
rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height,
0);
}
} else {
_cairo_gl_composite_emit_rect (ctx,
dst_x, dst_y,
dst_x + width, dst_y + height,
0);
}
status = _cairo_gl_context_release (ctx, status);
CLEANUP:
_cairo_gl_composite_fini (&setup);
return status;
}
cairo_int_status_t
_cairo_gl_surface_composite_trapezoids (cairo_operator_t op,
const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x, int src_y,
int dst_x, int dst_y,
unsigned int width,
unsigned int height,
cairo_trapezoid_t *traps,
int num_traps,
cairo_region_t *clip_region)
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_surface_pattern_t traps_pattern;
cairo_int_status_t status;
if (! _cairo_gl_operator_is_supported (op))
return UNSUPPORTED ("unsupported operator");
status = _cairo_gl_surface_deferred_clear (dst);
if (unlikely (status))
return status;
status = _cairo_gl_get_traps_pattern (dst,
dst_x, dst_y, width, height,
traps, num_traps, antialias,
&traps_pattern);
if (unlikely (status))
return status;
status = _cairo_gl_surface_composite (op,
pattern, &traps_pattern.base, dst,
src_x, src_y,
0, 0,
dst_x, dst_y,
width, height,
clip_region);
_cairo_pattern_fini (&traps_pattern.base);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
return status;
}
cairo_int_status_t
_cairo_gl_surface_fill_rectangles (void *abstract_dst,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_int_t *rects,
int num_rects)
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_solid_pattern_t solid;
cairo_gl_context_t *ctx;
cairo_status_t status;
cairo_gl_composite_t setup;
int i;
status = _cairo_gl_surface_deferred_clear (dst);
if (unlikely (status))
return status;
status = _cairo_gl_composite_init (&setup, op, dst,
FALSE,
/* XXX */ NULL);
if (unlikely (status))
goto CLEANUP;
_cairo_pattern_init_solid (&solid, color);
status = _cairo_gl_composite_set_source (&setup, &solid.base,
0, 0,
0, 0,
0, 0);
if (unlikely (status))
goto CLEANUP;
status = _cairo_gl_composite_set_mask (&setup, NULL,
0, 0,
0, 0,
0, 0);
if (unlikely (status))
goto CLEANUP;
status = _cairo_gl_composite_begin (&setup, &ctx);
if (unlikely (status))
goto CLEANUP;
for (i = 0; i < num_rects; i++) {
_cairo_gl_composite_emit_rect (ctx,
rects[i].x,
rects[i].y,
rects[i].x + rects[i].width,
rects[i].y + rects[i].height,
0);
}
status = _cairo_gl_context_release (ctx, status);
CLEANUP:
_cairo_gl_composite_fini (&setup);
return status;
}
typedef struct _cairo_gl_surface_span_renderer {
cairo_span_renderer_t base;
cairo_gl_composite_t setup;
int xmin, xmax;
int ymin, ymax;
cairo_gl_context_t *ctx;
} cairo_gl_surface_span_renderer_t;
static cairo_status_t
_cairo_gl_render_bounded_spans (void *abstract_renderer,
int y, int height,
const cairo_half_open_span_t *spans,
unsigned num_spans)
{
cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
if (num_spans == 0)
return CAIRO_STATUS_SUCCESS;
do {
if (spans[0].coverage) {
_cairo_gl_composite_emit_rect (renderer->ctx,
spans[0].x, y,
spans[1].x, y + height,
spans[0].coverage);
}
spans++;
} while (--num_spans > 1);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_gl_render_unbounded_spans (void *abstract_renderer,
int y, int height,
const cairo_half_open_span_t *spans,
unsigned num_spans)
{
cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
if (y > renderer->ymin) {
_cairo_gl_composite_emit_rect (renderer->ctx,
renderer->xmin, renderer->ymin,
renderer->xmax, y,
0);
}
if (num_spans == 0) {
_cairo_gl_composite_emit_rect (renderer->ctx,
renderer->xmin, y,
renderer->xmax, y + height,
0);
} else {
if (spans[0].x != renderer->xmin) {
_cairo_gl_composite_emit_rect (renderer->ctx,
renderer->xmin, y,
spans[0].x, y + height,
0);
}
do {
_cairo_gl_composite_emit_rect (renderer->ctx,
spans[0].x, y,
spans[1].x, y + height,
spans[0].coverage);
spans++;
} while (--num_spans > 1);
if (spans[0].x != renderer->xmax) {
_cairo_gl_composite_emit_rect (renderer->ctx,
spans[0].x, y,
renderer->xmax, y + height,
0);
}
}
renderer->ymin = y + height;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_gl_finish_unbounded_spans (void *abstract_renderer)
{
cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
if (renderer->ymax > renderer->ymin) {
_cairo_gl_composite_emit_rect (renderer->ctx,
renderer->xmin, renderer->ymin,
renderer->xmax, renderer->ymax,
0);
}
return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
}
static cairo_status_t
_cairo_gl_finish_bounded_spans (void *abstract_renderer)
{
cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
}
static void
_cairo_gl_surface_span_renderer_destroy (void *abstract_renderer)
{
cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
if (!renderer)
return;
_cairo_gl_composite_fini (&renderer->setup);
free (renderer);
}
cairo_bool_t
_cairo_gl_surface_check_span_renderer (cairo_operator_t op,
const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias)
{
if (! _cairo_gl_operator_is_supported (op))
return FALSE;
return TRUE;
(void) pattern;
(void) abstract_dst;
(void) antialias;
}
cairo_span_renderer_t *
_cairo_gl_surface_create_span_renderer (cairo_operator_t op,
const cairo_pattern_t *src,
void *abstract_dst,
cairo_antialias_t antialias,
const cairo_composite_rectangles_t *rects)
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_gl_surface_span_renderer_t *renderer;
cairo_status_t status;
const cairo_rectangle_int_t *extents;
status = _cairo_gl_surface_deferred_clear (dst);
if (unlikely (status))
return _cairo_span_renderer_create_in_error (status);
renderer = calloc (1, sizeof (*renderer));
if (unlikely (renderer == NULL))
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
if (rects->is_bounded) {
renderer->base.render_rows = _cairo_gl_render_bounded_spans;
renderer->base.finish = _cairo_gl_finish_bounded_spans;
extents = &rects->bounded;
} else {
renderer->base.render_rows = _cairo_gl_render_unbounded_spans;
renderer->base.finish = _cairo_gl_finish_unbounded_spans;
extents = &rects->unbounded;
}
renderer->xmin = extents->x;
renderer->xmax = extents->x + extents->width;
renderer->ymin = extents->y;
renderer->ymax = extents->y + extents->height;
status = _cairo_gl_composite_init (&renderer->setup,
op, dst,
FALSE, extents);
if (unlikely (status))
goto FAIL;
status = _cairo_gl_composite_set_source (&renderer->setup, src,
extents->x, extents->y,
extents->x, extents->y,
extents->width, extents->height);
if (unlikely (status))
goto FAIL;
_cairo_gl_composite_set_spans (&renderer->setup);
_cairo_gl_composite_set_clip_region (&renderer->setup,
_cairo_clip_get_region (rects->clip));
status = _cairo_gl_composite_begin (&renderer->setup, &renderer->ctx);
if (unlikely (status))
goto FAIL;
return &renderer->base;
FAIL:
_cairo_gl_composite_fini (&renderer->setup);
free (renderer);
return _cairo_span_renderer_create_in_error (status);
}

View file

@ -745,7 +745,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
cairo_image_surface_t *clone = NULL;
cairo_gl_context_t *ctx;
int cpp;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
@ -851,7 +851,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
}
} else {
cairo_surface_t *tmp;
tmp = _cairo_gl_surface_create_scratch (ctx,
dst->base.content,
width, height);
@ -864,7 +864,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
src_x, src_y,
width, height,
0, 0);
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
cairo_surface_pattern_t tmp_pattern;
_cairo_pattern_init_for_surface (&tmp_pattern, tmp);
@ -1212,7 +1212,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
{
cairo_gl_surface_t *dst = abstract_dst;
cairo_gl_context_t *ctx;
cairo_status_t status;
cairo_int_status_t status;
cairo_gl_composite_t setup;
cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
int dx, dy;
@ -1634,7 +1634,7 @@ static cairo_int_status_t
_cairo_gl_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
/* simplify the common case of clearing the surface */
if (clip == NULL) {
@ -1658,22 +1658,12 @@ _cairo_gl_surface_polygon (cairo_gl_surface_t *dst,
cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
const cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
const cairo_composite_rectangles_t *extents)
{
cairo_status_t status;
cairo_region_t *clip_region = NULL;
cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
if (unlikely (_cairo_status_is_error (status)))
return status;
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
return UNSUPPORTED ("a clip surface would be required");
}
if (! _cairo_clip_is_region (extents->clip))
return UNSUPPORTED ("a clip surface would be required");
if (! _cairo_surface_check_span_renderer (op, src, &dst->base, antialias))
return UNSUPPORTED ("no span renderer");
@ -1685,35 +1675,30 @@ _cairo_gl_surface_polygon (cairo_gl_surface_t *dst,
src = &_cairo_pattern_white.base;
}
status = _cairo_surface_composite_polygon (&dst->base,
op,
src,
fill_rule,
antialias,
extents,
polygon,
clip_region);
return status;
return _cairo_surface_composite_polygon (&dst->base,
op,
src,
fill_rule,
antialias,
extents,
polygon,
clip_region);
}
static cairo_int_status_t
_cairo_gl_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
cairo_polygon_t polygon;
cairo_status_t status;
@ -1726,24 +1711,7 @@ _cairo_gl_surface_stroke (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
clip = _cairo_clip_init_copy (&local_clip, clip);
have_clip = TRUE;
}
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
return status;
}
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
status = _cairo_path_fixed_stroke_to_polygon (path,
style,
ctm, ctm_inverse,
@ -1752,13 +1720,11 @@ _cairo_gl_surface_stroke (void *abstract_surface,
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _cairo_gl_surface_polygon (surface, op, source, &polygon,
CAIRO_FILL_RULE_WINDING, antialias,
&extents, clip);
&extents);
}
_cairo_polygon_fini (&polygon);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -1767,18 +1733,14 @@ static cairo_int_status_t
_cairo_gl_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_polygon_t polygon;
cairo_status_t status;
@ -1790,50 +1752,16 @@ _cairo_gl_surface_fill (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
#if 0
if (extents.is_bounded && clip != NULL) {
cairo_clip_path_t *clip_path;
if (((clip_path = _clip_get_single_path (clip)) != NULL) &&
_cairo_path_fixed_equal (&clip_path->path, path))
{
clip = NULL;
}
}
#endif
if (clip != NULL) {
clip = _cairo_clip_init_copy (&local_clip, clip);
have_clip = TRUE;
}
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
return status;
}
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _cairo_gl_surface_polygon (surface, op, source, &polygon,
fill_rule, antialias,
&extents, clip);
&extents);
}
_cairo_polygon_fini (&polygon);
if (clip_boxes != boxes_stack)
free (clip_boxes);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}

View file

@ -55,7 +55,7 @@ struct _cairo_gstate {
cairo_matrix_t font_matrix;
cairo_font_options_t font_options;
cairo_clip_t clip;
cairo_clip_t *clip;
cairo_surface_t *target; /* The target to which all rendering is directed */
cairo_surface_t *parent_target; /* The previous target which was receiving rendering */

View file

@ -111,7 +111,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
_cairo_font_options_init_default (&gstate->font_options);
_cairo_clip_init (&gstate->clip);
gstate->clip = NULL;
gstate->target = cairo_surface_reference (target);
gstate->parent_target = NULL;
@ -169,7 +169,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
_cairo_clip_init_copy (&gstate->clip, &other->clip);
gstate->clip = _cairo_clip_copy (other->clip);
gstate->target = cairo_surface_reference (other->target);
/* parent_target is always set to NULL; it's only ever set by redirect_target */
@ -206,7 +206,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
cairo_scaled_font_destroy (gstate->scaled_font);
gstate->scaled_font = NULL;
_cairo_clip_reset (&gstate->clip);
_cairo_clip_destroy (gstate->clip);
cairo_list_del (&gstate->device_transform_observer.link);
@ -300,8 +300,6 @@ _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
cairo_status_t
_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
{
cairo_matrix_t matrix;
/* If this gstate is already redirected, this is an error; we need a
* new gstate to be able to redirect */
assert (gstate->parent_target == NULL);
@ -320,13 +318,11 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
/* The clip is in surface backend coordinates for the previous target;
* translate it into the child's backend coordinates. */
cairo_matrix_init_translate (&matrix,
child->device_transform.x0 - gstate->parent_target->device_transform.x0,
child->device_transform.y0 - gstate->parent_target->device_transform.y0);
_cairo_clip_reset (&gstate->clip);
return _cairo_clip_init_copy_transformed (&gstate->clip,
&gstate->next->clip,
&matrix);
gstate->clip = _cairo_clip_copy_with_translation (gstate->next->clip,
child->device_transform.x0 - gstate->parent_target->device_transform.x0,
child->device_transform.y0 - gstate->parent_target->device_transform.y0);
return CAIRO_STATUS_SUCCESS;
}
/**
@ -388,7 +384,7 @@ _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
cairo_clip_t *
_cairo_gstate_get_clip (cairo_gstate_t *gstate)
{
return &gstate->clip;
return gstate->clip;
}
cairo_status_t
@ -938,39 +934,6 @@ _cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
&gstate->ctm_inverse);
}
/* We need to take a copy of the clip so that the lower layers may modify it
* by, perhaps, intersecting it with the operation extents and other paths.
*/
#define _gstate_get_clip(G, C) _cairo_clip_init_copy ((C), &(G)->clip)
static cairo_bool_t
_clipped (cairo_gstate_t *gstate)
{
cairo_rectangle_int_t extents;
if (gstate->clip.all_clipped)
return TRUE;
/* XXX consider applying a surface clip? */
if (gstate->clip.path == NULL)
return FALSE;
if (_cairo_surface_get_extents (gstate->target, &extents)) {
if (extents.width == 0 || extents.height == 0)
return TRUE;
if (! _cairo_rectangle_intersect (&extents,
&gstate->clip.path->extents))
{
return TRUE;
}
}
/* perform a simple query to exclude trivial all-clipped cases */
return _cairo_clip_get_region (&gstate->clip, NULL) == CAIRO_INT_STATUS_NOTHING_TO_DO;
}
static cairo_operator_t
_reduce_op (cairo_gstate_t *gstate)
{
@ -1029,7 +992,6 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
{
cairo_pattern_union_t source_pattern;
const cairo_pattern_t *pattern;
cairo_clip_t clip;
cairo_status_t status;
cairo_operator_t op;
@ -1040,7 +1002,7 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
if (gstate->op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
if (_clipped (gstate))
if (_cairo_clip_is_all_clipped (gstate->clip))
return CAIRO_STATUS_SUCCESS;
op = _reduce_op (gstate);
@ -1051,12 +1013,9 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
pattern = &source_pattern.base;
}
status = _cairo_surface_paint (gstate->target,
op, pattern,
_gstate_get_clip (gstate, &clip));
_cairo_clip_fini (&clip);
return status;
return _cairo_surface_paint (gstate->target,
op, pattern,
gstate->clip);
}
cairo_status_t
@ -1066,7 +1025,6 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
cairo_pattern_union_t source_pattern, mask_pattern;
const cairo_pattern_t *source;
cairo_operator_t op;
cairo_clip_t clip;
cairo_status_t status;
status = _cairo_gstate_get_pattern_status (mask);
@ -1080,7 +1038,7 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
if (gstate->op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
if (_clipped (gstate))
if (_cairo_clip_is_all_clipped (gstate->clip))
return CAIRO_STATUS_SUCCESS;
assert (gstate->opacity == 1.0);
@ -1126,16 +1084,15 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
status = _cairo_surface_paint (gstate->target, op,
&source_pattern.base,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
else
{
status = _cairo_surface_mask (gstate->target, op,
source,
&mask_pattern.base,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
_cairo_clip_fini (&clip);
return status;
}
@ -1146,7 +1103,6 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
cairo_pattern_union_t source_pattern;
cairo_stroke_style_t style;
double dash[2];
cairo_clip_t clip;
cairo_status_t status;
status = _cairo_gstate_get_pattern_status (gstate->source);
@ -1159,7 +1115,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
if (gstate->stroke_style.line_width <= 0.0)
return CAIRO_STATUS_SUCCESS;
if (_clipped (gstate))
if (_cairo_clip_is_all_clipped (gstate->clip))
return CAIRO_STATUS_SUCCESS;
assert (gstate->opacity == 1.0);
@ -1175,19 +1131,16 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
status = _cairo_surface_stroke (gstate->target,
gstate->op,
&source_pattern.base,
path,
&style,
&gstate->ctm,
&gstate->ctm_inverse,
gstate->tolerance,
gstate->antialias,
_gstate_get_clip (gstate, &clip));
_cairo_clip_fini (&clip);
return status;
return _cairo_surface_stroke (gstate->target,
gstate->op,
&source_pattern.base,
path,
&style,
&gstate->ctm,
&gstate->ctm_inverse,
gstate->tolerance,
gstate->antialias,
gstate->clip);
}
cairo_status_t
@ -1251,7 +1204,6 @@ BAIL:
cairo_status_t
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
cairo_clip_t clip;
cairo_status_t status;
status = _cairo_gstate_get_pattern_status (gstate->source);
@ -1261,7 +1213,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
if (gstate->op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
if (_clipped (gstate))
if (_cairo_clip_is_all_clipped (gstate->clip))
return CAIRO_STATUS_SUCCESS;
assert (gstate->opacity == 1.0);
@ -1273,7 +1225,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
status = _cairo_surface_paint (gstate->target,
CAIRO_OPERATOR_CLEAR,
&_cairo_pattern_clear.base,
_gstate_get_clip (gstate, &clip));
gstate->clip);
} else {
cairo_pattern_union_t source_pattern;
const cairo_pattern_t *pattern;
@ -1298,7 +1250,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
box.p2.y >= _cairo_fixed_from_int (extents.y + extents.height))
{
status = _cairo_surface_paint (gstate->target, op, pattern,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
else
{
@ -1307,12 +1259,10 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
gstate->fill_rule,
gstate->tolerance,
gstate->antialias,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
}
_cairo_clip_fini (&clip);
return status;
}
@ -1335,32 +1285,46 @@ _cairo_gstate_in_clip (cairo_gstate_t *gstate,
double x,
double y)
{
cairo_clip_path_t *clip_path;
cairo_clip_t *clip = gstate->clip;
int i;
if (gstate->clip.all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
clip_path = gstate->clip.path;
if (clip_path == NULL)
return TRUE;
_cairo_gstate_user_to_backend (gstate, &x, &y);
if (x < clip_path->extents.x ||
x >= clip_path->extents.x + clip_path->extents.width ||
y < clip_path->extents.y ||
y >= clip_path->extents.y + clip_path->extents.height)
if (x < clip->extents.x ||
x >= clip->extents.x + clip->extents.width ||
y < clip->extents.y ||
y >= clip->extents.y + clip->extents.height)
{
return FALSE;
}
do {
if (! _cairo_path_fixed_in_fill (&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
x, y))
if (clip->num_boxes) {
int fx, fy;
fx = _cairo_fixed_from_double (x);
fy = _cairo_fixed_from_double (y);
for (i = 0; i < clip->num_boxes; i++) {
if (fx >= clip->boxes[i].p1.x && fx <= clip->boxes[i].p2.x &&
fy >= clip->boxes[i].p1.y && fy <= clip->boxes[i].p2.y)
break;
}
if (i == clip->num_boxes)
return FALSE;
} while ((clip_path = clip_path->prev) != NULL);
}
if (clip->path) {
cairo_clip_path_t *clip_path = clip->path;
do {
if (! _cairo_path_fixed_in_fill (&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
x, y))
return FALSE;
} while ((clip_path = clip_path->prev) != NULL);
}
return TRUE;
}
@ -1500,7 +1464,8 @@ _cairo_gstate_fill_extents (cairo_gstate_t *gstate,
cairo_status_t
_cairo_gstate_reset_clip (cairo_gstate_t *gstate)
{
_cairo_clip_reset (&gstate->clip);
_cairo_clip_destroy (gstate->clip);
gstate->clip = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -1508,23 +1473,27 @@ _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
cairo_status_t
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
return _cairo_clip_clip (&gstate->clip,
path, gstate->fill_rule,
gstate->tolerance, gstate->antialias);
gstate->clip =
_cairo_clip_intersect_path (gstate->clip,
path,
gstate->fill_rule,
gstate->tolerance,
gstate->antialias);
/* XXX */
return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
_cairo_gstate_int_clip_extents (cairo_gstate_t *gstate,
cairo_rectangle_int_t *extents)
{
const cairo_rectangle_int_t *clip_extents;
cairo_bool_t is_bounded;
is_bounded = _cairo_surface_get_extents (gstate->target, extents);
clip_extents = _cairo_clip_get_extents (&gstate->clip);
if (clip_extents != NULL) {
_cairo_rectangle_intersect (extents, clip_extents);
if (gstate->clip) {
_cairo_rectangle_intersect (extents,
_cairo_clip_get_extents (gstate->clip));
is_bounded = TRUE;
}
@ -1568,23 +1537,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
cairo_rectangle_list_t*
_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
{
cairo_clip_t clip;
cairo_rectangle_int_t extents;
cairo_rectangle_list_t *list;
cairo_status_t status;
_cairo_clip_init_copy (&clip, &gstate->clip);
cairo_clip_t *clip;
if (_cairo_surface_get_extents (gstate->target, &extents))
status = _cairo_clip_rectangle (&clip, &extents);
clip = _cairo_clip_copy_intersect_rectangle (gstate->clip, &extents);
else
status = CAIRO_STATUS_SUCCESS;
clip = gstate->clip;
if (unlikely (status))
return _cairo_rectangle_list_create_in_error (status);
list = _cairo_clip_copy_rectangle_list (clip, gstate);
list = _cairo_clip_copy_rectangle_list (&clip, gstate);
_cairo_clip_fini (&clip);
if (clip != gstate->clip)
_cairo_clip_destroy (clip);
return list;
}
@ -1875,7 +1840,6 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
cairo_text_cluster_t *transformed_clusters = NULL;
cairo_operator_t op;
cairo_status_t status;
cairo_clip_t clip;
status = _cairo_gstate_get_pattern_status (gstate->source);
if (unlikely (status))
@ -1884,7 +1848,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (gstate->op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
if (_clipped (gstate))
if (_cairo_clip_is_all_clipped (gstate->clip))
return CAIRO_STATUS_SUCCESS;
status = _cairo_gstate_ensure_scaled_font (gstate);
@ -1958,14 +1922,14 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
transformed_clusters, info->num_clusters,
info->cluster_flags,
gstate->scaled_font,
_gstate_get_clip (gstate, &clip));
gstate->clip);
} else {
status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern,
NULL, 0,
transformed_glyphs, num_glyphs,
NULL, 0, 0,
gstate->scaled_font,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
}
else
@ -1984,14 +1948,12 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
CAIRO_FILL_RULE_WINDING,
gstate->tolerance,
gstate->scaled_font->options.antialias,
_gstate_get_clip (gstate, &clip));
gstate->clip);
}
_cairo_path_fixed_fini (&path);
}
_cairo_clip_fini (&clip);
CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
cairo_glyph_free (transformed_glyphs);

View file

@ -34,6 +34,8 @@
*/
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-image-info-private.h"
static uint32_t

View file

@ -77,16 +77,6 @@
* @Since: 1.8
*/
static cairo_int_status_t
_cairo_image_surface_fill (void *dst,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
static pixman_image_t *
_pixman_image_for_solid (const cairo_solid_pattern_t *pattern);
@ -113,6 +103,7 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
return CAIRO_FORMAT_A1;
case PIXMAN_r5g6b5:
return CAIRO_FORMAT_RGB16_565;
case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8: case PIXMAN_b5g6r5:
case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
@ -181,6 +172,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
surface->stride = pixman_image_get_stride (pixman_image);
surface->depth = pixman_image_get_depth (pixman_image);
surface->base.is_clear = width == 0 || height == 0;
return &surface->base;
}
@ -1099,7 +1092,7 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
cairo_circle_double_t extremes[2];
pixman_point_fixed_t p1, p2;
unsigned int i;
cairo_status_t status;
cairo_int_status_t status;
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
pixman_stops = _cairo_malloc_ab (pattern->n_stops,
@ -1150,7 +1143,7 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
extents->y + extents->height/2.,
&pixman_transform, ix, iy);
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
if (unlikely (status != CAIRO_STATUS_SUCCESS) ||
if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
! pixman_image_set_transform (pixman_image, &pixman_transform))
{
pixman_image_unref (pixman_image);
@ -1328,7 +1321,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
cairo_rectangle_int_t sample;
cairo_extend_t extend;
cairo_filter_t filter;
cairo_status_t status;
cairo_int_status_t status;
cairo_bool_t undo_src_transform = FALSE;
extend = pattern->base.extend;
@ -1529,7 +1522,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
* and we can use any filtering, so choose the fastest one. */
pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0);
}
else if (unlikely (status != CAIRO_STATUS_SUCCESS ||
else if (unlikely (status != CAIRO_INT_STATUS_SUCCESS ||
! pixman_image_set_transform (pixman_image,
&pixman_transform)))
{
@ -1795,7 +1788,7 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
_cairo_boxes_init (&tmp);
status = _cairo_boxes_add (&tmp, &box);
status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box);
assert (status == CAIRO_STATUS_SUCCESS);
tmp.chunks.next = &boxes->chunks;
@ -1812,12 +1805,14 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
pbox = pixman_region32_rectangles (&clip_region->rgn, &i);
_cairo_boxes_limit (&clear, (cairo_box_t *) pbox, i);
status = _cairo_boxes_add (&clear, &box);
status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box);
assert (status == CAIRO_STATUS_SUCCESS);
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
status = _cairo_boxes_add (&clear, &chunk->base[i]);
status = _cairo_boxes_add (&clear,
CAIRO_ANTIALIAS_DEFAULT,
&chunk->base[i]);
if (unlikely (status)) {
_cairo_boxes_fini (&clear);
return status;
@ -1885,7 +1880,7 @@ typedef cairo_status_t
const cairo_pattern_t *src,
int dst_x,
int dst_y,
cairo_matrix_t *dst_device_transform,
cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region);
@ -1896,23 +1891,13 @@ _create_composite_mask_pattern (cairo_clip_t *clip,
cairo_image_surface_t *dst,
const cairo_rectangle_int_t *extents)
{
cairo_region_t *clip_region = NULL;
cairo_region_t *clip_region = _cairo_clip_get_region (clip);
cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (clip);
pixman_image_t *mask;
cairo_status_t status;
cairo_bool_t need_clip_surface = FALSE;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
assert (! _cairo_status_is_error (status));
/* The all-clipped state should never propagate this far. */
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
}
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
mask = pixman_image_create_bits (PIXMAN_a8, extents->width, extents->height,
NULL, 0);
@ -1955,7 +1940,8 @@ _create_composite_mask_pattern (cairo_clip_t *clip,
pixman_image_ref (mask);
status = _cairo_clip_combine_with_surface (clip, tmp, extents->x, extents->y);
status = _cairo_clip_combine_with_surface (clip, tmp,
extents->x, extents->y);
cairo_surface_destroy (tmp);
if (unlikely (status)) {
pixman_image_unref (mask);
@ -2014,7 +2000,9 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
pixman_image_t *src;
int src_x, src_y;
src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
&dst->base.device_transform,
&src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2085,7 +2073,6 @@ _clip_and_composite_combine (cairo_clip_t *clip,
if (unlikely (status))
goto CLEANUP_SURFACE;
assert (clip->path != NULL);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;
@ -2156,7 +2143,6 @@ _clip_and_composite_source (cairo_clip_t *clip,
int src_x, src_y;
if (pattern == NULL) {
cairo_region_t *clip_region;
cairo_status_t status;
status = draw_func (draw_closure,
@ -2168,7 +2154,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
if (unlikely (status))
return status;
if (_cairo_clip_get_region (clip, &clip_region) == CAIRO_INT_STATUS_UNSUPPORTED)
if (! _cairo_clip_is_region (clip))
status = _cairo_clip_combine_with_surface (clip, &dst->base, 0, 0);
return status;
@ -2179,7 +2165,9 @@ _clip_and_composite_source (cairo_clip_t *clip,
if (unlikely (mask == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
&dst->base.device_transform,
&src_x, &src_y);
if (unlikely (src == NULL)) {
pixman_image_unref (mask);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2230,39 +2218,14 @@ _clip_and_composite (cairo_image_surface_t *dst,
const cairo_pattern_t *src,
image_draw_func_t draw_func,
void *draw_closure,
cairo_composite_rectangles_t*extents,
cairo_clip_t *clip)
cairo_composite_rectangles_t*extents)
{
cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (extents->clip);
cairo_status_t status;
cairo_region_t *clip_region = NULL;
cairo_bool_t need_clip_surface = FALSE;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
if (unlikely (_cairo_status_is_error (status)))
return status;
need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
if (clip_region != NULL) {
cairo_rectangle_int_t rect;
cairo_bool_t is_empty;
cairo_region_get_extents (clip_region, &rect);
is_empty = ! _cairo_rectangle_intersect (&extents->unbounded, &rect);
if (unlikely (is_empty))
return CAIRO_STATUS_SUCCESS;
is_empty = ! _cairo_rectangle_intersect (&extents->bounded, &rect);
if (unlikely (is_empty && extents->is_bounded))
return CAIRO_STATUS_SUCCESS;
if (cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
}
}
if (cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
if (clip_region != NULL) {
status = _cairo_image_surface_set_clip_region (dst, clip_region);
@ -2276,7 +2239,7 @@ _clip_and_composite (cairo_image_surface_t *dst,
}
if (op == CAIRO_OPERATOR_SOURCE) {
status = _clip_and_composite_source (clip, src,
status = _clip_and_composite_source (extents->clip, src,
draw_func, draw_closure,
dst, &extents->bounded);
} else {
@ -2287,11 +2250,11 @@ _clip_and_composite (cairo_image_surface_t *dst,
if (need_clip_surface) {
if (extents->is_bounded) {
status = _clip_and_composite_with_mask (clip, op, src,
status = _clip_and_composite_with_mask (extents->clip, op, src,
draw_func, draw_closure,
dst, &extents->bounded);
} else {
status = _clip_and_composite_combine (clip, op, src,
status = _clip_and_composite_combine (extents->clip, op, src,
draw_func, draw_closure,
dst, &extents->bounded);
}
@ -2308,7 +2271,7 @@ _clip_and_composite (cairo_image_surface_t *dst,
if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) {
status = _cairo_image_surface_fixup_unbounded (dst, extents,
need_clip_surface ? clip : NULL);
need_clip_surface ? extents->clip : NULL);
}
if (clip_region != NULL)
@ -2444,7 +2407,9 @@ _composite_traps (void *closure,
return CAIRO_STATUS_SUCCESS;
}
src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2856,7 +2821,9 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
if (unlikely (status))
goto CLEANUP;
src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded,
&dst->base.device_transform,
&src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
@ -2882,44 +2849,36 @@ _composite_boxes (cairo_image_surface_t *dst,
cairo_operator_t op,
const cairo_pattern_t *pattern,
cairo_boxes_t *boxes,
cairo_antialias_t antialias,
cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents)
{
cairo_region_t *clip_region = NULL;
cairo_bool_t need_clip_mask = FALSE;
cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
cairo_bool_t need_clip_mask = extents->clip->path != NULL;
cairo_status_t status;
struct _cairo_boxes_chunk *chunk;
uint32_t pixel;
int i;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
need_clip_mask = status == CAIRO_INT_STATUS_UNSUPPORTED;
if (need_clip_mask &&
(op == CAIRO_OPERATOR_SOURCE || ! extents->is_bounded))
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
if (need_clip_mask &&
(op == CAIRO_OPERATOR_SOURCE || ! extents->is_bounded))
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (antialias != CAIRO_ANTIALIAS_NONE) {
if (! boxes->is_pixel_aligned) {
if (need_clip_mask)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
if (pattern_to_pixel ((cairo_solid_pattern_t *) pattern, op,
dst->pixman_format, &pixel))
{
return _fill_unaligned_boxes (dst, pattern, pixel, boxes, extents);
}
else
{
return _composite_unaligned_boxes (dst, op, pattern, boxes, extents);
}
if (! boxes->is_pixel_aligned) {
if (need_clip_mask)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (pattern_to_pixel ((cairo_solid_pattern_t *) pattern, op,
dst->pixman_format, &pixel))
{
return _fill_unaligned_boxes (dst, pattern, pixel, boxes, extents);
}
else
{
return _composite_unaligned_boxes (dst, op, pattern, boxes, extents);
}
}
@ -2957,7 +2916,9 @@ _composite_boxes (cairo_image_surface_t *dst,
cairo_surface_t *clip_surface;
int clip_x, clip_y;
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
clip_surface = _cairo_clip_get_surface (extents->clip,
&dst->base,
&clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;
@ -2970,10 +2931,14 @@ _composite_boxes (cairo_image_surface_t *dst,
}
mask = ((cairo_image_surface_t *) clip_surface)->pixman_image;
pixman_image_ref (mask);
cairo_surface_destroy (clip_surface);
}
if (pattern != NULL) {
src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded,
&dst->base.device_transform,
&src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
@ -3022,19 +2987,17 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
cairo_operator_t op,
const cairo_pattern_t *src,
cairo_boxes_t *boxes,
cairo_antialias_t antialias,
cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
cairo_composite_rectangles_t *extents)
{
cairo_traps_t traps;
cairo_status_t status;
cairo_int_status_t status;
composite_traps_info_t info;
if (boxes->num_boxes == 0 && extents->is_bounded)
return CAIRO_STATUS_SUCCESS;
/* Use a fast path if the boxes are pixel aligned */
status = _composite_boxes (dst, op, src, boxes, antialias, clip, extents);
status = _composite_boxes (dst, op, src, boxes, extents);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
@ -3045,10 +3008,10 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
info.num_traps = traps.num_traps;
info.traps = traps.traps;
info.antialias = antialias;
info.antialias = CAIRO_ANTIALIAS_DEFAULT;
status = _clip_and_composite (dst, op, src,
_composite_traps, &info,
extents, clip);
extents);
_cairo_traps_fini (&traps);
return status;
@ -3151,8 +3114,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
const cairo_pattern_t *src,
cairo_traps_t *traps,
cairo_antialias_t antialias,
cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
cairo_composite_rectangles_t *extents)
{
composite_traps_info_t info;
cairo_bool_t need_clip_surface = FALSE;
@ -3161,12 +3123,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
if (traps->num_traps == 0 && extents->is_bounded)
return CAIRO_STATUS_SUCCESS;
if (clip != NULL) {
cairo_region_t *clip_region;
status = _cairo_clip_get_region (clip, &clip_region);
need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
}
need_clip_surface = ! _cairo_clip_is_region (extents->clip);
if (traps->has_intersections) {
if (traps->is_rectangular)
@ -3191,8 +3148,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
_boxes_for_traps (&boxes, traps, antialias);
return _clip_and_composite_boxes (dst, op, src,
&boxes, antialias,
extents, clip);
&boxes, extents);
}
/* No fast path, exclude self-intersections and clip trapezoids. */
@ -3204,27 +3160,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
info.antialias = antialias;
return _clip_and_composite (dst, op, src,
_composite_traps, &info,
extents, clip);
}
static cairo_clip_path_t *
_clip_get_single_path (cairo_clip_t *clip)
{
cairo_clip_path_t *iter = clip->path;
cairo_clip_path_t *path = NULL;
/* Boxes only effect the extents, so discard any outer boxes. */
do {
if (path != NULL)
return FALSE;
if ((iter->flags & CAIRO_CLIP_PATH_IS_BOX) == 0)
path = iter;
iter = iter->prev;
} while (iter != NULL);
return path;
extents);
}
/* high level image interface */
@ -3233,16 +3169,12 @@ static cairo_int_status_t
_cairo_image_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_clip_path_t *clip_path;
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_status_t status;
cairo_boxes_t boxes;
status = _cairo_composite_rectangles_init_for_paint (&extents,
surface->width,
@ -3252,53 +3184,20 @@ _cairo_image_surface_paint (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
clip = _cairo_clip_init_copy (&local_clip, clip);
have_clip = TRUE;
}
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
return status;
}
/* If the clip cannot be reduced to a set of boxes, we will need to
* use a clipmask. Paint is special as it is the only operation that
* does not implicitly use a mask, so we may be able to reduce this
* operation to a fill...
*/
if (clip != NULL &&
extents.is_bounded &&
(clip_path = _clip_get_single_path (clip)) != NULL)
{
status = _cairo_image_surface_fill (surface, op, source,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
NULL);
}
else
{
cairo_boxes_t boxes;
_cairo_boxes_init_for_array (&boxes, clip_boxes, num_boxes);
status = _cairo_clip_to_boxes (extents.clip, &boxes);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _clip_and_composite_boxes (surface, op, source,
&boxes, CAIRO_ANTIALIAS_DEFAULT,
&extents, clip);
&boxes, &extents);
_cairo_boxes_fini (&boxes);
}
if (clip_boxes != boxes_stack)
free (clip_boxes);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -3311,7 +3210,7 @@ _composite_mask (void *closure,
const cairo_pattern_t *src_pattern,
int dst_x,
int dst_y,
cairo_matrix_t *dst_device_transform,
cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@ -3321,11 +3220,15 @@ _composite_mask (void *closure,
int mask_x = 0, mask_y = 0;
if (src_pattern != NULL) {
src = _pixman_image_for_pattern (src_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (src_pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, dst_device_transform, &mask_x, &mask_y);
mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents,
dst_device_transform,
&mask_x, &mask_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3334,7 +3237,9 @@ _composite_mask (void *closure,
if (mask_pattern->has_component_alpha)
pixman_image_set_component_alpha (mask, TRUE);
} else {
src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (mask_pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -3357,12 +3262,10 @@ _cairo_image_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
cairo_status_t status;
status = _cairo_composite_rectangles_init_for_mask (&extents,
@ -3371,26 +3274,11 @@ _cairo_image_surface_mask (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
clip = _cairo_clip_init_copy (&local_clip, clip);
status = _cairo_clip_rectangle (clip, &extents.bounded);
if (unlikely (status)) {
_cairo_clip_fini (&local_clip);
return status;
}
have_clip = TRUE;
}
status = _clip_and_composite (surface, op, source,
_composite_mask, (void *) mask,
&extents, clip);
&extents);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -3410,7 +3298,7 @@ _composite_spans (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
cairo_matrix_t *dst_device_transform,
cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@ -3494,7 +3382,9 @@ _composite_spans (void *closure,
pixman_image_t *src;
int src_x, src_y;
src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
if (unlikely (src == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_RENDERER;
@ -3527,8 +3417,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
cairo_composite_rectangles_t *extents)
{
cairo_status_t status;
@ -3541,7 +3430,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
_cairo_traps_init (&traps);
status = _clip_and_composite_trapezoids (dst, op, src,
&traps, antialias,
extents, clip);
extents);
_cairo_traps_fini (&traps);
return status;
@ -3560,7 +3449,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
status = _clip_and_composite (dst, op, src,
_composite_spans, &info,
extents, clip);
extents);
} else {
cairo_traps_t traps;
@ -3573,7 +3462,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _clip_and_composite_trapezoids (dst, op, src,
&traps, antialias,
extents, clip);
extents);
}
_cairo_traps_fini (&traps);
@ -3586,21 +3475,17 @@ static cairo_int_status_t
_cairo_image_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_composite_rectangles_init_for_stroke (&extents,
surface->width,
@ -3611,80 +3496,42 @@ _cairo_image_surface_stroke (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
clip = _cairo_clip_init_copy (&local_clip, clip);
have_clip = TRUE;
}
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
return status;
}
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
if (num_boxes == 0) {
/* When compositing with the span renderer, we limit the mask
* to the bounded area, and so we must also constrain the path
* appropriately. (Unlike the other compositing paths
* where the operation itself is limited to extents.)
*/
boxes_stack[0].p1.x = extents.bounded.x;
boxes_stack[0].p1.y = extents.bounded.y;
boxes_stack[0].p2.x = extents.bounded.x + extents.bounded.width;
boxes_stack[0].p2.y = extents.bounded.y + extents.bounded.height;
clip_boxes = boxes_stack;
num_boxes = 1;
}
_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
_cairo_boxes_init_with_clip (&boxes, extents.clip);
status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
style,
ctm,
antialias,
&boxes);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
status = _clip_and_composite_boxes (surface, op, source,
&boxes, antialias,
&extents, clip);
&boxes, &extents);
}
_cairo_boxes_fini (&boxes);
}
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_polygon_t polygon;
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
status = _cairo_path_fixed_stroke_to_polygon (path,
style,
ctm, ctm_inverse,
tolerance,
&polygon);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
status = _clip_and_composite_polygon (surface, op, source, &polygon,
CAIRO_FILL_RULE_WINDING, antialias,
&extents, clip);
CAIRO_FILL_RULE_WINDING,
antialias,
&extents);
}
_cairo_polygon_fini (&polygon);
}
if (clip_boxes != boxes_stack)
free (clip_boxes);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -3693,18 +3540,14 @@ static cairo_int_status_t
_cairo_image_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_status_t status;
status = _cairo_composite_rectangles_init_for_fill (&extents,
@ -3715,84 +3558,35 @@ _cairo_image_surface_fill (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (extents.is_bounded && clip != NULL) {
cairo_clip_path_t *clip_path;
if (((clip_path = _clip_get_single_path (clip)) != NULL) &&
_cairo_path_fixed_equal (&clip_path->path, path))
{
clip = NULL;
}
}
if (clip != NULL) {
clip = _cairo_clip_init_copy (&local_clip, clip);
have_clip = TRUE;
}
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
return status;
}
if (_cairo_path_fixed_fill_is_rectilinear (path)) {
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
if (num_boxes == 0) {
/* When compositing with the span renderer, we limit the mask
* to the bounded area, and so we must also constrain the path
* appropriately. (Unlike the other compositing paths
* where the operation itself is limited to extents.)
*/
boxes_stack[0].p1.x = extents.bounded.x;
boxes_stack[0].p1.y = extents.bounded.y;
boxes_stack[0].p2.x = extents.bounded.x + extents.bounded.width;
boxes_stack[0].p2.y = extents.bounded.y + extents.bounded.height;
clip_boxes = boxes_stack;
num_boxes = 1;
}
_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
_cairo_boxes_init_with_clip (&boxes, extents.clip);
status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
fill_rule,
antialias,
&boxes);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _clip_and_composite_boxes (surface, op, source,
&boxes, antialias,
&extents, clip);
&boxes, &extents);
}
_cairo_boxes_fini (&boxes);
} else {
cairo_polygon_t polygon;
assert (! _cairo_path_fixed_fill_is_empty (path));
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _clip_and_composite_polygon (surface, op, source, &polygon,
fill_rule, antialias,
&extents, clip);
&extents);
}
_cairo_polygon_fini (&polygon);
}
if (clip_boxes != boxes_stack)
free (clip_boxes);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -3811,7 +3605,7 @@ _composite_glyphs_via_mask (void *closure,
const cairo_pattern_t *pattern,
int dst_x,
int dst_y,
cairo_matrix_t *dst_device_transform,
cairo_matrix_t *dst_device_transform,
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region)
{
@ -3827,7 +3621,9 @@ _composite_glyphs_via_mask (void *closure,
int src_x, src_y;
int i;
src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3961,7 +3757,9 @@ _composite_glyphs (void *closure,
int i;
if (pattern != NULL) {
src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (pattern, FALSE, extents,
dst_device_transform,
&src_x, &src_y);
src_x -= dst_x;
src_y -= dst_y;
} else {
@ -4042,16 +3840,14 @@ _cairo_image_surface_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *num_remaining)
{
cairo_image_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
composite_glyphs_info_t glyph_info;
cairo_clip_t local_clip;
cairo_bool_t have_clip = FALSE;
cairo_bool_t overlap;
cairo_status_t status;
cairo_bool_t overlap;
status = _cairo_composite_rectangles_init_for_glyphs (&extents,
surface->width,
@ -4064,20 +3860,6 @@ _cairo_image_surface_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
clip = _cairo_clip_init_copy (&local_clip, clip);
status = _cairo_clip_rectangle (clip, &extents.bounded);
if (unlikely (status)) {
_cairo_clip_fini (&local_clip);
return status;
}
have_clip = TRUE;
}
glyph_info.font = scaled_font;
glyph_info.glyphs = glyphs;
glyph_info.num_glyphs = num_glyphs;
@ -4085,10 +3867,9 @@ _cairo_image_surface_glyphs (void *abstract_surface,
status = _clip_and_composite (surface, op, source,
overlap || extents.is_bounded == 0 ? _composite_glyphs_via_mask : _composite_glyphs,
&glyph_info,
&extents, clip);
&extents);
if (have_clip)
_cairo_clip_fini (&local_clip);
_cairo_composite_rectangles_fini (&extents);
*num_remaining = 0;
return status;
@ -4228,7 +4009,9 @@ _cairo_image_surface_composite (cairo_operator_t op,
extents.is_bounded = _cairo_operator_bounded_by_either (op);
src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &dst->base.device_transform, &src_offset_x, &src_offset_y);
src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source,
&dst->base.device_transform,
&src_offset_x, &src_offset_y);
if (unlikely (src == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -4237,7 +4020,9 @@ _cairo_image_surface_composite (cairo_operator_t op,
pixman_image_t *mask;
int mask_offset_x, mask_offset_y;
mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &dst->base.device_transform, &mask_offset_x, &mask_offset_y);
mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask,
&dst->base.device_transform,
&mask_offset_x, &mask_offset_y);
if (unlikely (mask == NULL)) {
pixman_image_unref (src);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -4507,7 +4292,9 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
return status;
}
src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &renderer->dst->base.device_transform, &src_x, &src_y);
src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded,
&renderer->dst->base.device_transform,
&src_x, &src_y);
if (src == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -41,7 +41,7 @@
#include "cairoint.h"
#include "cairo-error-private.h"
COMPILE_TIME_ASSERT (CAIRO_STATUS_LAST_STATUS < CAIRO_INT_STATUS_UNSUPPORTED);
COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
/**

View file

@ -279,7 +279,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
cairo_status_t status;
cairo_surface_t *image;
cairo_surface_pattern_t pattern;
cairo_clip_t clip;
cairo_clip_t *clip;
x = rect->x;
y = rect->y;
@ -304,15 +304,14 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
* filtering (if possible) to avoid introducing potential artifacts. */
pattern.base.filter = CAIRO_FILTER_NEAREST;
_cairo_clip_init (&clip);
status = _cairo_clip_rectangle (&clip, rect);
clip = _cairo_clip_intersect_rectangle (NULL, rect);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status = _cairo_surface_paint (surface->target,
CAIRO_OPERATOR_SOURCE,
&pattern.base, &clip);
&pattern.base, clip);
}
_cairo_clip_fini (&clip);
_cairo_clip_destroy (clip);
_cairo_pattern_fini (&pattern.base);
CLEANUP_IMAGE:
@ -325,7 +324,7 @@ static cairo_int_status_t
_paint_page (cairo_paginated_surface_t *surface)
{
cairo_surface_t *analysis;
cairo_status_t status;
cairo_int_status_t status;
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
if (unlikely (surface->target->status))
@ -340,7 +339,7 @@ _paint_page (cairo_paginated_surface_t *surface)
status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
analysis);
if (status || analysis->status) {
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = analysis->status;
goto FAIL;
}
@ -542,7 +541,7 @@ static cairo_int_status_t
_cairo_paginated_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_paginated_surface_t *surface = abstract_surface;
@ -554,7 +553,7 @@ _cairo_paginated_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_paginated_surface_t *surface = abstract_surface;
@ -565,13 +564,13 @@ static cairo_int_status_t
_cairo_paginated_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_paginated_surface_t *surface = abstract_surface;
@ -586,11 +585,11 @@ static cairo_int_status_t
_cairo_paginated_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_paginated_surface_t *surface = abstract_surface;
@ -620,7 +619,7 @@ _cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_paginated_surface_t *surface = abstract_surface;

View file

@ -37,6 +37,7 @@
#include "cairoint.h"
#include "cairo-box-private.h"
#include "cairo-error-private.h"
#include "cairo-path-fixed-private.h"

View file

@ -120,6 +120,86 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path,
return _cairo_filler_close (&filler);
}
typedef struct cairo_filler_rectilinear_aligned {
cairo_polygon_t *polygon;
cairo_point_t current_point;
cairo_point_t last_move_to;
} cairo_filler_ra_t;
static cairo_status_t
_cairo_filler_ra_line_to (void *closure,
const cairo_point_t *point)
{
cairo_filler_ra_t *filler = closure;
cairo_status_t status;
cairo_point_t p;
p.x = _cairo_fixed_round_down (point->x);
p.y = _cairo_fixed_round_down (point->y);
status = _cairo_polygon_add_external_edge (filler->polygon,
&filler->current_point,
&p);
filler->current_point = p;
return status;
}
static cairo_status_t
_cairo_filler_ra_move_to (void *closure,
const cairo_point_t *point)
{
cairo_filler_t *filler = closure;
cairo_status_t status;
cairo_point_t p;
/* close current subpath */
status = _cairo_filler_close (closure);
if (unlikely (status))
return status;
p.x = _cairo_fixed_round_down (point->x);
p.y = _cairo_fixed_round_down (point->y);
/* make sure that the closure represents a degenerate path */
filler->current_point = p;
filler->last_move_to = p;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path,
cairo_antialias_t antialias,
cairo_polygon_t *polygon)
{
cairo_filler_ra_t filler;
cairo_status_t status;
if (antialias != CAIRO_ANTIALIAS_NONE)
return _cairo_path_fixed_fill_to_polygon (path, 0., polygon);
filler.polygon = polygon;
/* make sure that the closure represents a degenerate path */
filler.current_point.x = 0;
filler.current_point.y = 0;
filler.last_move_to = filler.current_point;
status = _cairo_path_fixed_interpret_flat (path,
_cairo_filler_ra_move_to,
_cairo_filler_ra_line_to,
_cairo_filler_close,
&filler,
0.);
if (unlikely (status))
return status;
return _cairo_filler_close (&filler);
}
cairo_status_t
_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
@ -170,12 +250,15 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
_cairo_traps_init (&traps);
status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
fill_rule,
CAIRO_ANTIALIAS_NONE,
&traps);
if (_cairo_status_is_error (status))
goto CLEANUP_TRAPS;
if (status == CAIRO_STATUS_SUCCESS) {
status = _cairo_traps_extract_region (&traps, &region);
status = _cairo_traps_extract_region (&traps,
CAIRO_ANTIALIAS_NONE,
&region);
goto CLEANUP_TRAPS;
}
@ -200,7 +283,9 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
&polygon,
fill_rule);
if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_traps_extract_region (&traps, &region);
status = _cairo_traps_extract_region (&traps,
CAIRO_ANTIALIAS_NONE,
&region);
}
CLEANUP_POLYGON:
@ -338,6 +423,7 @@ TESSELLATE:
cairo_int_status_t
_cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_traps_t *traps)
{
cairo_box_t box;
@ -347,6 +433,12 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
traps->is_rectangular = TRUE;
if (_cairo_path_fixed_is_box (path, &box)) {
if (antialias == CAIRO_ANTIALIAS_NONE) {
box.p1.x = _cairo_fixed_round_down (box.p1.x);
box.p1.y = _cairo_fixed_round_down (box.p1.y);
box.p2.x = _cairo_fixed_round_down (box.p2.x);
box.p2.y = _cairo_fixed_round_down (box.p2.y);
}
return _cairo_traps_tessellate_rectangle (traps, &box.p1, &box.p2);
} else {
cairo_path_fixed_iter_t iter;
@ -365,6 +457,13 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
box.p2.x = t;
}
if (antialias == CAIRO_ANTIALIAS_NONE) {
box.p1.x = _cairo_fixed_round_down (box.p1.x);
box.p1.y = _cairo_fixed_round_down (box.p1.y);
box.p2.x = _cairo_fixed_round_down (box.p2.x);
box.p2.y = _cairo_fixed_round_down (box.p2.y);
}
status = _cairo_traps_tessellate_rectangle (traps,
&box.p1, &box.p2);
if (unlikely (status)) {
@ -384,6 +483,7 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
static cairo_status_t
_cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_boxes_t *boxes)
{
cairo_polygon_t polygon;
@ -393,7 +493,7 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t
boxes->num_limits = 0;
/* tolerance will be ignored as the path is rectilinear */
status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon);
status = _cairo_path_fixed_fill_rectilinear_to_polygon (path, antialias, &polygon);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
status =
_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (&polygon,
@ -409,6 +509,7 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t
cairo_status_t
_cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_boxes_t *boxes)
{
cairo_path_fixed_iter_t iter;
@ -416,7 +517,7 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
cairo_box_t box;
if (_cairo_path_fixed_is_box (path, &box))
return _cairo_boxes_add (boxes, &box);
return _cairo_boxes_add (boxes, antialias, &box);
_cairo_path_fixed_iter_init (&iter, path);
while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
@ -435,7 +536,7 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
box.p2.x = t;
}
status = _cairo_boxes_add (boxes, &box);
status = _cairo_boxes_add (boxes, antialias, &box);
if (unlikely (status))
return status;
}
@ -447,5 +548,6 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
_cairo_boxes_clear (boxes);
return _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (path,
fill_rule,
antialias,
boxes);
}

View file

@ -1402,6 +1402,7 @@ _cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path,
status = _cairo_path_fixed_stroke_rectilinear_to_traps (path,
stroke_style,
ctm,
CAIRO_ANTIALIAS_DEFAULT,
traps);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
@ -1440,6 +1441,7 @@ typedef struct _segment_t {
typedef struct _cairo_rectilinear_stroker {
const cairo_stroke_style_t *stroke_style;
const cairo_matrix_t *ctm;
cairo_antialias_t antialias;
cairo_fixed_t half_line_width;
cairo_bool_t do_traps;
@ -1478,6 +1480,7 @@ static cairo_bool_t
_cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
cairo_antialias_t antialias,
cairo_bool_t do_traps,
void *container)
{
@ -1512,6 +1515,7 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker,
stroker->stroke_style = stroke_style;
stroker->ctm = ctm;
stroker->antialias = antialias;
stroker->half_line_width =
_cairo_fixed_from_double (stroke_style->line_width / 2.0);
@ -1687,6 +1691,12 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
}
if (stroker->do_traps) {
if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
a->x = _cairo_fixed_round_down (a->x);
a->y = _cairo_fixed_round_down (a->y);
b->x = _cairo_fixed_round_down (b->x);
b->y = _cairo_fixed_round_down (b->y);
}
status = _cairo_traps_tessellate_rectangle (stroker->container, a, b);
} else {
cairo_box_t box;
@ -1694,7 +1704,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
box.p1 = *a;
box.p2 = *b;
status = _cairo_boxes_add (stroker->container, &box);
status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
}
if (unlikely (status))
return status;
@ -1762,6 +1772,12 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
}
if (stroker->do_traps) {
if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
p1.x = _cairo_fixed_round_down (p1.x);
p1.y = _cairo_fixed_round_down (p1.y);
p2.x = _cairo_fixed_round_down (p2.x);
p2.y = _cairo_fixed_round_down (p2.y);
}
status = _cairo_traps_tessellate_rectangle (stroker->container, &p1, &p2);
} else {
cairo_box_t box;
@ -1769,7 +1785,7 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
box.p1 = p1;
box.p2 = p2;
status = _cairo_boxes_add (stroker->container, &box);
status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
}
if (unlikely (status))
return status;
@ -1824,6 +1840,12 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
continue;
if (stroker->do_traps) {
if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
a->x = _cairo_fixed_round_down (a->x);
a->y = _cairo_fixed_round_down (a->y);
b->x = _cairo_fixed_round_down (b->x);
b->y = _cairo_fixed_round_down (b->y);
}
status = _cairo_traps_tessellate_rectangle (stroker->container, a, b);
} else {
cairo_box_t box;
@ -1831,7 +1853,7 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
box.p1 = *a;
box.p2 = *b;
status = _cairo_boxes_add (stroker->container, &box);
status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
}
if (unlikely (status))
return status;
@ -2029,6 +2051,7 @@ cairo_int_status_t
_cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
cairo_antialias_t antialias,
cairo_traps_t *traps)
{
cairo_rectilinear_stroker_t rectilinear_stroker;
@ -2037,7 +2060,7 @@ _cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t *path,
assert (_cairo_path_fixed_stroke_is_rectilinear (path));
if (! _cairo_rectilinear_stroker_init (&rectilinear_stroker,
stroke_style, ctm,
stroke_style, ctm, antialias,
TRUE, traps))
{
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -2082,6 +2105,7 @@ cairo_int_status_t
_cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
cairo_antialias_t antialias,
cairo_boxes_t *boxes)
{
cairo_rectilinear_stroker_t rectilinear_stroker;
@ -2090,7 +2114,7 @@ _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path,
assert (_cairo_path_fixed_stroke_is_rectilinear (path));
if (! _cairo_rectilinear_stroker_init (&rectilinear_stroker,
stroke_style, ctm,
stroke_style, ctm, antialias,
FALSE, boxes))
{
return CAIRO_INT_STATUS_UNSUPPORTED;

View file

@ -2118,7 +2118,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
pixman_transform_t pixman_transform;
cairo_circle_double_t extremes[2];
pixman_point_fixed_t p1, p2;
cairo_status_t status;
cairo_int_status_t status;
cairo_bool_t repeat = FALSE;
int ix, iy;
pixman_gradient_stop_t pixman_stops_static[2];
@ -2241,7 +2241,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
&pixman_transform,
&ix, &iy);
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
if (unlikely (status != CAIRO_STATUS_SUCCESS) ||
if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
! pixman_image_set_transform (pixman_image, &pixman_transform))
{
cairo_surface_destroy (&image->base);

View file

@ -129,8 +129,8 @@ cairo_private void
_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators);
cairo_private cairo_int_status_t
_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule);
cairo_private cairo_int_status_t
@ -140,19 +140,19 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
cairo_private cairo_int_status_t
_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse);
cairo_private cairo_int_status_t
_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule);
_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule);
cairo_private cairo_int_status_t
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,

View file

@ -493,7 +493,7 @@ _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
*/
static cairo_status_t
_cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_matrix_t *path_transform,
cairo_line_cap_t line_cap)
{
@ -530,7 +530,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
cairo_int_status_t
_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule)
{
const char *pdf_operator;
@ -763,7 +763,7 @@ _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
static cairo_int_status_t
_cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
@ -854,7 +854,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_int_status_t
_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse)
@ -869,7 +869,7 @@ _cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_int_status_t
_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule)
{
const char *pdf_operator;
@ -908,7 +908,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
cairo_int_status_t
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,

View file

@ -1089,12 +1089,12 @@ _get_jpeg_image_info (cairo_surface_t *source,
return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length);
}
static cairo_status_t
static cairo_int_status_t
_get_source_surface_size (cairo_surface_t *source,
int *width,
int *height)
{
cairo_status_t status;
cairo_int_status_t status;
cairo_rectangle_int_t extents;
cairo_image_info_t info;
const unsigned char *mime_data;
@ -2184,12 +2184,12 @@ static cairo_status_t
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
cairo_surface_t *source,
cairo_pdf_resource_t resource,
cairo_bool_t interpolate,
cairo_bool_t interpolate,
cairo_bool_t mask)
{
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_pdf_surface_emit_jpx_image (surface, source, resource);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@ -2226,7 +2226,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
cairo_image_surface_t *image;
cairo_surface_t *pad_image;
void *image_extra;
cairo_status_t status;
cairo_int_status_t status;
cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
int x = 0;
int y = 0;
@ -2276,6 +2276,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
}
switch (pdf_pattern->pattern->filter) {
default:
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_BILINEAR:
@ -2323,7 +2324,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
cairo_paginated_mode_t old_paginated_mode;
cairo_rectangle_int_t recording_extents;
cairo_bool_t is_bounded;
cairo_status_t status;
cairo_int_status_t status;
int alpha = 0;
is_bounded = _cairo_surface_get_extents (recording_surface, &recording_extents);
@ -2384,7 +2385,7 @@ _cairo_pdf_surface_emit_recording_subsurface (cairo_pdf_surface_t *surface,
{
double old_width, old_height;
cairo_paginated_mode_t old_paginated_mode;
cairo_status_t status;
cairo_int_status_t status;
int alpha = 0;
old_width = surface->width;
@ -4351,6 +4352,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
if (_cairo_status_is_error (status))
return status;
last_glyph = font_subset->num_glyphs - 1;
if (font_subset->is_latin) {
/* find last glyph used */
for (i = 255; i >= 32; i--)
@ -4404,7 +4406,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
tag,
subset->base_font,
font_subset->is_latin ? 32 : 0,
font_subset->is_latin ? last_glyph : font_subset->num_glyphs - 1,
last_glyph,
descriptor.id);
if (font_subset->is_latin)
@ -4741,7 +4743,7 @@ _cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
return _cairo_output_stream_get_status (stream);
}
static cairo_status_t
static cairo_int_status_t
_cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@ -4781,7 +4783,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
return status;
}
static cairo_status_t
static cairo_int_status_t
_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
@ -4966,12 +4968,12 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
return _cairo_array_append (&surface->fonts, &font);
}
static cairo_status_t
static cairo_int_status_t
_cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
cairo_pdf_surface_t *surface = closure;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@ -4994,22 +4996,22 @@ _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_s
return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
cairo_pdf_surface_t *surface = closure;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
@ -5742,20 +5744,20 @@ static cairo_int_status_t
_cairo_pdf_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_pdf_smask_group_t *group;
cairo_pdf_resource_t pattern_res, gstate_res;
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
status = _cairo_composite_rectangles_init_for_paint (&extents,
surface->width, surface->height,
op, source, clip);
if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
return status;
}
@ -5859,12 +5861,12 @@ _cairo_pdf_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_smask_group_t *group;
cairo_status_t status;
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
status = _cairo_composite_rectangles_init_for_mask (&extents,
surface->width, surface->height,
@ -5966,19 +5968,19 @@ static cairo_int_status_t
_cairo_pdf_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_smask_group_t *group;
cairo_pdf_resource_t pattern_res, gstate_res;
cairo_composite_rectangles_t extents;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_composite_rectangles_init_for_stroke (&extents,
surface->width,
@ -5988,7 +5990,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
clip);
if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
return status;
}
@ -6003,7 +6005,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
return status;
if (! _cairo_rectangle_intersect (&extents.bounded, &extents.mask))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@ -6021,7 +6023,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
if (unlikely (status))
return status;
@ -6097,14 +6099,14 @@ static cairo_int_status_t
_cairo_pdf_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
cairo_pdf_smask_group_t *group;
cairo_pdf_resource_t pattern_res, gstate_res;
cairo_composite_rectangles_t extents;
@ -6116,7 +6118,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
clip);
if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
return status;
}
@ -6129,7 +6131,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
&extents.mask);
if (! _cairo_rectangle_intersect (&extents.bounded, &extents.mask))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
@ -6180,7 +6182,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
if (unlikely (status))
return status;
@ -6251,7 +6253,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_operator_t stroke_op,
const cairo_pattern_t *stroke_source,
const cairo_stroke_style_t *stroke_style,
@ -6259,10 +6261,10 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
cairo_pdf_resource_t fill_pattern_res, stroke_pattern_res, gstate_res;
cairo_composite_rectangles_t extents;
@ -6408,14 +6410,14 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_smask_group_t *group;
cairo_pdf_resource_t pattern_res, gstate_res;
cairo_composite_rectangles_t extents;
cairo_bool_t overlap;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_composite_rectangles_init_for_glyphs (&extents,
surface->width,
@ -6427,7 +6429,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
&overlap);
if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
return status;
}
@ -6447,7 +6449,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
if (unlikely (status))
return status;

View file

@ -169,7 +169,7 @@ write_png (cairo_surface_t *surface,
void *closure)
{
int i;
cairo_status_t status;
cairo_int_status_t status;
cairo_image_surface_t *image;
cairo_image_surface_t * volatile clone;
void *image_extra;

File diff suppressed because it is too large Load diff

1491
src/cairo-polygon-reduce.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -37,8 +37,14 @@
#include "cairoint.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
static void
_cairo_polygon_add_edge (cairo_polygon_t *polygon,
const cairo_point_t *p1,
const cairo_point_t *p2);
void
_cairo_polygon_init (cairo_polygon_t *polygon,
const cairo_box_t *limits,
@ -79,6 +85,111 @@ _cairo_polygon_init (cairo_polygon_t *polygon,
}
}
void
_cairo_polygon_init_with_clip (cairo_polygon_t *polygon,
const cairo_clip_t *clip)
{
if (clip)
_cairo_polygon_init (polygon, clip->boxes, clip->num_boxes);
else
_cairo_polygon_init (polygon, 0, 0);
}
cairo_status_t
_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
const cairo_boxes_t *boxes)
{
const struct _cairo_boxes_chunk *chunk;
int i;
VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
polygon->status = CAIRO_STATUS_SUCCESS;
polygon->num_edges = 0;
polygon->edges = polygon->edges_embedded;
polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
polygon->edges_size = 2 * boxes->num_boxes;
polygon->edges = _cairo_malloc_ab (polygon->edges_size,
2*sizeof(cairo_edge_t));
if (unlikely (polygon->edges == NULL))
return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;
polygon->limits = NULL;
polygon->num_limits = 0;
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
cairo_point_t p1, p2;
p1 = chunk->base[i].p1;
p2.x = p1.x;
p2.y = chunk->base[i].p2.y;
_cairo_polygon_add_edge (polygon, &p1, &p2);
p1 = chunk->base[i].p2;
p2.x = p1.x;
p2.y = chunk->base[i].p1.y;
_cairo_polygon_add_edge (polygon, &p1, &p2);
}
}
return polygon->status;
}
cairo_status_t
_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
cairo_box_t *boxes,
int num_boxes)
{
int i;
VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
polygon->status = CAIRO_STATUS_SUCCESS;
polygon->num_edges = 0;
polygon->edges = polygon->edges_embedded;
polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
polygon->edges_size = 2 * num_boxes;
polygon->edges = _cairo_malloc_ab (polygon->edges_size,
2*sizeof(cairo_edge_t));
if (unlikely (polygon->edges == NULL))
return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;
polygon->limits = NULL;
polygon->num_limits = 0;
for (i = 0; i < num_boxes; i++) {
cairo_point_t p1, p2;
p1 = boxes[i].p1;
p2.x = p1.x;
p2.y = boxes[i].p2.y;
_cairo_polygon_add_edge (polygon, &p1, &p2);
p1 = boxes[i].p2;
p2.x = p1.x;
p2.y = boxes[i].p1.y;
_cairo_polygon_add_edge (polygon, &p1, &p2);
}
return polygon->status;
}
void
_cairo_polygon_fini (cairo_polygon_t *polygon)
{

View file

@ -572,7 +572,7 @@ _cairo_ps_emit_imagemask (cairo_image_surface_t *image,
return _cairo_output_stream_get_status (stream);
}
static cairo_status_t
static cairo_int_status_t
_cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
@ -704,16 +704,15 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
cairo_ps_surface_t *surface = closure;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
if (_cairo_status_is_error (status))
if (_cairo_int_status_is_error (status))
return status;
status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
@ -732,15 +731,15 @@ _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_su
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
cairo_ps_surface_t *surface = closure;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
if (_cairo_status_is_error (status))
if (_cairo_int_status_is_error (status))
return status;
status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
@ -748,7 +747,7 @@ _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subs
return status;
ASSERT_NOT_REACHED;
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
@ -1640,7 +1639,7 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
if (unlikely (status))
return status;
if (surface->clipper.clip.path != NULL) {
if (surface->clipper.clip != NULL) {
_cairo_output_stream_printf (surface->stream, "Q Q\n");
_cairo_surface_clipper_reset (&surface->clipper);
} else
@ -2444,7 +2443,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
cairo_content_t old_content;
cairo_rectangle_int_t old_page_bbox;
cairo_box_t bbox;
cairo_status_t status;
cairo_int_status_t status;
old_content = surface->content;
old_width = surface->width;
@ -2516,7 +2515,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
cairo_surface_t *recording_surface,
const cairo_rectangle_int_t *extents)
@ -2525,7 +2524,7 @@ _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
cairo_matrix_t old_cairo_to_ps;
cairo_content_t old_content;
cairo_rectangle_int_t old_page_bbox;
cairo_status_t status;
cairo_int_status_t status;
old_content = surface->content;
old_width = surface->width;
@ -2733,7 +2732,7 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface,
int width,
int height)
{
cairo_status_t status;
cairo_int_status_t status;
if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
cairo_surface_t *source = pattern->surface;
@ -3576,7 +3575,7 @@ static cairo_int_status_t
_cairo_ps_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_output_stream_t *stream = surface->stream;
@ -3635,13 +3634,13 @@ static cairo_int_status_t
_cairo_ps_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
@ -3699,11 +3698,11 @@ static cairo_int_status_t
_cairo_ps_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_composite_rectangles_t extents;
@ -3786,7 +3785,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_ps_surface_t *surface = abstract_surface;
@ -3840,7 +3839,7 @@ _cairo_ps_surface_set_paginated_mode (void *abstract_surface,
surface->paginated_mode = paginated_mode;
if (surface->clipper.clip.path != NULL) {
if (surface->clipper.clip != NULL) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
_cairo_output_stream_printf (surface->stream, "Q q\n");

View file

@ -1725,7 +1725,7 @@ static cairo_int_status_t
_cairo_quartz_surface_paint_cg (cairo_quartz_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_drawing_state_t state;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@ -1752,7 +1752,7 @@ static cairo_int_status_t
_cairo_quartz_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv;
@ -1779,11 +1779,11 @@ static cairo_int_status_t
_cairo_quartz_surface_fill_cg (cairo_quartz_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_drawing_state_t state;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@ -1827,11 +1827,11 @@ static cairo_int_status_t
_cairo_quartz_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv;
@ -1864,13 +1864,13 @@ static cairo_int_status_t
_cairo_quartz_surface_stroke_cg (cairo_quartz_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_drawing_state_t state;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@ -1947,13 +1947,13 @@ static cairo_int_status_t
_cairo_quartz_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv;
@ -1987,7 +1987,7 @@ _cairo_quartz_surface_show_glyphs_cg (cairo_quartz_surface_t *surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
CGAffineTransform textTransform, invTextTransform;
@ -2131,7 +2131,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
@ -2248,7 +2248,7 @@ _cairo_quartz_surface_mask_cg (cairo_quartz_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_surface_t *mask_surf;
cairo_matrix_t matrix;
@ -2350,7 +2350,7 @@ _cairo_quartz_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv;

View file

@ -40,7 +40,6 @@
#include "cairoint.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-clip-private.h"
typedef enum {
/* The 5 basic drawing operations. */
@ -61,7 +60,7 @@ typedef struct _cairo_command_header {
cairo_command_type_t type;
cairo_recording_region_type_t region;
cairo_operator_t op;
cairo_clip_t clip;
cairo_clip_t *clip;
} cairo_command_header_t;
typedef struct _cairo_command_paint {
@ -130,8 +129,6 @@ typedef struct _cairo_recording_surface {
cairo_rectangle_int_t extents;
cairo_bool_t unbounded;
cairo_clip_t clip;
cairo_array_t commands;
int replay_start_idx;

View file

@ -136,7 +136,6 @@ cairo_recording_surface_create (cairo_content_t content,
const cairo_rectangle_t *extents)
{
cairo_recording_surface_t *recording_surface;
cairo_status_t status;
recording_surface = malloc (sizeof (cairo_recording_surface_t));
if (unlikely (recording_surface == NULL))
@ -150,7 +149,6 @@ cairo_recording_surface_create (cairo_content_t content,
recording_surface->content = content;
recording_surface->unbounded = TRUE;
_cairo_clip_init (&recording_surface->clip);
/* unbounded -> 'infinite' extents */
if (extents != NULL) {
@ -162,13 +160,6 @@ cairo_recording_surface_create (cairo_content_t content,
recording_surface->extents.width = ceil (extents->x + extents->width) - recording_surface->extents.x;
recording_surface->extents.height = ceil (extents->y + extents->height) - recording_surface->extents.y;
status = _cairo_clip_rectangle (&recording_surface->clip,
&recording_surface->extents);
if (unlikely (status)) {
free (recording_surface);
return _cairo_surface_create_in_error (status);
}
recording_surface->unbounded = FALSE;
}
@ -239,12 +230,11 @@ _cairo_recording_surface_finish (void *abstract_surface)
ASSERT_NOT_REACHED;
}
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
}
_cairo_array_fini (&recording_surface->commands);
_cairo_clip_fini (&recording_surface->clip);
return CAIRO_STATUS_SUCCESS;
}
@ -321,16 +311,14 @@ _command_init (cairo_recording_surface_t *recording_surface,
cairo_command_header_t *command,
cairo_command_type_t type,
cairo_operator_t op,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
command->type = type;
command->op = op;
command->region = CAIRO_RECORDING_REGION_ALL;
_cairo_clip_init_copy (&command->clip, clip);
if (recording_surface->clip.path != NULL)
status = _cairo_clip_apply_clip (&command->clip, &recording_surface->clip);
command->clip = _cairo_clip_copy (clip);
return status;
}
@ -339,7 +327,7 @@ static cairo_int_status_t
_cairo_recording_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_recording_surface_t *recording_surface = abstract_surface;
@ -373,7 +361,7 @@ _cairo_recording_surface_paint (void *abstract_surface,
CLEANUP_SOURCE:
_cairo_pattern_fini (&command->source.base);
CLEANUP_COMMAND:
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
return status;
}
@ -383,7 +371,7 @@ _cairo_recording_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_recording_surface_t *recording_surface = abstract_surface;
@ -417,7 +405,7 @@ _cairo_recording_surface_mask (void *abstract_surface,
CLEANUP_SOURCE:
_cairo_pattern_fini (&command->source.base);
CLEANUP_COMMAND:
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
return status;
}
@ -426,13 +414,13 @@ static cairo_int_status_t
_cairo_recording_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_recording_surface_t *recording_surface = abstract_surface;
@ -477,7 +465,7 @@ _cairo_recording_surface_stroke (void *abstract_surface,
CLEANUP_SOURCE:
_cairo_pattern_fini (&command->source.base);
CLEANUP_COMMAND:
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
return status;
}
@ -486,11 +474,11 @@ static cairo_int_status_t
_cairo_recording_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_recording_surface_t *recording_surface = abstract_surface;
@ -528,7 +516,7 @@ _cairo_recording_surface_fill (void *abstract_surface,
CLEANUP_SOURCE:
_cairo_pattern_fini (&command->source.base);
CLEANUP_COMMAND:
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
return status;
}
@ -551,7 +539,7 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_recording_surface_t *recording_surface = abstract_surface;
@ -622,7 +610,7 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
_cairo_pattern_fini (&command->source.base);
CLEANUP_COMMAND:
_cairo_clip_fini (&command->header.clip);
_cairo_clip_destroy (command->header.clip);
free (command);
return status;
}
@ -661,8 +649,6 @@ _cairo_recording_surface_snapshot (void *abstract_other)
recording_surface->unbounded = other->unbounded;
recording_surface->content = other->content;
_cairo_clip_init_copy (&recording_surface->clip, &other->clip);
/* XXX We should in theory be able to reuse the original array, but we
* need to handle reference cycles during subsurface and self-copy.
*/
@ -795,7 +781,7 @@ _cairo_recording_surface_get_path (cairo_surface_t *surface,
command->stroke.tolerance,
&traps);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = _cairo_traps_path (&traps, path);
_cairo_traps_fini (&traps);
@ -828,7 +814,6 @@ _cairo_recording_surface_get_path (cairo_surface_t *surface,
return _cairo_surface_set_error (surface, status);
}
#define _clip(c) ((c)->header.clip.path ? &(c)->header.clip : NULL)
static cairo_status_t
_cairo_recording_surface_replay_internal (cairo_surface_t *surface,
const cairo_rectangle_int_t *surface_extents,
@ -867,18 +852,24 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
for (i = recording_surface->replay_start_idx; i < num_elements; i++) {
cairo_command_t *command = elements[i];
cairo_clip_t *clip = command->header.clip;
if (type == CAIRO_RECORDING_REPLAY && region != CAIRO_RECORDING_REGION_ALL) {
if (command->header.region != region)
continue;
}
if (! recording_surface->unbounded)
clip = _cairo_clip_copy_intersect_rectangle (clip, &recording_surface->extents);
if (_cairo_clip_is_all_clipped (clip))
continue;
switch (command->header.type) {
case CAIRO_COMMAND_PAINT:
status = _cairo_surface_wrapper_paint (&wrapper,
command->header.op,
&command->paint.source.base,
_clip (command));
clip);
break;
case CAIRO_COMMAND_MASK:
@ -886,7 +877,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
command->header.op,
&command->mask.source.base,
&command->mask.mask.base,
_clip (command));
clip);
break;
case CAIRO_COMMAND_STROKE:
@ -900,7 +891,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
&command->stroke.ctm_inverse,
command->stroke.tolerance,
command->stroke.antialias,
_clip (command));
clip);
break;
}
case CAIRO_COMMAND_FILL:
@ -938,7 +929,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
&stroke_command->stroke.ctm_inverse,
stroke_command->stroke.tolerance,
stroke_command->stroke.antialias,
_clip (command));
clip);
i++;
}
else
@ -950,7 +941,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
command->fill.fill_rule,
command->fill.tolerance,
command->fill.antialias,
_clip (command));
clip);
}
break;
}
@ -980,7 +971,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters,
command->show_text_glyphs.cluster_flags,
command->show_text_glyphs.scaled_font,
_clip (command));
clip);
free (glyphs_copy);
break;
}
@ -989,29 +980,24 @@ _cairo_recording_surface_replay_internal (cairo_surface_t *surface,
}
if (type == CAIRO_RECORDING_CREATE_REGIONS) {
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
command->header.region = CAIRO_RECORDING_REGION_NATIVE;
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
command->header.region = CAIRO_RECORDING_REGION_IMAGE_FALLBACK;
status = CAIRO_STATUS_SUCCESS;
status = CAIRO_INT_STATUS_SUCCESS;
} else {
assert (_cairo_status_is_error (status));
assert (_cairo_int_status_is_error (status));
}
}
if (clip != command->header.clip)
_cairo_clip_destroy (clip);
if (unlikely (status))
break;
}
/* free up any caches */
for (i = recording_surface->replay_start_idx; i < num_elements; i++) {
cairo_command_t *command = elements[i];
_cairo_clip_drop_cache (&command->header.clip);
}
_cairo_surface_wrapper_fini (&wrapper);
return _cairo_surface_set_error (surface, status);
}

View file

@ -216,11 +216,11 @@ cairo_private cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets,
cairo_scaled_font_t *scaled_font,
unsigned long scaled_font_glyph_index,
const char * utf8,
const char * utf8,
int utf8_len,
cairo_scaled_font_subsets_glyph_t *subset_glyph_ret);
typedef cairo_status_t
typedef cairo_int_status_t
(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset,
void *closure);

View file

@ -511,7 +511,7 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t *sub_font,
int *num_glyphs_in_subset_ptr;
double x_advance;
double y_advance;
cairo_status_t status;
cairo_int_status_t status;
_cairo_scaled_font_freeze_cache (sub_font->scaled_font);
status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
@ -828,7 +828,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
cairo_matrix_t identity;
cairo_font_options_t font_options;
cairo_scaled_font_t *unscaled_font;
cairo_status_t status;
cairo_int_status_t status;
int max_glyphs;
cairo_bool_t type1_font;
@ -881,10 +881,10 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
&scaled_glyph);
_cairo_scaled_font_thaw_cache (scaled_font);
}
if (_cairo_status_is_error (status))
if (_cairo_int_status_is_error (status))
return status;
if (status == CAIRO_STATUS_SUCCESS &&
if (status == CAIRO_INT_STATUS_SUCCESS &&
subsets->type != CAIRO_SUBSETS_SCALED &&
! _cairo_font_face_is_user (scaled_font->font_face))
{

View file

@ -1858,7 +1858,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
cairo_text_cluster_flags_t *cluster_flags)
{
int num_chars = 0;
cairo_status_t status;
cairo_int_status_t status;
cairo_glyph_t *orig_glyphs;
cairo_text_cluster_t *orig_clusters;
@ -1941,7 +1941,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
clusters, num_clusters,
cluster_flags);
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
/* The checks here are crude; we only should do them in
* user-font backend, but they don't hurt here. This stuff
* can be hard to get right. */
@ -2193,7 +2193,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_region_t *clip_region)
{
cairo_status_t status;
cairo_int_status_t status;
cairo_surface_t *mask = NULL;
cairo_format_t mask_format = CAIRO_FORMAT_A1; /* shut gcc up */
cairo_surface_pattern_t mask_pattern;
@ -2224,7 +2224,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
glyphs += num_glyphs - remaining_glyphs;
num_glyphs = remaining_glyphs;
if (remaining_glyphs == 0)
status = CAIRO_STATUS_SUCCESS;
status = CAIRO_INT_STATUS_SUCCESS;
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return _cairo_scaled_font_set_error (scaled_font, status);
}
@ -2480,7 +2480,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_path_fixed_t *path)
{
cairo_status_t status;
cairo_int_status_t status;
int i;
status = scaled_font->status;
@ -2495,7 +2495,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
status = _cairo_path_fixed_append (path,
scaled_glyph->path,
_cairo_fixed_from_double (glyphs[i].x),
@ -2787,7 +2787,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
cairo_scaled_glyph_info_t info,
cairo_scaled_glyph_t **scaled_glyph_ret)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
cairo_scaled_glyph_t *scaled_glyph;
cairo_scaled_glyph_info_t need_info;

View file

@ -839,6 +839,7 @@ _format_to_string (cairo_format_t format)
{
switch (format) {
case CAIRO_FORMAT_ARGB32: return "ARGB32";
case CAIRO_FORMAT_RGB30: return "RGB30";
case CAIRO_FORMAT_RGB24: return "RGB24";
case CAIRO_FORMAT_RGB16_565: return "RGB16_565";
case CAIRO_FORMAT_A8: return "A8";
@ -1204,6 +1205,7 @@ _write_image_surface (cairo_output_stream_t *output,
data += stride;
}
break;
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_ARGB32:
for (row = image->height; row--; ) {
uint32_t *src = (uint32_t *) data;
@ -1279,14 +1281,14 @@ _undef (void *data)
free (def);
}
static cairo_status_t
static cairo_int_status_t
_emit_image_surface (cairo_script_surface_t *surface,
cairo_image_surface_t *image)
{
cairo_script_context_t *ctx = to_context (surface);
cairo_output_stream_t *base85_stream;
cairo_output_stream_t *zlib_stream;
cairo_status_t status, status2;
cairo_int_status_t status, status2;
const uint8_t *mime_data;
unsigned long mime_data_length;
struct def *tag;
@ -1297,11 +1299,11 @@ _emit_image_surface (cairo_script_surface_t *surface,
_cairo_output_stream_printf (ctx->stream,
"s%u ",
image->base.unique_id);
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
status = _emit_png_surface (surface, image);
if (_cairo_status_is_error (status)) {
if (_cairo_int_status_is_error (status)) {
return status;
} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_image_surface_t *clone;
@ -1336,6 +1338,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
case CAIRO_FORMAT_RGB24:
len = clone->width * 3;
break;
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_ARGB32:
len = clone->width * 4;
break;
@ -1357,10 +1360,10 @@ _emit_image_surface (cairo_script_surface_t *surface,
status = _write_image_surface (zlib_stream, clone);
status2 = _cairo_output_stream_destroy (zlib_stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
status2 = _cairo_output_stream_destroy (base85_stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
if (unlikely (status))
return status;
@ -1370,7 +1373,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
base85_stream = _cairo_base85_stream_create (ctx->stream);
status = _write_image_surface (base85_stream, clone);
status2 = _cairo_output_stream_destroy (base85_stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
if (unlikely (status))
return status;
@ -1432,10 +1435,10 @@ _emit_image_surface (cairo_script_surface_t *surface,
_cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n");
}
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_emit_image_surface_pattern (cairo_script_surface_t *surface,
cairo_surface_t *source)
{
@ -1458,12 +1461,12 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface,
return status;
}
static cairo_status_t
static cairo_int_status_t
_emit_subsurface_pattern (cairo_script_surface_t *surface,
cairo_surface_subsurface_t *sub)
{
cairo_surface_t *source = sub->target;
cairo_status_t status;
cairo_int_status_t status;
switch ((int) source->backend->type) {
case CAIRO_SURFACE_TYPE_RECORDING:
@ -1485,16 +1488,16 @@ _emit_subsurface_pattern (cairo_script_surface_t *surface,
sub->extents.y,
sub->extents.width,
sub->extents.height);
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_emit_surface_pattern (cairo_script_surface_t *surface,
const cairo_pattern_t *pattern)
{
cairo_surface_pattern_t *surface_pattern;
cairo_surface_t *source;
cairo_status_t status;
cairo_int_status_t status;
surface_pattern = (cairo_surface_pattern_t *) pattern;
source = surface_pattern->surface;
@ -1520,15 +1523,15 @@ _emit_surface_pattern (cairo_script_surface_t *surface,
return status;
_cairo_output_stream_puts (to_context (surface)->stream, "pattern");
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_emit_pattern (cairo_script_surface_t *surface,
const cairo_pattern_t *pattern)
{
cairo_script_context_t *ctx = to_context (surface);
cairo_status_t status;
cairo_int_status_t status;
cairo_bool_t is_default_extend;
cairo_bool_t need_newline = TRUE;
@ -1599,17 +1602,17 @@ _emit_pattern (cairo_script_surface_t *surface,
if (need_newline)
_cairo_output_stream_puts (ctx->stream, "\n ");
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_emit_identity (cairo_script_surface_t *surface,
cairo_bool_t *matrix_updated)
{
assert (target_is_active (surface));
if (_cairo_matrix_is_identity (&surface->cr.current_ctm))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
_cairo_output_stream_puts (to_context (surface)->stream,
"identity set-matrix\n");
@ -1617,26 +1620,26 @@ _emit_identity (cairo_script_surface_t *surface,
*matrix_updated = TRUE;
cairo_matrix_init_identity (&surface->cr.current_ctm);
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_emit_source (cairo_script_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source)
{
cairo_bool_t matrix_updated = FALSE;
cairo_status_t status;
cairo_int_status_t status;
assert (target_is_active (surface));
if (op == CAIRO_OPERATOR_CLEAR) {
/* the source is ignored, so don't change it */
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
if (_cairo_pattern_equal (&surface->cr.current_source.base, source))
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
_cairo_pattern_fini (&surface->cr.current_source.base);
status = _cairo_pattern_init_copy (&surface->cr.current_source.base,
@ -1655,7 +1658,7 @@ _emit_source (cairo_script_surface_t *surface,
assert (target_is_active (surface));
_cairo_output_stream_puts (to_context (surface)->stream,
" set-source\n");
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
@ -1711,7 +1714,7 @@ _path_close (void *closure)
static cairo_status_t
_emit_path (cairo_script_surface_t *surface,
cairo_path_fixed_t *path)
const cairo_path_fixed_t *path)
{
cairo_script_context_t *ctx = to_context (surface);
cairo_box_t box;
@ -2263,7 +2266,7 @@ static cairo_int_status_t
_cairo_script_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_script_surface_t *surface = abstract_surface;
cairo_status_t status;
@ -2310,7 +2313,7 @@ _cairo_script_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_script_surface_t *surface = abstract_surface;
cairo_status_t status;
@ -2366,13 +2369,13 @@ static cairo_int_status_t
_cairo_script_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_script_surface_t *surface = abstract_surface;
cairo_bool_t matrix_updated = FALSE;
@ -2457,11 +2460,11 @@ static cairo_int_status_t
_cairo_script_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_script_surface_t *surface = abstract_surface;
cairo_bool_t matrix_updated = FALSE;
@ -2743,7 +2746,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
{
cairo_script_context_t *ctx = to_context (surface);
cairo_script_surface_font_private_t *font_private;
cairo_status_t status;
cairo_int_status_t status;
font_private = malloc (sizeof (cairo_script_surface_font_private_t));
if (unlikely (font_private == NULL))
@ -3135,7 +3138,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t backward,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_script_surface_t *surface = abstract_surface;
cairo_script_context_t *ctx = to_context (surface);

View file

@ -27,7 +27,10 @@
#include "cairoint.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-fixed-private.h"
#include "cairo-types-private.h"
static cairo_scan_converter_t *
_create_scan_converter (cairo_fill_rule_t fill_rule,
@ -62,6 +65,31 @@ _cairo_surface_composite_polygon (cairo_surface_t *surface,
cairo_span_renderer_t *renderer;
cairo_scan_converter_t *converter;
cairo_status_t status;
cairo_clip_path_t *clip_path = rects->clip->path;
if (rects->is_bounded) {
if (polygon->num_edges == 0)
return CAIRO_STATUS_SUCCESS;
if (clip_path) { /* XXX */
cairo_polygon_t clipper;
cairo_fill_rule_t clipper_fill_rule;
cairo_antialias_t clipper_antialias;
if (_cairo_clip_get_polygon (rects->clip, &clipper,
&clipper_fill_rule,
&clipper_antialias) == CAIRO_INT_STATUS_SUCCESS) {
if (clipper_antialias != CAIRO_ANTIALIAS_NONE &&
_cairo_polygon_intersect (polygon, fill_rule,
&clipper, clipper_fill_rule) == CAIRO_STATUS_SUCCESS)
{
rects->clip->path = NULL;
}
_cairo_polygon_fini (&clipper);
}
}
}
converter = _create_scan_converter (fill_rule, antialias, rects);
status = converter->add_polygon (converter, polygon);
@ -81,6 +109,7 @@ _cairo_surface_composite_polygon (cairo_surface_t *surface,
renderer->destroy (renderer);
CLEANUP_CONVERTER:
converter->destroy (converter);
rects->clip->path = clip_path;
return status;
}

View file

@ -51,14 +51,13 @@ typedef cairo_status_t
double,
cairo_antialias_t);
struct _cairo_surface_clipper {
cairo_clip_t clip;
cairo_bool_t is_clipped;
cairo_clip_t *clip;
cairo_surface_clipper_intersect_clip_path_func_t intersect_clip_path;
};
cairo_private cairo_status_t
_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private void
_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,

View file

@ -39,6 +39,63 @@
/* A collection of routines to facilitate vector surface clipping */
/* XXX Eliminate repeated paths and nested clips */
static cairo_status_t
_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
const cairo_box_t *box)
{
cairo_status_t status;
status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y);
if (unlikely (status))
return status;
return _cairo_path_fixed_close_path (path);
}
static cairo_status_t
_cairo_surface_clipper_intersect_clip_boxes (cairo_surface_clipper_t *clipper,
const cairo_clip_t *clip)
{
cairo_path_fixed_t path;
cairo_status_t status;
int i;
/* Reconstruct the path for the clip boxes.
* XXX maybe a new clipper callback?
*/
_cairo_path_fixed_init (&path);
for (i = 0; i < clip->num_boxes; i++) {
status = _cairo_path_fixed_add_box (&path, &clip->boxes[i]);
if (unlikely (status)) {
_cairo_path_fixed_fini (&path);
return status;
}
}
status = clipper->intersect_clip_path (clipper, &path,
CAIRO_FILL_RULE_WINDING,
0.,
CAIRO_ANTIALIAS_DEFAULT);
_cairo_path_fixed_init (&path);
return status;
}
static cairo_status_t
_cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper,
cairo_clip_path_t *clip_path)
@ -62,57 +119,33 @@ _cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *c
cairo_status_t
_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_bool_t clear;
/* XXX as we cache a reference to the path, and compare every time,
* we may in future need to install a notification if the clip->path
* is every modified (e.g. cairo_clip_translate).
*/
if (clip == NULL && clipper->clip.path == NULL)
if (_cairo_clip_equal (clip, clipper->clip))
return CAIRO_STATUS_SUCCESS;
if (clip != NULL && clipper->clip.path != NULL &&
_cairo_clip_equal (clip, &clipper->clip))
{
return CAIRO_STATUS_SUCCESS;
}
/* all clipped out state should never propagate this far */
assert (clip == NULL || clip->path != NULL);
assert (!_cairo_clip_is_all_clipped (clip));
/* Check whether this clip is a continuation of the previous.
* If not, we have to remove the current clip and rebuild.
*/
clear = clip == NULL || clip->path->prev != clipper->clip.path;
_cairo_clip_destroy (clipper->clip);
clipper->clip = _cairo_clip_copy (clip);
_cairo_clip_reset (&clipper->clip);
_cairo_clip_init_copy (&clipper->clip, clip);
status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
if (unlikely (status))
return status;
if (clear) {
clipper->is_clipped = FALSE;
status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
if (unlikely (status))
return status;
if (clip == NULL)
return CAIRO_STATUS_SUCCESS;
if (clip != NULL && clip->path != NULL) {
status =
_cairo_surface_clipper_intersect_clip_path_recursive (clipper,
clip->path);
clipper->is_clipped = TRUE;
}
} else {
cairo_clip_path_t *path = clip->path;
status = _cairo_surface_clipper_intersect_clip_boxes (clipper, clip);
if (unlikely (status))
return status;
clipper->is_clipped = TRUE;
status = clipper->intersect_clip_path (clipper,
&path->path,
path->fill_rule,
path->tolerance,
path->antialias);
if (clip->path != NULL) {
status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper,
clip->path);
}
return status;
@ -122,14 +155,13 @@ void
_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,
cairo_surface_clipper_intersect_clip_path_func_t func)
{
_cairo_clip_init (&clipper->clip);
clipper->is_clipped = FALSE;
clipper->clip = NULL;
clipper->intersect_clip_path = func;
}
void
_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper)
{
_cairo_clip_reset (&clipper->clip);
clipper->is_clipped = FALSE;
_cairo_clip_destroy (clipper->clip);
clipper->clip = NULL;
}

View file

@ -45,36 +45,36 @@ cairo_private cairo_status_t
_cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fallback_fill (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
@ -83,7 +83,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface);

View file

@ -128,20 +128,10 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
const cairo_rectangle_int_t *extents)
{
cairo_surface_t *mask;
cairo_region_t *clip_region = NULL, *fallback_region = NULL;
cairo_status_t status;
cairo_bool_t clip_surface = FALSE;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (_cairo_status_is_error (status) ||
status == CAIRO_INT_STATUS_NOTHING_TO_DO))
{
return status;
}
clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
}
cairo_region_t *clip_region = _cairo_clip_get_region (clip);
cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
cairo_region_t *fallback_region = NULL;
/* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with
* a mask (as called via _cairo_surface_mask) triggers assertion failures.
@ -282,7 +272,6 @@ _clip_and_composite_combine (cairo_clip_t *clip,
if (unlikely (status))
goto CLEANUP_SURFACE;
assert (clip->path != NULL);
clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;
@ -344,18 +333,9 @@ _clip_and_composite_source (cairo_clip_t *clip,
const cairo_rectangle_int_t *extents)
{
cairo_surface_pattern_t mask_pattern;
cairo_region_t *clip_region = NULL;
cairo_region_t *clip_region = _cairo_clip_get_region (clip);
cairo_status_t status;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (_cairo_status_is_error (status) ||
status == CAIRO_INT_STATUS_NOTHING_TO_DO))
{
return status;
}
}
/* Create a surface that is mask IN clip */
status = _create_composite_mask_pattern (&mask_pattern,
clip,
@ -390,12 +370,6 @@ _clip_and_composite_source (cairo_clip_t *clip,
return status;
}
static int
_cairo_rectangle_empty (const cairo_rectangle_int_t *rect)
{
return rect->width == 0 || rect->height == 0;
}
/**
* _clip_and_composite:
* @clip: a #cairo_clip_t
@ -428,10 +402,6 @@ _clip_and_composite (cairo_clip_t *clip,
{
cairo_status_t status;
if (_cairo_rectangle_empty (extents))
/* Nothing to do */
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_CLEAR) {
src = &_cairo_pattern_white.base;
op = CAIRO_OPERATOR_DEST_OUT;
@ -443,21 +413,7 @@ _clip_and_composite (cairo_clip_t *clip,
draw_func, draw_closure,
dst, extents);
} else {
cairo_bool_t clip_surface = FALSE;
cairo_region_t *clip_region = NULL;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (_cairo_status_is_error (status) ||
status == CAIRO_INT_STATUS_NOTHING_TO_DO))
{
return status;
}
clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
}
if (clip_surface) {
if (! _cairo_clip_is_region (clip)) {
if (_cairo_operator_bounded_by_mask (op)) {
status = _clip_and_composite_with_mask (clip, op,
src,
@ -474,7 +430,7 @@ _clip_and_composite (cairo_clip_t *clip,
src, dst,
0, 0,
extents,
clip_region);
_cairo_clip_get_region (clip));
}
}
@ -779,23 +735,12 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
cairo_rectangle_int_t *extents)
{
cairo_composite_traps_info_t traps_info;
cairo_region_t *clip_region = NULL;
cairo_bool_t clip_surface = FALSE;
cairo_status_t status;
cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
cairo_int_status_t status;
if (traps->num_traps == 0 && _cairo_operator_bounded_by_mask (op))
return CAIRO_STATUS_SUCCESS;
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (_cairo_status_is_error (status)))
return status;
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Use a fast path if the trapezoids consist of a simple region,
* but we can only do this if we do not have a clip surface, or can
* substitute the mask with the clip.
@ -815,8 +760,8 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
return status;
}
status = _cairo_traps_extract_region (traps, &trap_region);
if (unlikely (_cairo_status_is_error (status)))
status = _cairo_traps_extract_region (traps, antialias, &trap_region);
if (unlikely (_cairo_int_status_is_error (status)))
return status;
if (trap_region != NULL) {
@ -826,21 +771,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
return status;
}
if (clip_region != NULL) {
status = cairo_region_intersect (trap_region, clip_region);
if (unlikely (status)) {
cairo_region_destroy (trap_region);
return status;
}
}
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t trap_extents;
cairo_region_get_extents (trap_region, &trap_extents);
if (! _cairo_rectangle_intersect (extents, &trap_extents)) {
cairo_region_destroy (trap_region);
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
}
@ -882,16 +819,12 @@ cairo_status_t
_cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_rectangle_int_t rect;
cairo_clip_path_t *clip_path = clip ? clip->path : NULL;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
cairo_boxes_t boxes;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_status_t status;
cairo_traps_t traps;
cairo_int_status_t status;
if (!_cairo_surface_get_extents (surface, &rect))
ASSERT_NOT_REACHED;
@ -904,44 +837,22 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (extents.clip, &boxes);
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
cairo_traps_t traps;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
/* If the clip cannot be reduced to a set of boxes, we will need to
* use a clipmask. Paint is special as it is the only operation that
* does not implicitly use a mask, so we may be able to reduce this
* operation to a fill...
*/
if (clip != NULL && clip_path->prev == NULL &&
_cairo_operator_bounded_by_mask (op))
{
return _cairo_surface_fill (surface, op, source,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
NULL);
/* meh, surface-fallback is dying anyway... */
status = _cairo_traps_init_boxes (&traps, &boxes);
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
status = _clip_and_composite_trapezoids (source, op, surface,
&traps, CAIRO_ANTIALIAS_DEFAULT,
extents.clip,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
_cairo_traps_fini (&traps);
}
}
/* meh, surface-fallback is dying anyway... */
_cairo_boxes_init_for_array (&boxes, clip_boxes, num_boxes);
status = _cairo_traps_init_boxes (&traps, &boxes);
if (unlikely (status))
goto CLEANUP_BOXES;
status = _clip_and_composite_trapezoids (source, op, surface,
&traps, CAIRO_ANTIALIAS_DEFAULT,
clip,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
_cairo_traps_fini (&traps);
CLEANUP_BOXES:
if (clip_boxes != boxes_stack)
free (clip_boxes);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -957,7 +868,7 @@ _cairo_surface_mask_draw_func (void *closure,
cairo_region_t *clip_region)
{
cairo_pattern_t *mask = closure;
cairo_status_t status;
cairo_int_status_t status;
cairo_region_t *extents_region = NULL;
if (clip_region == NULL &&
@ -998,7 +909,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_rectangle_int_t rect;
@ -1013,38 +924,31 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _clip_and_composite (extents.clip, op, source,
_cairo_surface_mask_draw_func,
(void *) mask,
surface,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
if (clip != NULL && extents.is_bounded) {
status = _cairo_clip_rectangle (clip, &extents.bounded);
if (unlikely (status))
return status;
}
_cairo_composite_rectangles_fini (&extents);
return _clip_and_composite (clip, op, source,
_cairo_surface_mask_draw_func,
(void *) mask,
surface,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
return status;
}
cairo_status_t
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_polygon_t polygon;
cairo_traps_t traps;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_composite_rectangles_t extents;
cairo_rectangle_int_t rect;
cairo_status_t status;
@ -1061,22 +965,14 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, clip_boxes, num_boxes);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
_cairo_traps_init_with_clip (&traps, extents.clip);
if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
status = _cairo_path_fixed_stroke_rectilinear_to_traps (path,
stroke_style,
ctm,
antialias,
&traps);
if (likely (status == CAIRO_STATUS_SUCCESS))
goto DO_TRAPS;
@ -1112,13 +1008,13 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
DO_TRAPS:
status = _clip_and_composite_trapezoids (source, op, surface,
&traps, antialias,
clip,
extents.clip,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
CLEANUP:
_cairo_traps_fini (&traps);
_cairo_polygon_fini (&polygon);
if (clip_boxes != boxes_stack)
free (clip_boxes);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -1127,16 +1023,14 @@ cairo_status_t
_cairo_surface_fallback_fill (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_polygon_t polygon;
cairo_traps_t traps;
cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
int num_boxes = ARRAY_LENGTH (boxes_stack);
cairo_bool_t is_rectilinear;
cairo_composite_rectangles_t extents;
cairo_rectangle_int_t rect;
@ -1153,17 +1047,8 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, clip_boxes, num_boxes);
_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
_cairo_traps_init_with_clip (&traps, extents.clip);
_cairo_polygon_init_with_clip (&polygon, extents.clip);
if (_cairo_path_fixed_fill_is_empty (path))
goto DO_TRAPS;
@ -1172,6 +1057,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
if (is_rectilinear) {
status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
fill_rule,
antialias,
&traps);
if (likely (status == CAIRO_STATUS_SUCCESS))
goto DO_TRAPS;
@ -1214,13 +1100,13 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
DO_TRAPS:
status = _clip_and_composite_trapezoids (source, op, surface,
&traps, antialias,
clip,
extents.clip,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
CLEANUP:
_cairo_traps_fini (&traps);
_cairo_polygon_fini (&polygon);
if (clip_boxes != boxes_stack)
free (clip_boxes);
_cairo_composite_rectangles_fini (&extents);
return status;
}
@ -1242,17 +1128,7 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
cairo_region_t *clip_region)
{
cairo_show_glyphs_info_t *glyph_info = closure;
cairo_status_t status;
cairo_region_t *extents_region = NULL;
if (clip_region == NULL &&
!_cairo_operator_bounded_by_source (op)) {
extents_region = cairo_region_create_rectangle (extents);
if (unlikely (extents_region->status))
return extents_region->status;
cairo_region_translate (extents_region, -dst_x, -dst_y);
clip_region = extents_region;
}
cairo_int_status_t status;
/* Modifying the glyph array is fine because we know that this function
* will be called only once, and we've already made a copy of the
@ -1291,9 +1167,6 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
clip_region);
}
if (extents_region)
cairo_region_destroy (extents_region);
return status;
}
@ -1304,12 +1177,12 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_show_glyphs_info_t glyph_info;
cairo_composite_rectangles_t extents;
cairo_rectangle_int_t rect;
cairo_status_t status;
cairo_int_status_t status;
if (!_cairo_surface_get_extents (surface, &rect))
ASSERT_NOT_REACHED;
@ -1325,24 +1198,18 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
if (unlikely (status))
return status;
if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
status = _cairo_clip_rectangle (clip, &extents.bounded);
if (unlikely (status))
return status;
}
glyph_info.font = scaled_font;
glyph_info.glyphs = glyphs;
glyph_info.num_glyphs = num_glyphs;
return _clip_and_composite (clip, op, source,
_cairo_surface_old_show_glyphs_draw_func,
&glyph_info,
surface,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
status = _clip_and_composite (extents.clip, op, source,
_cairo_surface_old_show_glyphs_draw_func,
&glyph_info, surface,
extents.is_bounded ? &extents.bounded : &extents.unbounded);
_cairo_composite_rectangles_fini (&extents);
return status;
}
cairo_surface_t *

View file

@ -48,7 +48,7 @@ _cairo_surface_offset_paint (cairo_surface_t *target,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_offset_mask (cairo_surface_t *target,
@ -56,31 +56,31 @@ _cairo_surface_offset_mask (cairo_surface_t *target,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_offset_stroke (cairo_surface_t *surface,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_offset_fill (cairo_surface_t *surface,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t*source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_offset_glyphs (cairo_surface_t *surface,
@ -90,6 +90,6 @@ _cairo_surface_offset_glyphs (cairo_surface_t *surface,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip);
const cairo_clip_t *clip);
#endif /* CAIRO_SURFACE_OFFSET_PRIVATE_H */

View file

@ -59,29 +59,22 @@ _cairo_surface_offset_paint (cairo_surface_t *target,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
if (unlikely (target->status))
return target->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (x | y) {
cairo_matrix_t m;
if (clip != NULL) {
cairo_matrix_init_translate (&m, -x, -y);
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
cairo_matrix_init_translate (&m, x, y);
_copy_transformed_pattern (&source_copy.base, source, &m);
@ -90,9 +83,8 @@ _cairo_surface_offset_paint (cairo_surface_t *target,
status = _cairo_surface_paint (target, op, source, dev_clip);
FINISH:
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -103,30 +95,23 @@ _cairo_surface_offset_mask (cairo_surface_t *target,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
cairo_pattern_union_t mask_copy;
if (unlikely (target->status))
return target->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (x | y) {
cairo_matrix_t m;
if (clip != NULL) {
cairo_matrix_init_translate (&m, -x, -y);
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
cairo_matrix_init_translate (&m, x, y);
_copy_transformed_pattern (&source_copy.base, source, &m);
@ -139,9 +124,8 @@ _cairo_surface_offset_mask (cairo_surface_t *target,
source, mask,
dev_clip);
FINISH:
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -151,16 +135,16 @@ _cairo_surface_offset_stroke (cairo_surface_t *surface,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t*stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_path_fixed_t path_copy, *dev_path = path;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_matrix_t dev_ctm = *ctm;
cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
cairo_pattern_union_t source_copy;
@ -169,12 +153,14 @@ _cairo_surface_offset_stroke (cairo_surface_t *surface,
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (x | y) {
cairo_matrix_t m;
dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
if (unlikely (status))
goto FINISH;
@ -186,13 +172,6 @@ _cairo_surface_offset_stroke (cairo_surface_t *surface,
cairo_matrix_init_translate (&m, -x, -y);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
cairo_matrix_init_translate (&m, x, y);
_copy_transformed_pattern (&source_copy.base, source, &m);
@ -206,11 +185,11 @@ _cairo_surface_offset_stroke (cairo_surface_t *surface,
tolerance, antialias,
dev_clip);
FINISH:
FINISH:
if (dev_path != path)
_cairo_path_fixed_fini (dev_path);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -220,26 +199,28 @@ _cairo_surface_offset_fill (cairo_surface_t *surface,
int x, int y,
cairo_operator_t op,
const cairo_pattern_t*source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_path_fixed_t path_copy, *dev_path = path;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (x | y) {
cairo_matrix_t m;
dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
if (unlikely (status))
goto FINISH;
@ -249,15 +230,6 @@ _cairo_surface_offset_fill (cairo_surface_t *surface,
_cairo_fixed_from_int (-y));
dev_path = &path_copy;
if (clip != NULL) {
cairo_matrix_init_translate (&m, -x, -y);
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
cairo_matrix_init_translate (&m, x, y);
_copy_transformed_pattern (&source_copy.base, source, &m);
source = &source_copy.base;
@ -268,11 +240,11 @@ _cairo_surface_offset_fill (cairo_surface_t *surface,
tolerance, antialias,
dev_clip);
FINISH:
FINISH:
if (dev_path != path)
_cairo_path_fixed_fini (dev_path);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -285,10 +257,10 @@ _cairo_surface_offset_glyphs (cairo_surface_t *surface,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
cairo_glyph_t *dev_glyphs;
int i;
@ -296,7 +268,7 @@ _cairo_surface_offset_glyphs (cairo_surface_t *surface,
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
@ -308,14 +280,7 @@ _cairo_surface_offset_glyphs (cairo_surface_t *surface,
if (x | y) {
cairo_matrix_t m;
if (clip != NULL) {
cairo_matrix_init_translate (&m, -x, -y);
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
cairo_matrix_init_translate (&m, x, y);
_copy_transformed_pattern (&source_copy.base, source, &m);
@ -334,9 +299,8 @@ _cairo_surface_offset_glyphs (cairo_surface_t *surface,
scaled_font,
dev_clip);
FINISH:
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
free (dev_glyphs);
return status;

View file

@ -65,23 +65,18 @@ static cairo_int_status_t
_cairo_surface_subsurface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
cairo_status_t status;
cairo_clip_t target_clip;
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &rect);
if (unlikely (status))
goto CLEANUP;
cairo_clip_t *target_clip;
target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
status = _cairo_surface_offset_paint (surface->target,
-surface->extents.x, -surface->extents.y,
op, source, &target_clip);
CLEANUP:
_cairo_clip_fini (&target_clip);
op, source, target_clip);
_cairo_clip_destroy (target_clip);
return status;
}
@ -90,23 +85,18 @@ _cairo_surface_subsurface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
cairo_status_t status;
cairo_clip_t target_clip;
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &rect);
if (unlikely (status))
goto CLEANUP;
cairo_clip_t *target_clip;
target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
status = _cairo_surface_offset_mask (surface->target,
-surface->extents.x, -surface->extents.y,
op, source, mask, &target_clip);
CLEANUP:
_cairo_clip_fini (&target_clip);
op, source, mask, target_clip);
_cairo_clip_destroy (target_clip);
return status;
}
@ -114,28 +104,23 @@ static cairo_int_status_t
_cairo_surface_subsurface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
cairo_status_t status;
cairo_clip_t target_clip;
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &rect);
if (unlikely (status))
goto CLEANUP;
cairo_clip_t *target_clip;
target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
status = _cairo_surface_offset_fill (surface->target,
-surface->extents.x, -surface->extents.y,
op, source, path, fill_rule, tolerance, antialias,
&target_clip);
CLEANUP:
_cairo_clip_fini (&target_clip);
target_clip);
_cairo_clip_destroy (target_clip);
return status;
}
@ -143,31 +128,26 @@ static cairo_int_status_t
_cairo_surface_subsurface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
cairo_status_t status;
cairo_clip_t target_clip;
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &rect);
if (unlikely (status))
goto CLEANUP;
cairo_clip_t *target_clip;
target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
status = _cairo_surface_offset_stroke (surface->target,
-surface->extents.x, -surface->extents.y,
op, source, path, stroke_style, ctm, ctm_inverse,
tolerance, antialias,
&target_clip);
CLEANUP:
_cairo_clip_fini (&target_clip);
target_clip);
_cairo_clip_destroy (target_clip);
return status;
}
@ -178,27 +158,22 @@ _cairo_surface_subsurface_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
cairo_status_t status;
cairo_clip_t target_clip;
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &rect);
if (unlikely (status))
goto CLEANUP;
cairo_clip_t *target_clip;
target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
status = _cairo_surface_offset_glyphs (surface->target,
-surface->extents.x, -surface->extents.y,
op, source,
scaled_font, glyphs, num_glyphs,
&target_clip);
target_clip);
*remaining_glyphs = 0;
CLEANUP:
_cairo_clip_fini (&target_clip);
_cairo_clip_destroy (target_clip);
return status;
}

View file

@ -76,26 +76,26 @@ cairo_private cairo_status_t
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
@ -112,17 +112,17 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
@ -136,7 +136,7 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_surface_t *
_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,

View file

@ -90,26 +90,20 @@ cairo_status_t
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_clip_t *target_clip = NULL;
cairo_pattern_union_t source_copy;
cairo_clip_t target_clip;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -127,13 +121,8 @@ _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
if (_cairo_surface_wrapper_needs_device_transform (wrapper))
cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
status = cairo_matrix_invert (&m);
assert (status == CAIRO_STATUS_SUCCESS);
@ -145,10 +134,9 @@ _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
FINISH:
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (target_clip);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -157,27 +145,21 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
cairo_pattern_union_t mask_copy;
cairo_clip_t target_clip;
cairo_clip_t *target_clip = NULL;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -195,13 +177,8 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
if (_cairo_surface_wrapper_needs_device_transform (wrapper))
cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
status = cairo_matrix_invert (&m);
assert (status == CAIRO_STATUS_SUCCESS);
@ -216,10 +193,9 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
FINISH:
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (target_clip);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -227,35 +203,29 @@ cairo_status_t
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_path_fixed_t path_copy, *dev_path = path;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_matrix_t dev_ctm = *ctm;
cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
cairo_pattern_union_t source_copy;
cairo_clip_t target_clip;
cairo_clip_t *target_clip = NULL;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -280,13 +250,8 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
_cairo_path_fixed_transform (&path_copy, &m);
dev_path = &path_copy;
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
@ -298,13 +263,6 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
_copy_transformed_pattern (&source_copy.base, source, &m);
source = &source_copy.base;
}
else
{
if (clip != NULL) {
dev_clip = &clip_copy;
_cairo_clip_init_copy (&clip_copy, clip);
}
}
status = _cairo_surface_stroke (wrapper->target, op, source,
dev_path, stroke_style,
@ -315,10 +273,9 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
FINISH:
if (dev_path != path)
_cairo_path_fixed_fini (dev_path);
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (target_clip);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -337,30 +294,24 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_path_fixed_t path_copy, *dev_path = path;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_matrix_t dev_ctm = *stroke_ctm;
cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
cairo_pattern_union_t stroke_source_copy;
cairo_pattern_union_t fill_source_copy;
cairo_clip_t target_clip;
cairo_clip_t *target_clip = NULL;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -385,13 +336,8 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
_cairo_path_fixed_transform (&path_copy, &m);
dev_path = &path_copy;
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
@ -406,13 +352,6 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
_copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
fill_source = &fill_source_copy.base;
}
else
{
if (clip != NULL) {
dev_clip = &clip_copy;
_cairo_clip_init_copy (&clip_copy, clip);
}
}
status = _cairo_surface_fill_stroke (wrapper->target,
fill_op, fill_source, fill_rule,
@ -427,10 +366,9 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
FINISH:
if (dev_path != path)
_cairo_path_fixed_fini (dev_path);
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (target_clip);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -438,31 +376,25 @@ cairo_status_t
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_path_fixed_t path_copy, *dev_path = path;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
cairo_pattern_union_t source_copy;
cairo_clip_t target_clip;
cairo_clip_t *target_clip = NULL;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -487,13 +419,8 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
_cairo_path_fixed_transform (&path_copy, &m);
dev_path = &path_copy;
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
status = cairo_matrix_invert (&m);
assert (status == CAIRO_STATUS_SUCCESS);
@ -501,13 +428,6 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
_copy_transformed_pattern (&source_copy.base, source, &m);
source = &source_copy.base;
}
else
{
if (clip != NULL) {
dev_clip = &clip_copy;
_cairo_clip_init_copy (&clip_copy, clip);
}
}
status = _cairo_surface_fill (wrapper->target, op, source,
dev_path, fill_rule,
@ -517,10 +437,9 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
FINISH:
if (dev_path != path)
_cairo_path_fixed_fini (dev_path);
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (target_clip);
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
_cairo_clip_destroy (dev_clip);
return status;
}
@ -536,13 +455,13 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_clip_t clip_copy, *dev_clip = clip;
cairo_clip_t *dev_clip = (cairo_clip_t *)clip;
cairo_glyph_t *dev_glyphs = glyphs;
cairo_pattern_union_t source_copy;
cairo_clip_t target_clip;
cairo_clip_t *target_clip = NULL;
if (unlikely (wrapper->target->status))
return wrapper->target->status;
@ -550,16 +469,10 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
if (glyphs == NULL || num_glyphs == 0)
return CAIRO_STATUS_SUCCESS;
if (wrapper->has_extents) {
_cairo_clip_init_copy (&target_clip, clip);
status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
if (unlikely (status))
goto FINISH;
if (wrapper->has_extents)
dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
dev_clip = clip = &target_clip;
}
if (clip && clip->all_clipped) {
if (_cairo_clip_is_all_clipped (dev_clip)) {
status = CAIRO_STATUS_SUCCESS;
goto FINISH;
}
@ -578,13 +491,8 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
if (_cairo_surface_wrapper_needs_device_transform (wrapper))
cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
if (clip != NULL) {
status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
if (unlikely (status))
goto FINISH;
dev_clip = &clip_copy;
}
/* XXX */
dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
if (dev_glyphs == NULL) {
@ -603,13 +511,6 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
_copy_transformed_pattern (&source_copy.base, source, &m);
source = &source_copy.base;
}
else
{
if (clip != NULL) {
dev_clip = &clip_copy;
_cairo_clip_init_copy (&clip_copy, clip);
}
}
status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
utf8, utf8_len,
@ -621,9 +522,8 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
FINISH:
if (dev_clip != clip)
_cairo_clip_reset (dev_clip);
if (wrapper->has_extents)
_cairo_clip_reset (&target_clip);
_cairo_clip_destroy (dev_clip);
_cairo_clip_destroy (target_clip);
if (dev_glyphs != glyphs)
free (dev_glyphs);
return status;

View file

@ -170,7 +170,7 @@ _cairo_surface_set_error (cairo_surface_t *surface,
cairo_status_t status)
{
if (status == CAIRO_STATUS_SUCCESS ||
status == CAIRO_INT_STATUS_NOTHING_TO_DO)
status == (int)CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
/* Don't overwrite an existing error. This preserves the first
@ -498,6 +498,8 @@ cairo_surface_create_similar (cairo_surface_t *other,
int width,
int height)
{
cairo_surface_t *surface;
if (unlikely (other->status))
return _cairo_surface_create_in_error (other->status);
if (unlikely (other->finished))
@ -508,10 +510,13 @@ cairo_surface_create_similar (cairo_surface_t *other,
if (unlikely (! CAIRO_CONTENT_VALID (content)))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
return _cairo_surface_create_similar_solid (other,
content, width, height,
CAIRO_COLOR_TRANSPARENT,
TRUE);
surface = _cairo_surface_create_similar_solid (other,
content, width, height,
CAIRO_COLOR_TRANSPARENT,
TRUE);
assert (surface->is_clear);
return surface;
}
cairo_surface_t *
@ -1699,7 +1704,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
int *clone_offset_y,
cairo_surface_t **clone_out)
{
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
cairo_image_surface_t *image;
void *image_extra;
@ -1746,7 +1751,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
/* If we failed, try again with an image surface */
status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
status =
surface->backend->clone_similar (surface, &image->base,
src_x, src_y,
@ -1995,27 +2000,27 @@ _pattern_has_error (const cairo_pattern_t *pattern)
}
cairo_status_t
_cairo_surface_paint (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
_cairo_surface_paint (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_SOURCE && _cairo_pattern_is_clear (source))
op = CAIRO_OPERATOR_CLEAR;
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_OVER &&
_cairo_pattern_is_clear (source))
{
if (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_clear (source))
return CAIRO_STATUS_SUCCESS;
}
status = _pattern_has_error (source);
if (unlikely (status))
@ -2043,14 +2048,14 @@ _cairo_surface_mask (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@ -2109,14 +2114,14 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (surface->is_clear &&
@ -2178,20 +2183,20 @@ cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@ -2237,18 +2242,18 @@ cairo_status_t
_cairo_surface_fill (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
if (unlikely (surface->status))
return surface->status;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@ -2355,11 +2360,8 @@ _cairo_surface_create_span_renderer (cairo_operator_t op,
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
if (dst->backend->create_span_renderer) {
return dst->backend->create_span_renderer (op,
pattern, dst,
antialias,
rects,
clip_region);
return dst->backend->create_span_renderer (op, pattern, dst, antialias,
rects, clip_region);
}
ASSERT_NOT_REACHED;
return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
@ -2570,9 +2572,9 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_int_status_t status;
cairo_scaled_font_t *dev_scaled_font = scaled_font;
if (unlikely (surface->status))
@ -2581,7 +2583,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
if (num_glyphs == 0 && utf8_len == 0)
return CAIRO_STATUS_SUCCESS;
if (clip && clip->all_clipped)
if (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@ -2641,7 +2643,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
glyphs += num_glyphs - remaining_glyphs;
num_glyphs = remaining_glyphs;
if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
status = CAIRO_STATUS_SUCCESS;
status = CAIRO_INT_STATUS_SUCCESS;
}
} else {
/* A mere show_glyphs call. Try show_glyphs backend method first */

View file

@ -85,7 +85,7 @@ static const cairo_svg_version_t _cairo_svg_versions[] =
static void
_cairo_svg_surface_emit_path (cairo_output_stream_t *output,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_matrix_t *ctm_inverse);
static cairo_bool_t
@ -562,10 +562,10 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
static cairo_svg_page_t *
_cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
{
unsigned int i;
cairo_svg_page_t page;
cairo_output_stream_t *stream;
cairo_status_t status;
cairo_int_status_t status;
unsigned int i;
stream = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (stream)) {
@ -715,7 +715,7 @@ _cairo_svg_path_close_path (void *closure)
static void
_cairo_svg_surface_emit_path (cairo_output_stream_t *output,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_matrix_t *ctm_inverse)
{
cairo_status_t status;
@ -814,14 +814,14 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_svg_document_emit_glyph (cairo_svg_document_t *document,
cairo_scaled_font_t *scaled_font,
unsigned long scaled_font_glyph_index,
unsigned int font_id,
unsigned int subset_glyph_index)
{
cairo_status_t status;
cairo_int_status_t status;
_cairo_output_stream_printf (document->xml_node_glyphs,
"<symbol overflow=\"visible\" id=\"glyph%d-%d\">\n",
@ -840,16 +840,16 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t *document,
_cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n");
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
static cairo_int_status_t
_cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
void *closure)
{
cairo_svg_document_t *document = closure;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
unsigned int i;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
_cairo_scaled_font_freeze_cache (font_subset->scaled_font);
for (i = 0; i < font_subset->num_glyphs; i++) {
@ -1163,7 +1163,7 @@ static cairo_int_status_t
_cairo_surface_base64_encode (cairo_surface_t *surface,
cairo_output_stream_t *output)
{
cairo_status_t status;
cairo_int_status_t status;
base64_write_closure_t info;
status = _cairo_surface_base64_encode_jpeg (surface, output);
@ -2137,7 +2137,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_operator_t stroke_op,
const cairo_pattern_t *stroke_source,
const cairo_stroke_style_t *stroke_style,
@ -2145,7 +2145,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_status_t status;
@ -2179,11 +2179,11 @@ static cairo_int_status_t
_cairo_svg_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_status_t status;
@ -2274,7 +2274,7 @@ static cairo_int_status_t
_cairo_svg_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_svg_surface_t *surface = abstract_surface;
@ -2340,7 +2340,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_status_t status;
cairo_svg_surface_t *surface = abstract_surface;
@ -2430,13 +2430,13 @@ static cairo_int_status_t
_cairo_svg_surface_stroke (void *abstract_dst,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_svg_surface_t *surface = abstract_dst;
cairo_status_t status;
@ -2473,13 +2473,13 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_svg_document_t *document = surface->document;
cairo_path_fixed_t path;
cairo_status_t status;
cairo_int_status_t status;
cairo_scaled_font_subsets_glyph_t subset_glyph;
int i;
@ -2834,7 +2834,7 @@ _cairo_svg_surface_supports_fine_grained_fallbacks (void *abstract_surface)
CAIRO_OPERATOR_SOURCE);
}
return status == CAIRO_STATUS_SUCCESS;
return status == CAIRO_INT_STATUS_SUCCESS;
}
static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend = {

View file

@ -199,12 +199,12 @@ static cairo_int_status_t
_cairo_tee_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_tee_surface_t *surface = abstract_surface;
cairo_surface_wrapper_t *slaves;
int n, num_slaves;
cairo_status_t status;
cairo_int_status_t status;
status = _cairo_surface_wrapper_paint (&surface->master, op, source, clip);
if (unlikely (status))
@ -226,12 +226,12 @@ _cairo_tee_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_tee_surface_t *surface = abstract_surface;
cairo_surface_wrapper_t *slaves;
cairo_int_status_t status;
int n, num_slaves;
cairo_status_t status;
status = _cairo_surface_wrapper_mask (&surface->master,
op, source, mask, clip);
@ -254,18 +254,18 @@ static cairo_int_status_t
_cairo_tee_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_tee_surface_t *surface = abstract_surface;
cairo_surface_wrapper_t *slaves;
cairo_int_status_t status;
int n, num_slaves;
cairo_status_t status;
status = _cairo_surface_wrapper_stroke (&surface->master,
op, source,
@ -296,16 +296,16 @@ static cairo_int_status_t
_cairo_tee_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_tee_surface_t *surface = abstract_surface;
cairo_surface_wrapper_t *slaves;
cairo_int_status_t status;
int n, num_slaves;
cairo_status_t status;
status = _cairo_surface_wrapper_fill (&surface->master,
op, source,
@ -327,7 +327,7 @@ _cairo_tee_surface_fill (void *abstract_surface,
return status;
}
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_bool_t
@ -348,12 +348,12 @@ _cairo_tee_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_tee_surface_t *surface = abstract_surface;
cairo_surface_wrapper_t *slaves;
cairo_int_status_t status;
int n, num_slaves;
cairo_status_t status;
cairo_glyph_t *glyphs_copy;
/* XXX: This copying is ugly. */
@ -504,8 +504,8 @@ cairo_tee_surface_remove (cairo_surface_t *abstract_surface,
{
cairo_tee_surface_t *surface;
cairo_surface_wrapper_t *slaves;
cairo_int_status_t status;
int n, num_slaves;
cairo_status_t status;
if (unlikely (abstract_surface->status))
return;
@ -549,7 +549,7 @@ cairo_tee_surface_remove (cairo_surface_t *abstract_surface,
cairo_surface_t *
cairo_tee_surface_index (cairo_surface_t *abstract_surface,
int index)
unsigned int index)
{
cairo_tee_surface_t *surface;

View file

@ -55,7 +55,7 @@ cairo_tee_surface_remove (cairo_surface_t *surface,
cairo_public cairo_surface_t *
cairo_tee_surface_index (cairo_surface_t *surface,
int index);
unsigned int index);
CAIRO_END_DECLS

View file

@ -1960,8 +1960,8 @@ blit_with_span_renderer (struct cell_list *cells,
int xmin, int xmax)
{
struct cell *cell = cells->head;
int prev_x = xmin;
int cover = 0;
int prev_x = xmin, last_x = -1;
int cover = 0, last_cover = -1;
cairo_half_open_span_t *spans;
unsigned num_spans;
@ -2005,26 +2005,34 @@ blit_with_span_renderer (struct cell_list *cells,
if (x > prev_x) {
spans[num_spans].x = prev_x;
spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
last_cover = cover;
last_x = prev_x;
++num_spans;
}
cover += cell->covered_height*GRID_X*2;
area = cover - cell->uncovered_area;
spans[num_spans].x = x;
spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area);
++num_spans;
if (area != last_cover) {
spans[num_spans].x = x;
spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area);
last_cover = area;
last_x = x;
++num_spans;
}
prev_x = x+1;
}
if (prev_x <= xmax) {
if (prev_x <= xmax && cover != last_cover) {
spans[num_spans].x = prev_x;
spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
last_cover = cover;
last_x = prev_x;
++num_spans;
}
if (prev_x < xmax && cover) {
if (last_x < xmax && last_cover) {
spans[num_spans].x = xmax;
spans[num_spans].coverage = 0;
++num_spans;

View file

@ -75,6 +75,15 @@ _cairo_traps_limit (cairo_traps_t *traps,
traps->num_limits = num_limits;
}
void
_cairo_traps_init_with_clip (cairo_traps_t *traps,
const cairo_clip_t *clip)
{
_cairo_traps_init (traps);
if (clip)
_cairo_traps_limit (traps, clip->boxes, clip->num_boxes);
}
void
_cairo_traps_clear (cairo_traps_t *traps)
{
@ -485,6 +494,44 @@ _cairo_traps_extents (const cairo_traps_t *traps,
}
}
static cairo_bool_t
_mono_edge_is_vertical (const cairo_line_t *line)
{
return _cairo_fixed_integer_round_down (line->p1.x) == _cairo_fixed_integer_round_down (line->p2.x);
}
static cairo_bool_t
_traps_are_pixel_aligned (cairo_traps_t *traps,
cairo_antialias_t antialias)
{
int i;
if (antialias == CAIRO_ANTIALIAS_NONE) {
for (i = 0; i < traps->num_traps; i++) {
if (! _mono_edge_is_vertical (&traps->traps[i].left) ||
! _mono_edge_is_vertical (&traps->traps[i].right))
{
traps->maybe_region = FALSE;
return FALSE;
}
}
} else {
for (i = 0; i < traps->num_traps; i++) {
if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
! _cairo_fixed_is_integer (traps->traps[i].top) ||
! _cairo_fixed_is_integer (traps->traps[i].bottom) ||
! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) ||
! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
{
traps->maybe_region = FALSE;
return FALSE;
}
}
}
return TRUE;
}
/**
* _cairo_traps_extract_region:
@ -502,6 +549,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
**/
cairo_int_status_t
_cairo_traps_extract_region (cairo_traps_t *traps,
cairo_antialias_t antialias,
cairo_region_t **region)
{
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
@ -510,20 +558,12 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
int i, rect_count;
/* we only treat this a hint... */
if (! traps->maybe_region)
if (antialias != CAIRO_ANTIALIAS_NONE && ! traps->maybe_region)
return CAIRO_INT_STATUS_UNSUPPORTED;
for (i = 0; i < traps->num_traps; i++) {
if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
! _cairo_fixed_is_integer (traps->traps[i].top) ||
! _cairo_fixed_is_integer (traps->traps[i].bottom) ||
! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) ||
! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
{
traps->maybe_region = FALSE;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (! _traps_are_pixel_aligned (traps, antialias)) {
traps->maybe_region = FALSE;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (traps->num_traps > ARRAY_LENGTH (stack_rects)) {
@ -535,19 +575,30 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
rect_count = 0;
for (i = 0; i < traps->num_traps; i++) {
int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
int y1 = _cairo_fixed_integer_part (traps->traps[i].top);
int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
int y2 = _cairo_fixed_integer_part (traps->traps[i].bottom);
int x1, y1, x2, y2;
rects[rect_count].x = x1;
rects[rect_count].y = y1;
rects[rect_count].width = x2 - x1;
rects[rect_count].height = y2 - y1;
if (antialias == CAIRO_ANTIALIAS_NONE) {
x1 = _cairo_fixed_integer_round_down (traps->traps[i].left.p1.x);
y1 = _cairo_fixed_integer_round_down (traps->traps[i].top);
x2 = _cairo_fixed_integer_round_down (traps->traps[i].right.p1.x);
y2 = _cairo_fixed_integer_round_down (traps->traps[i].bottom);
} else {
x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
y1 = _cairo_fixed_integer_part (traps->traps[i].top);
x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
y2 = _cairo_fixed_integer_part (traps->traps[i].bottom);
}
rect_count++;
if (x2 > x1 && y2 > y1) {
rects[rect_count].x = x1;
rects[rect_count].y = y1;
rects[rect_count].width = x2 - x1;
rects[rect_count].height = y2 - y1;
rect_count++;
}
}
*region = cairo_region_create_rectangles (rects, rect_count);
status = (*region)->status;

View file

@ -122,7 +122,8 @@ static cairo_status_t
_cairo_truetype_font_set_error (cairo_truetype_font_t *font,
cairo_status_t status)
{
if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
if (status == CAIRO_STATUS_SUCCESS ||
status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
return status;
_cairo_status_set_error (&font->status, status);
@ -1056,19 +1057,19 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
size = 0;
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_cvt, 0, NULL,
&size) == CAIRO_STATUS_SUCCESS)
&size) == CAIRO_INT_STATUS_SUCCESS)
has_cvt = TRUE;
size = 0;
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_fpgm, 0, NULL,
&size) == CAIRO_STATUS_SUCCESS)
&size) == CAIRO_INT_STATUS_SUCCESS)
has_fpgm = TRUE;
size = 0;
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_prep, 0, NULL,
&size) == CAIRO_STATUS_SUCCESS)
&size) == CAIRO_INT_STATUS_SUCCESS)
has_prep = TRUE;
font->num_tables = 0;
@ -1344,7 +1345,7 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
unsigned long index,
uint32_t *ucs4)
{
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
const cairo_scaled_font_backend_t *backend;
tt_cmap_t *cmap;
char buf[4];

View file

@ -626,7 +626,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
fail:
status2 = _cairo_output_stream_destroy (encrypted_output);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
return status;

View file

@ -188,7 +188,7 @@ static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
const cairo_surface_pattern_t *pattern;
@ -224,7 +224,7 @@ _cairo_type3_glyph_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return _cairo_type3_glyph_surface_paint (abstract_surface,
op, mask,
@ -235,13 +235,13 @@ static cairo_int_status_t
_cairo_type3_glyph_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@ -261,11 +261,11 @@ static cairo_int_status_t
_cairo_type3_glyph_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@ -286,7 +286,7 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
@ -418,7 +418,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status, status2;
cairo_int_status_t status, status2;
cairo_output_stream_t *null_stream;
if (unlikely (surface->base.status))
@ -436,11 +436,11 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
&scaled_glyph);
if (_cairo_status_is_error (status))
if (_cairo_int_status_is_error (status))
goto cleanup;
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
status = CAIRO_STATUS_SUCCESS;
status = CAIRO_INT_STATUS_SUCCESS;
goto cleanup;
}
@ -451,13 +451,13 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
status = CAIRO_STATUS_SUCCESS;
status = CAIRO_INT_STATUS_SUCCESS;
cleanup:
_cairo_scaled_font_thaw_cache (surface->scaled_font);
status2 = _cairo_output_stream_destroy (null_stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
return status;
@ -472,7 +472,7 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status, status2;
cairo_int_status_t status, status2;
double x_advance, y_advance;
cairo_matrix_t font_matrix_inverse;
@ -492,10 +492,10 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
if (_cairo_status_is_error (status)) {
if (_cairo_int_status_is_error (status)) {
_cairo_scaled_font_thaw_cache (surface->scaled_font);
return status;
}
@ -508,7 +508,7 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
/* The invertability of font_matrix is tested in
* pdf_operators_show_glyphs before any glyphs are mapped to the
* subset. */
assert (status2 == CAIRO_STATUS_SUCCESS);
assert (status2 == CAIRO_INT_STATUS_SUCCESS);
cairo_matrix_transform_distance (&font_matrix_inverse, &x_advance, &y_advance);
*width = x_advance;
@ -525,7 +525,7 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
_cairo_fixed_to_double (bbox->p2.x),
- _cairo_fixed_to_double (bbox->p1.y));
if (status == CAIRO_STATUS_SUCCESS) {
if (status == CAIRO_INT_STATUS_SUCCESS) {
cairo_output_stream_t *mem_stream;
mem_stream = _cairo_memory_stream_create ();
@ -540,17 +540,17 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
&surface->base);
status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
_cairo_output_stream_printf (surface->stream, "Q\n");
_cairo_type3_glyph_surface_set_stream (surface, stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
_cairo_memory_stream_copy (mem_stream, stream);
status2 = _cairo_output_stream_destroy (mem_stream);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
}

View file

@ -228,16 +228,7 @@ typedef enum _cairo_paginated_mode {
* from #cairo_status_t. Oh well, without that, I'll use this bogus 100
* offset. We want to keep it fit in int8_t as the compiler may choose
* that for #cairo_status_t */
typedef enum _cairo_int_status {
CAIRO_INT_STATUS_UNSUPPORTED = 100,
CAIRO_INT_STATUS_DEGENERATE,
CAIRO_INT_STATUS_NOTHING_TO_DO,
CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
CAIRO_INT_STATUS_IMAGE_FALLBACK,
CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN,
CAIRO_INT_STATUS_LAST_STATUS
} cairo_int_status_t;
typedef enum _cairo_int_status cairo_int_status_t;
typedef enum _cairo_internal_surface_type {
CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT = 0x1000,

View file

@ -158,7 +158,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
_cairo_scaled_glyph_index(scaled_glyph),
cr, &extents);
if (status == CAIRO_STATUS_SUCCESS)
if (status == CAIRO_INT_STATUS_SUCCESS)
status = cairo_status (cr);
cairo_destroy (cr);
@ -328,11 +328,12 @@ _cairo_user_text_to_glyphs (void *abstract_font,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags);
if (status != CAIRO_STATUS_SUCCESS &&
status != CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED)
if (status != CAIRO_INT_STATUS_SUCCESS &&
status != CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED)
return status;
if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED || *num_glyphs < 0) {
if (status == CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED ||
*num_glyphs < 0) {
if (orig_glyphs != *glyphs) {
cairo_glyph_free (*glyphs);
*glyphs = orig_glyphs;

View file

@ -1167,7 +1167,7 @@ static cairo_int_status_t
_cairo_win32_printing_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_solid_pattern_t clear;
@ -1244,13 +1244,13 @@ static cairo_int_status_t
_cairo_win32_printing_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *stroke_ctm,
const cairo_matrix_t *stroke_ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@ -1373,11 +1373,11 @@ static cairo_int_status_t
_cairo_win32_printing_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@ -1528,7 +1528,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_win32_surface_t *surface = abstract_surface;

View file

@ -1522,7 +1522,7 @@ _cairo_win32_surface_show_glyphs_internal (void *surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs,
cairo_bool_t glyph_indexing)
{
@ -1674,11 +1674,11 @@ cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
int *remaining_glyphs)
const cairo_clip_t *clip,
int *remaining_glyphs)
{
return _cairo_win32_surface_show_glyphs_internal (surface,
op,

View file

@ -360,36 +360,36 @@ cairo_private cairo_int_status_t
_cairo_xcb_surface_cairo_paint (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_cairo_mask (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_cairo_stroke (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_cairo_fill (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t *surface,
@ -398,42 +398,42 @@ _cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t *surface,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_render_paint (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_render_mask (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_render_stroke (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
_cairo_xcb_surface_render_stroke (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
cairo_antialias_t antialias,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_render_fill (cairo_xcb_surface_t *surface,
cairo_operator_t op,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t *surface,
@ -442,7 +442,7 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t *surface,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private void
_cairo_xcb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);

View file

@ -38,7 +38,7 @@ cairo_int_status_t
_cairo_xcb_surface_cairo_paint (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -48,7 +48,7 @@ _cairo_xcb_surface_cairo_mask (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -57,13 +57,13 @@ cairo_int_status_t
_cairo_xcb_surface_cairo_stroke (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -72,11 +72,11 @@ cairo_int_status_t
_cairo_xcb_surface_cairo_fill (cairo_xcb_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -88,7 +88,7 @@ _cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t *surface,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}

File diff suppressed because it is too large Load diff

View file

@ -379,7 +379,7 @@ _get_image (cairo_xcb_surface_t *surface,
cairo_image_surface_t *image;
cairo_xcb_connection_t *connection;
xcb_get_image_reply_t *reply;
cairo_status_t status;
cairo_int_status_t status;
if (surface->base.is_clear || surface->deferred_clear) {
image = (cairo_image_surface_t *)
@ -594,7 +594,7 @@ static cairo_status_t
_put_image (cairo_xcb_surface_t *surface,
cairo_image_surface_t *image)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
/* XXX track damaged region? */
@ -688,10 +688,10 @@ static cairo_int_status_t
_cairo_xcb_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xcb_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
if (surface->fallback == NULL) {
status = _cairo_xcb_surface_cairo_paint (surface, op, source, clip);
@ -713,10 +713,10 @@ _cairo_xcb_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xcb_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
if (surface->fallback == NULL) {
status = _cairo_xcb_surface_cairo_mask (surface,
@ -741,16 +741,16 @@ static cairo_int_status_t
_cairo_xcb_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xcb_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
if (surface->fallback == NULL) {
status = _cairo_xcb_surface_cairo_stroke (surface, op, source,
@ -786,14 +786,14 @@ static cairo_int_status_t
_cairo_xcb_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xcb_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
if (surface->fallback == NULL) {
status = _cairo_xcb_surface_cairo_fill (surface, op, source,
@ -827,11 +827,11 @@ _cairo_xcb_surface_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *num_remaining)
{
cairo_xcb_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_int_status_t status;
*num_remaining = 0;

View file

@ -175,7 +175,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs);
/*
@ -369,6 +369,9 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return NULL;
if (width == 0 || height == 0)
return NULL;
if (! CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (src))
return NULL;
@ -1695,7 +1698,7 @@ _cairo_xlib_surface_can_repaint_solid_pattern_surface (void *abstract_surface,
return CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other);
}
static cairo_status_t
static cairo_int_status_t
_cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
cairo_xlib_surface_t *surface,
const cairo_matrix_t *matrix,
@ -1707,7 +1710,7 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
{
XTransform xtransform;
pixman_transform_t *pixman_transform;
cairo_status_t status;
cairo_int_status_t status;
/* Casting between pixman_transform_t and XTransform is safe because
* they happen to be the exact same type.
@ -1718,8 +1721,8 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
pixman_transform,
x_offset, y_offset);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
status = CAIRO_STATUS_SUCCESS;
if (unlikely (status != CAIRO_STATUS_SUCCESS))
status = CAIRO_INT_STATUS_SUCCESS;
if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
return status;
if (memcmp (&xtransform, &surface->xtransform, sizeof (XTransform)) == 0)
@ -4573,7 +4576,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_display_t *display,
int *remaining_glyphs)
{
int i;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
cairo_scaled_glyph_t *scaled_glyph;
cairo_fixed_t x = 0, y = 0;
cairo_xlib_font_glyphset_info_t *glyphset_info = NULL, *this_glyphset_info;
@ -4725,7 +4728,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_display_t *display,
}
*remaining_glyphs = num_glyphs - i;
if (*remaining_glyphs != 0 && status == CAIRO_STATUS_SUCCESS)
if (*remaining_glyphs != 0 && status == CAIRO_INT_STATUS_SUCCESS)
status = CAIRO_INT_STATUS_UNSUPPORTED;
return status;
@ -4755,7 +4758,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
@ -4779,23 +4782,16 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
* then the entire thing is copied to the destination surface,
* including the fully transparent "background" of the rectangular
* glyph surface. */
if (op == CAIRO_OPERATOR_SOURCE &&
! CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
{
if (op == CAIRO_OPERATOR_SOURCE)
return UNSUPPORTED ("known bug in Render");
}
/* We can only use our code if we either have no clip or
* have a real native clip region set. If we're using
* fallback clip masking, we have to go through the full
* fallback path.
*/
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
if (status)
return status;
}
if (!_cairo_clip_is_region (clip))
return UNSUPPORTED ("clip mask required");
operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
if (operation == DO_UNSUPPORTED)

View file

@ -206,6 +206,7 @@ _format_to_string (cairo_format_t format)
{
switch (format) {
case CAIRO_FORMAT_ARGB32: return "ARGB32";
case CAIRO_FORMAT_RGB30: return "RGB30";
case CAIRO_FORMAT_RGB24: return "RGB24";
case CAIRO_FORMAT_RGB16_565: return "RGB16_565";
case CAIRO_FORMAT_A8: return "A8";
@ -416,7 +417,7 @@ _cairo_xml_close_path (void *closure)
static void
_cairo_xml_emit_path (cairo_xml_t *xml,
cairo_path_fixed_t *path)
const cairo_path_fixed_t *path)
{
cairo_status_t status;
@ -500,7 +501,7 @@ _cairo_xml_surface_emit_clip_path (cairo_xml_surface_t *surface,
static cairo_status_t
_cairo_xml_surface_emit_clip (cairo_xml_surface_t *surface,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
if (clip == NULL)
return CAIRO_STATUS_SUCCESS;
@ -686,7 +687,7 @@ static cairo_int_status_t
_cairo_xml_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xml_surface_t *surface = abstract_surface;
cairo_xml_t *xml = to_xml (surface);
@ -713,10 +714,10 @@ _cairo_xml_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_xml_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip)
{
cairo_xml_surface_t *surface = abstract_surface;
cairo_xml_t *xml = to_xml (surface);
@ -749,13 +750,13 @@ static cairo_int_status_t
_cairo_xml_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xml_surface_t *surface = abstract_surface;
cairo_xml_t *xml = to_xml (surface);
@ -805,11 +806,11 @@ static cairo_int_status_t
_cairo_xml_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
cairo_xml_surface_t *surface = abstract_surface;
cairo_xml_t *xml = to_xml (surface);
@ -924,7 +925,7 @@ _cairo_xml_emit_scaled_font (cairo_xml_t *xml,
cairo_glyph_t *glyphs,
int num_glyphs)
{
cairo_status_t status;
cairo_int_status_t status;
_cairo_xml_printf (xml, "<scaled-font>");
_cairo_xml_indent (xml, 2);
@ -948,7 +949,7 @@ _cairo_xml_surface_glyphs (void *abstract_surface,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_xml_surface_t *surface = abstract_surface;

View file

@ -744,7 +744,8 @@ struct _cairo_surface_backend {
void *dst,
cairo_antialias_t antialias,
const cairo_composite_rectangles_t *rects,
cairo_region_t *clip_region);
cairo_region_t *clip_region);
cairo_warn cairo_bool_t
(*check_span_renderer) (cairo_operator_t op,
@ -818,36 +819,36 @@ struct _cairo_surface_backend {
(*paint) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_warn cairo_int_status_t
(*mask) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_warn cairo_int_status_t
(*stroke) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_warn cairo_int_status_t
(*fill) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_warn cairo_int_status_t
(*show_glyphs) (void *surface,
@ -856,7 +857,7 @@ struct _cairo_surface_backend {
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs);
cairo_surface_t *
@ -873,7 +874,7 @@ struct _cairo_surface_backend {
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_operator_t stroke_op,
const cairo_pattern_t *stroke_source,
const cairo_stroke_style_t *stroke_style,
@ -881,7 +882,7 @@ struct _cairo_surface_backend {
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_surface_t *
(*create_solid_pattern_surface)
@ -908,7 +909,7 @@ struct _cairo_surface_backend {
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_warn cairo_status_t
(*acquire_source_image_transformed) (void *abstract_surface,
@ -1357,14 +1358,21 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path,
double tolerance,
cairo_polygon_t *polygon);
cairo_private cairo_status_t
_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path,
cairo_antialias_t antialias,
cairo_polygon_t *polygon);
cairo_private cairo_int_status_t
_cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_traps_t *traps);
cairo_private cairo_status_t
_cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias,
cairo_boxes_t *boxes);
cairo_private cairo_region_t *
@ -1391,12 +1399,14 @@ cairo_private cairo_int_status_t
_cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
cairo_antialias_t antialias,
cairo_traps_t *traps);
cairo_private cairo_int_status_t
_cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path,
const cairo_stroke_style_t *stroke_style,
const cairo_matrix_t *ctm,
cairo_antialias_t antialias,
cairo_boxes_t *boxes);
cairo_private cairo_int_status_t
@ -1656,14 +1666,14 @@ cairo_private cairo_status_t
_cairo_surface_paint (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_mask (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fill_stroke (cairo_surface_t *surface,
@ -1680,29 +1690,29 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
const cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_fill (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
@ -1716,7 +1726,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip);
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t op,
@ -2025,6 +2035,19 @@ _cairo_polygon_init (cairo_polygon_t *polygon,
const cairo_box_t *boxes,
int num_boxes);
cairo_private void
_cairo_polygon_init_with_clip (cairo_polygon_t *polygon,
const cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
const cairo_boxes_t *boxes);
cairo_private cairo_status_t
_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
cairo_box_t *boxes,
int num_boxes);
cairo_private void
_cairo_polygon_fini (cairo_polygon_t *polygon);
@ -2039,6 +2062,14 @@ _cairo_polygon_add_external_edge (void *polygon,
const cairo_point_t *p1,
const cairo_point_t *p2);
cairo_private cairo_status_t
_cairo_polygon_reduce (cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule);
cairo_private cairo_status_t
_cairo_polygon_intersect (cairo_polygon_t *a, int winding_a,
cairo_polygon_t *b, int winding_b);
#define _cairo_polygon_status(P) ((cairo_polygon_t *) (P))->status
/* cairo-spline.c */
@ -2128,6 +2159,10 @@ _cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t *matrix,
cairo_private void
_cairo_traps_init (cairo_traps_t *traps);
cairo_private void
_cairo_traps_init_with_clip (cairo_traps_t *traps,
const cairo_clip_t *clip);
cairo_private void
_cairo_traps_limit (cairo_traps_t *traps,
const cairo_box_t *boxes,
@ -2200,6 +2235,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
cairo_private cairo_int_status_t
_cairo_traps_extract_region (cairo_traps_t *traps,
cairo_antialias_t antialias,
cairo_region_t **region);
cairo_private cairo_status_t
@ -2454,6 +2490,9 @@ cairo_private void
_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path);
cairo_private void
_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip);
_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon);
cairo_private void
_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip);
#endif

View file

@ -56,36 +56,36 @@ typedef cairo_int_status_t
(*_paint_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_mask_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_stroke_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_fill_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t*path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip);
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_show_glyphs_func) (void *surface,
@ -94,7 +94,7 @@ typedef cairo_int_status_t
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip,
const cairo_clip_t *clip,
int *remaining_glyphs);
typedef cairo_int_status_t
@ -109,7 +109,7 @@ typedef cairo_int_status_t
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip);
const cairo_clip_t *clip);
static cairo_surface_t *
_cairo_null_surface_create_similar (void *other,

View file

@ -122,7 +122,7 @@ static cairo_int_status_t
_test_paginated_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_paginated_surface_t *surface = abstract_surface;
@ -137,7 +137,7 @@ _test_paginated_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_paginated_surface_t *surface = abstract_surface;
@ -152,13 +152,13 @@ static cairo_int_status_t
_test_paginated_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_paginated_surface_t *surface = abstract_surface;
@ -176,11 +176,11 @@ static cairo_int_status_t
_test_paginated_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_paginated_surface_t *surface = abstract_surface;
@ -213,7 +213,7 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_paginated_surface_t *surface = abstract_surface;

View file

@ -138,7 +138,7 @@ static cairo_int_status_t
_test_wrapping_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_wrapping_surface_t *surface = abstract_surface;
@ -150,7 +150,7 @@ _test_wrapping_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_wrapping_surface_t *surface = abstract_surface;
@ -162,13 +162,13 @@ static cairo_int_status_t
_test_wrapping_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_wrapping_surface_t *surface = abstract_surface;
@ -184,11 +184,11 @@ static cairo_int_status_t
_test_wrapping_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_wrapping_surface_t *surface = abstract_surface;
@ -219,7 +219,7 @@ _test_wrapping_surface_show_text_glyphs (void *abstract_surface,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
cairo_clip_t *clip)
const cairo_clip_t *clip)
{
test_wrapping_surface_t *surface = abstract_surface;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB