Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2011 Intel Corporation
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is University of Southern
32
 * California.
33
 *
34
 * Contributor(s):
35
 *	Chris Wilson 
36
 */
37
 
38
#include "cairoint.h"
39
#include "cairo-clip-inline.h"
40
#include "cairo-clip-private.h"
41
#include "cairo-error-private.h"
42
#include "cairo-freed-pool-private.h"
43
#include "cairo-gstate-private.h"
44
#include "cairo-path-fixed-private.h"
45
#include "cairo-pattern-private.h"
46
#include "cairo-composite-rectangles-private.h"
47
#include "cairo-region-private.h"
48
 
49
static cairo_bool_t
50
can_convert_to_polygon (const cairo_clip_t *clip)
51
{
52
    cairo_clip_path_t *clip_path = clip->path;
53
    cairo_antialias_t antialias = clip_path->antialias;
54
 
55
    while ((clip_path = clip_path->prev) != NULL) {
56
	if (clip_path->antialias != antialias)
57
	    return FALSE;
58
    }
59
 
60
    return TRUE;
61
}
62
 
63
cairo_int_status_t
64
_cairo_clip_get_polygon (const cairo_clip_t *clip,
65
			 cairo_polygon_t *polygon,
66
			 cairo_fill_rule_t *fill_rule,
67
			 cairo_antialias_t *antialias)
68
{
69
    cairo_status_t status;
70
    cairo_clip_path_t *clip_path;
71
 
72
    if (_cairo_clip_is_all_clipped (clip)) {
73
	_cairo_polygon_init (polygon, NULL, 0);
74
	return CAIRO_INT_STATUS_SUCCESS;
75
    }
76
 
77
    /* If there is no clip, we need an infinite polygon */
78
    assert (clip && (clip->path || clip->num_boxes));
79
 
80
    if (clip->path == NULL) {
81
	*fill_rule = CAIRO_FILL_RULE_WINDING;
82
	*antialias = CAIRO_ANTIALIAS_DEFAULT;
83
	return _cairo_polygon_init_box_array (polygon,
84
					      clip->boxes,
85
					      clip->num_boxes);
86
    }
87
 
88
    /* check that residual is all of the same type/tolerance */
89
    if (! can_convert_to_polygon (clip))
90
	return CAIRO_INT_STATUS_UNSUPPORTED;
91
 
92
    if (clip->num_boxes < 2)
93
	_cairo_polygon_init_with_clip (polygon, clip);
94
    else
95
	_cairo_polygon_init_with_clip (polygon, NULL);
96
 
97
    clip_path = clip->path;
98
    *fill_rule = clip_path->fill_rule;
99
    *antialias = clip_path->antialias;
100
 
101
    status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
102
						clip_path->tolerance,
103
						polygon);
104
    if (unlikely (status))
105
	goto err;
106
 
107
    if (clip->num_boxes > 1) {
108
	status = _cairo_polygon_intersect_with_boxes (polygon, fill_rule,
109
						      clip->boxes, clip->num_boxes);
110
	if (unlikely (status))
111
	    goto err;
112
    }
113
 
114
    polygon->limits = NULL;
115
    polygon->num_limits = 0;
116
 
117
    while ((clip_path = clip_path->prev) != NULL) {
118
	cairo_polygon_t next;
119
 
120
	_cairo_polygon_init (&next, NULL, 0);
121
	status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
122
						    clip_path->tolerance,
123
						    &next);
124
	if (likely (status == CAIRO_STATUS_SUCCESS))
125
		status = _cairo_polygon_intersect (polygon, *fill_rule,
126
						   &next, clip_path->fill_rule);
127
	_cairo_polygon_fini (&next);
128
	if (unlikely (status))
129
	    goto err;
130
 
131
	*fill_rule = CAIRO_FILL_RULE_WINDING;
132
    }
133
 
134
    return CAIRO_STATUS_SUCCESS;
135
 
136
err:
137
    _cairo_polygon_fini (polygon);
138
    return status;
139
}
140
 
141
cairo_bool_t
142
_cairo_clip_is_polygon (const cairo_clip_t *clip)
143
{
144
    if (_cairo_clip_is_all_clipped (clip))
145
	return TRUE;
146
 
147
    /* If there is no clip, we need an infinite polygon */
148
    if (clip == NULL)
149
	return FALSE;
150
 
151
    if (clip->path == NULL)
152
	return TRUE;
153
 
154
    /* check that residual is all of the same type/tolerance */
155
    return can_convert_to_polygon (clip);
156
}