Line data Source code
1 : /* cairo - a vector graphics library with display and print output
2 : *
3 : * Copyright © 2009 Intel Corporation
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it either under the terms of the GNU Lesser General Public
7 : * License version 2.1 as published by the Free Software Foundation
8 : * (the "LGPL") or, at your option, under the terms of the Mozilla
9 : * Public License Version 1.1 (the "MPL"). If you do not alter this
10 : * notice, a recipient may use your version of this file under either
11 : * the MPL or the LGPL.
12 : *
13 : * You should have received a copy of the LGPL along with this library
14 : * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 : * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 : * You should have received a copy of the MPL along with this library
17 : * in the file COPYING-MPL-1.1
18 : *
19 : * The contents of this file are subject to the Mozilla Public License
20 : * Version 1.1 (the "License"); you may not use this file except in
21 : * compliance with the License. You may obtain a copy of the License at
22 : * http://www.mozilla.org/MPL/
23 : *
24 : * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 : * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 : * the specific language governing rights and limitations.
27 : *
28 : * The Original Code is the cairo graphics library.
29 : *
30 : * The Initial Developer of the Original Code is Red Hat, Inc.
31 : *
32 : * Contributor(s):
33 : * Chris Wilson <chris@chris-wilson.co.uk>
34 : */
35 :
36 : #include "cairoint.h"
37 :
38 : #include "cairo-error-private.h"
39 : #include "cairo-composite-rectangles-private.h"
40 :
41 : /* A collection of routines to facilitate writing compositors. */
42 :
43 : static inline cairo_bool_t
44 0 : _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
45 : const cairo_rectangle_int_t *surface_extents,
46 : cairo_operator_t op,
47 : const cairo_pattern_t *source,
48 : cairo_clip_t *clip)
49 : {
50 0 : extents->unbounded = *surface_extents;
51 :
52 0 : if (clip != NULL) {
53 : const cairo_rectangle_int_t *clip_extents;
54 :
55 0 : clip_extents = _cairo_clip_get_extents (clip);
56 0 : if (clip_extents == NULL)
57 0 : return FALSE;
58 :
59 0 : if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
60 0 : return FALSE;
61 : }
62 :
63 0 : extents->bounded = extents->unbounded;
64 0 : extents->is_bounded = _cairo_operator_bounded_by_either (op);
65 :
66 0 : _cairo_pattern_get_extents (source, &extents->source);
67 0 : if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
68 0 : if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
69 0 : return FALSE;
70 : }
71 :
72 0 : return TRUE;
73 : }
74 :
75 : cairo_int_status_t
76 0 : _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
77 : const cairo_rectangle_int_t *surface_extents,
78 : cairo_operator_t op,
79 : const cairo_pattern_t *source,
80 : cairo_clip_t *clip)
81 : {
82 0 : if (! _cairo_composite_rectangles_init (extents,
83 : surface_extents,
84 : op, source, clip))
85 : {
86 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
87 : }
88 :
89 0 : extents->mask = extents->bounded;
90 0 : return CAIRO_STATUS_SUCCESS;
91 : }
92 :
93 : static cairo_int_status_t
94 0 : _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
95 : {
96 : cairo_bool_t ret;
97 :
98 0 : ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
99 0 : if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
100 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
101 :
102 0 : return CAIRO_STATUS_SUCCESS;
103 : }
104 :
105 : cairo_int_status_t
106 0 : _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
107 : const cairo_rectangle_int_t *surface_extents,
108 : cairo_operator_t op,
109 : const cairo_pattern_t *source,
110 : const cairo_pattern_t *mask,
111 : cairo_clip_t *clip)
112 : {
113 0 : if (! _cairo_composite_rectangles_init (extents,
114 : surface_extents,
115 : op, source, clip))
116 : {
117 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
118 : }
119 :
120 0 : _cairo_pattern_get_extents (mask, &extents->mask);
121 :
122 0 : return _cairo_composite_rectangles_intersect (extents);
123 : }
124 :
125 : cairo_int_status_t
126 0 : _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
127 : const cairo_rectangle_int_t *surface_extents,
128 : cairo_operator_t op,
129 : const cairo_pattern_t *source,
130 : cairo_path_fixed_t *path,
131 : const cairo_stroke_style_t *style,
132 : const cairo_matrix_t *ctm,
133 : cairo_clip_t *clip)
134 : {
135 0 : if (! _cairo_composite_rectangles_init (extents,
136 : surface_extents,
137 : op, source, clip))
138 : {
139 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
140 : }
141 :
142 0 : _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
143 :
144 0 : return _cairo_composite_rectangles_intersect (extents);
145 : }
146 :
147 : cairo_int_status_t
148 0 : _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
149 : const cairo_rectangle_int_t *surface_extents,
150 : cairo_operator_t op,
151 : const cairo_pattern_t *source,
152 : cairo_path_fixed_t *path,
153 : cairo_clip_t *clip)
154 : {
155 0 : if (! _cairo_composite_rectangles_init (extents,
156 : surface_extents,
157 : op, source, clip))
158 : {
159 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
160 : }
161 :
162 0 : _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
163 :
164 0 : return _cairo_composite_rectangles_intersect (extents);
165 : }
166 :
167 : cairo_int_status_t
168 0 : _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
169 : const cairo_rectangle_int_t *surface_extents,
170 : cairo_operator_t op,
171 : const cairo_pattern_t *source,
172 : cairo_scaled_font_t *scaled_font,
173 : cairo_glyph_t *glyphs,
174 : int num_glyphs,
175 : cairo_clip_t *clip,
176 : cairo_bool_t *overlap)
177 : {
178 : cairo_status_t status;
179 :
180 0 : if (! _cairo_composite_rectangles_init (extents,
181 : surface_extents,
182 : op, source, clip))
183 : {
184 0 : return CAIRO_INT_STATUS_NOTHING_TO_DO;
185 : }
186 :
187 0 : status = _cairo_scaled_font_glyph_device_extents (scaled_font,
188 : glyphs, num_glyphs,
189 : &extents->mask,
190 : overlap);
191 0 : if (unlikely (status))
192 0 : return status;
193 :
194 0 : return _cairo_composite_rectangles_intersect (extents);
195 : }
|