Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1892 | Rev 3959 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | * Chris Wilson |
33 | * Chris Wilson |
34 | */ |
34 | */ |
Line 35... | Line 35... | ||
35 | 35 | ||
Line -... | Line 36... | ||
- | 36 | #include "cairoint.h" |
|
36 | #include "cairoint.h" |
37 | |
37 | 38 | #include "cairo-clip-inline.h" |
|
- | 39 | #include "cairo-error-private.h" |
|
Line 38... | Line 40... | ||
38 | #include "cairo-error-private.h" |
40 | #include "cairo-composite-rectangles-private.h" |
Line -... | Line 41... | ||
- | 41 | #include "cairo-pattern-private.h" |
|
- | 42 | ||
- | 43 | /* A collection of routines to facilitate writing compositors. */ |
|
- | 44 | ||
- | 45 | void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents) |
|
- | 46 | { |
|
- | 47 | _cairo_clip_destroy (extents->clip); |
|
- | 48 | } |
|
- | 49 | ||
- | 50 | static void |
|
- | 51 | _cairo_composite_reduce_pattern (const cairo_pattern_t *src, |
|
- | 52 | cairo_pattern_union_t *dst) |
|
- | 53 | { |
|
- | 54 | int tx, ty; |
|
- | 55 | ||
- | 56 | _cairo_pattern_init_static_copy (&dst->base, src); |
|
- | 57 | if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID) |
|
- | 58 | return; |
|
- | 59 | ||
- | 60 | dst->base.filter = _cairo_pattern_analyze_filter (&dst->base, NULL), |
|
- | 61 | ||
- | 62 | tx = ty = 0; |
|
- | 63 | if (_cairo_matrix_is_pixman_translation (&dst->base.matrix, |
|
- | 64 | dst->base.filter, |
|
- | 65 | &tx, &ty)) |
|
- | 66 | { |
|
- | 67 | dst->base.matrix.x0 = tx; |
|
39 | #include "cairo-composite-rectangles-private.h" |
68 | dst->base.matrix.y0 = ty; |
40 | 69 | } |
|
41 | /* A collection of routines to facilitate writing compositors. */ |
70 | } |
42 | 71 | ||
43 | static inline cairo_bool_t |
72 | static inline cairo_bool_t |
44 | _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents, |
73 | _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents, |
45 | int width, int height, |
74 | cairo_surface_t *surface, |
46 | cairo_operator_t op, |
- | |
47 | const cairo_pattern_t *source, |
75 | cairo_operator_t op, |
48 | cairo_clip_t *clip) |
76 | const cairo_pattern_t *source, |
Line 49... | Line 77... | ||
49 | { |
77 | const cairo_clip_t *clip) |
50 | extents->unbounded.x = extents->unbounded.y = 0; |
78 | { |
Line 51... | Line 79... | ||
51 | extents->unbounded.width = width; |
79 | if (_cairo_clip_is_all_clipped (clip)) |
52 | extents->unbounded.height = height; |
80 | return FALSE; |
53 | - | ||
Line -... | Line 81... | ||
- | 81 | ||
54 | if (clip != NULL) { |
82 | extents->surface = surface; |
- | 83 | extents->op = op; |
|
55 | const cairo_rectangle_int_t *clip_extents; |
84 | |
56 | - | ||
Line 57... | Line 85... | ||
57 | clip_extents = _cairo_clip_get_extents (clip); |
85 | _cairo_surface_get_extents (surface, &extents->destination); |
58 | if (clip_extents == NULL) |
86 | extents->clip = NULL; |
Line -... | Line 87... | ||
- | 87 | ||
- | 88 | extents->unbounded = extents->destination; |
|
- | 89 | if (clip && ! _cairo_rectangle_intersect (&extents->unbounded, |
|
59 | return FALSE; |
90 | _cairo_clip_get_extents (clip))) |
- | 91 | return FALSE; |
|
60 | 92 | ||
61 | if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents)) |
93 | extents->bounded = extents->unbounded; |
62 | return FALSE; |
94 | extents->is_bounded = _cairo_operator_bounded_by_either (op); |
63 | } |
95 | |
Line -... | Line 96... | ||
- | 96 | extents->original_source_pattern = source; |
|
- | 97 | _cairo_composite_reduce_pattern (source, &extents->source_pattern); |
|
- | 98 | ||
- | 99 | _cairo_pattern_get_extents (&extents->source_pattern.base, |
|
- | 100 | &extents->source); |
|
64 | 101 | if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) { |
|
65 | extents->bounded = extents->unbounded; |
102 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source)) |
Line 66... | Line 103... | ||
66 | extents->is_bounded = _cairo_operator_bounded_by_either (op); |
103 | return FALSE; |
67 | 104 | } |
|
68 | _cairo_pattern_get_extents (source, &extents->source); |
105 | |
69 | if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) { |
106 | extents->original_mask_pattern = NULL; |
70 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source)) |
107 | extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID; |
71 | return FALSE; |
108 | extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */ |
72 | } |
109 | extents->mask_pattern.solid.color.alpha_short = 0xffff; |
73 | 110 | ||
74 | return TRUE; |
- | |
75 | } |
111 | return TRUE; |
76 | 112 | } |
|
77 | cairo_int_status_t |
113 | |
78 | _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents, |
114 | cairo_int_status_t |
Line 79... | Line 115... | ||
79 | int surface_width, int surface_height, |
115 | _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents, |
- | 116 | cairo_surface_t *surface, |
|
- | 117 | cairo_operator_t op, |
|
- | 118 | const cairo_pattern_t *source, |
|
- | 119 | const cairo_clip_t *clip) |
|
- | 120 | { |
|
- | 121 | if (! _cairo_composite_rectangles_init (extents, |
|
- | 122 | surface, op, source, clip)) |
|
- | 123 | { |
|
- | 124 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 125 | } |
|
- | 126 | ||
- | 127 | extents->mask = extents->destination; |
|
- | 128 | ||
- | 129 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
|
80 | cairo_operator_t op, |
130 | if (_cairo_clip_is_all_clipped (extents->clip)) |
81 | const cairo_pattern_t *source, |
131 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
Line 82... | Line 132... | ||
82 | cairo_clip_t *clip) |
132 | |
83 | { |
133 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
- | 134 | _cairo_clip_get_extents (extents->clip))) |
|
84 | if (! _cairo_composite_rectangles_init (extents, |
135 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
85 | surface_width, surface_height, |
136 | |
Line 86... | Line 137... | ||
86 | op, source, clip)) |
137 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
87 | { |
138 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
88 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
139 | &extents->bounded, |
Line -... | Line 140... | ||
- | 140 | &extents->source_sample_area); |
|
- | 141 | ||
- | 142 | return CAIRO_STATUS_SUCCESS; |
|
- | 143 | } |
|
- | 144 | ||
- | 145 | static cairo_int_status_t |
|
- | 146 | _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents, |
|
- | 147 | const cairo_clip_t *clip) |
|
- | 148 | { |
|
- | 149 | cairo_bool_t ret; |
|
- | 150 | ||
- | 151 | ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask); |
|
- | 152 | if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
|
- | 153 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 154 | ||
- | 155 | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
|
- | 156 | extents->unbounded = extents->bounded; |
|
- | 157 | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
|
- | 158 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
|
- | 159 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 160 | } |
|
- | 161 | ||
- | 162 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
|
- | 163 | if (_cairo_clip_is_all_clipped (extents->clip)) |
|
- | 164 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 165 | ||
- | 166 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
|
- | 167 | _cairo_clip_get_extents (extents->clip))) |
|
- | 168 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 169 | ||
- | 170 | if (! _cairo_rectangle_intersect (&extents->bounded, |
|
- | 171 | _cairo_clip_get_extents (extents->clip)) && |
|
- | 172 | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
|
- | 173 | { |
|
- | 174 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 175 | } |
|
- | 176 | ||
89 | } |
177 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
90 | 178 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
|
Line 91... | Line 179... | ||
91 | extents->mask = extents->bounded; |
179 | &extents->bounded, |
- | 180 | &extents->source_sample_area); |
|
- | 181 | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
|
- | 182 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
|
- | 183 | &extents->bounded, |
|
- | 184 | &extents->mask_sample_area); |
|
- | 185 | if (extents->mask_sample_area.width == 0 || |
|
- | 186 | extents->mask_sample_area.height == 0) { |
|
- | 187 | _cairo_composite_rectangles_fini (extents); |
|
- | 188 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 189 | } |
|
- | 190 | } |
|
- | 191 | ||
- | 192 | return CAIRO_STATUS_SUCCESS; |
|
- | 193 | } |
|
- | 194 | ||
- | 195 | cairo_int_status_t |
|
- | 196 | _cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents, |
|
- | 197 | const cairo_box_t *box) |
|
- | 198 | { |
|
- | 199 | cairo_rectangle_int_t rect; |
|
- | 200 | cairo_clip_t *clip; |
|
- | 201 | ||
- | 202 | _cairo_box_round_to_rectangle (box, &rect); |
|
- | 203 | if (rect.x == extents->source.x && |
|
- | 204 | rect.y == extents->source.y && |
|
- | 205 | rect.width == extents->source.width && |
|
- | 206 | rect.height == extents->source.height) |
|
- | 207 | { |
|
- | 208 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 209 | } |
|
- | 210 | ||
- | 211 | _cairo_rectangle_intersect (&extents->source, &rect); |
|
- | 212 | ||
- | 213 | rect = extents->bounded; |
|
- | 214 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) && |
|
- | 215 | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) |
|
- | 216 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 217 | ||
- | 218 | if (rect.width == extents->bounded.width && |
|
- | 219 | rect.height == extents->bounded.height) |
|
- | 220 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 221 | ||
- | 222 | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
|
- | 223 | extents->unbounded = extents->bounded; |
|
- | 224 | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
|
- | 225 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
|
- | 226 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 227 | } |
|
- | 228 | ||
- | 229 | clip = extents->clip; |
|
- | 230 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
|
- | 231 | if (clip != extents->clip) |
|
- | 232 | _cairo_clip_destroy (clip); |
|
- | 233 | ||
- | 234 | if (_cairo_clip_is_all_clipped (extents->clip)) |
|
- | 235 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 236 | ||
- | 237 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
|
- | 238 | _cairo_clip_get_extents (extents->clip))) |
|
- | 239 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 240 | ||
- | 241 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
|
- | 242 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
|
- | 243 | &extents->bounded, |
|
- | 244 | &extents->source_sample_area); |
|
- | 245 | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
|
- | 246 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
|
- | 247 | &extents->bounded, |
|
- | 248 | &extents->mask_sample_area); |
|
- | 249 | if (extents->mask_sample_area.width == 0 || |
|
- | 250 | extents->mask_sample_area.height == 0) |
|
- | 251 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 252 | } |
|
- | 253 | ||
- | 254 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 255 | } |
|
- | 256 | ||
- | 257 | cairo_int_status_t |
|
- | 258 | _cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents, |
|
- | 259 | const cairo_box_t *box) |
|
- | 260 | { |
|
- | 261 | cairo_rectangle_int_t mask; |
|
- | 262 | cairo_clip_t *clip; |
|
- | 263 | ||
- | 264 | _cairo_box_round_to_rectangle (box, &mask); |
|
- | 265 | if (mask.x == extents->mask.x && |
|
- | 266 | mask.y == extents->mask.y && |
|
- | 267 | mask.width == extents->mask.width && |
|
- | 268 | mask.height == extents->mask.height) |
|
- | 269 | { |
|
- | 270 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 271 | } |
|
- | 272 | ||
- | 273 | _cairo_rectangle_intersect (&extents->mask, &mask); |
|
- | 274 | ||
- | 275 | mask = extents->bounded; |
|
- | 276 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) && |
|
- | 277 | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
|
- | 278 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 279 | ||
- | 280 | if (mask.width == extents->bounded.width && |
|
- | 281 | mask.height == extents->bounded.height) |
|
- | 282 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 283 | ||
- | 284 | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
|
- | 285 | extents->unbounded = extents->bounded; |
|
- | 286 | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
|
- | 287 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
|
- | 288 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 289 | } |
|
- | 290 | ||
- | 291 | clip = extents->clip; |
|
- | 292 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
|
- | 293 | if (clip != extents->clip) |
|
- | 294 | _cairo_clip_destroy (clip); |
|
- | 295 | ||
- | 296 | if (_cairo_clip_is_all_clipped (extents->clip)) |
|
- | 297 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 298 | ||
- | 299 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
|
- | 300 | _cairo_clip_get_extents (extents->clip))) |
|
- | 301 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 302 | ||
- | 303 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
|
92 | return CAIRO_STATUS_SUCCESS; |
304 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
93 | } |
305 | &extents->bounded, |
94 | 306 | &extents->source_sample_area); |
|
95 | static cairo_int_status_t |
307 | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
96 | _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents) |
308 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
97 | { |
309 | &extents->bounded, |
98 | cairo_bool_t ret; |
310 | &extents->mask_sample_area); |
99 | 311 | if (extents->mask_sample_area.width == 0 || |
|
100 | ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask); |
- | |
101 | if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
312 | extents->mask_sample_area.height == 0) |
102 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
313 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
103 | 314 | } |
|
104 | return CAIRO_STATUS_SUCCESS; |
315 | |
Line -... | Line 316... | ||
- | 316 | return CAIRO_INT_STATUS_SUCCESS; |
|
- | 317 | } |
|
105 | } |
318 | |
Line 106... | Line 319... | ||
106 | 319 | cairo_int_status_t |
|
107 | cairo_int_status_t |
320 | _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents, |
Line 108... | Line 321... | ||
108 | _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents, |
321 | cairo_surface_t*surface, |
109 | int surface_width, int surface_height, |
322 | cairo_operator_t op, |
110 | cairo_operator_t op, |
323 | const cairo_pattern_t *source, |
111 | const cairo_pattern_t *source, |
324 | const cairo_pattern_t *mask, |
112 | const cairo_pattern_t *mask, |
325 | const cairo_clip_t *clip) |
113 | cairo_clip_t *clip) |
326 | { |
114 | { |
327 | if (! _cairo_composite_rectangles_init (extents, |
115 | if (! _cairo_composite_rectangles_init (extents, |
328 | surface, op, source, clip)) |
116 | surface_width, surface_height, |
329 | { |
117 | op, source, clip)) |
330 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
118 | { |
331 | } |
119 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
- | |
120 | } |
332 | |
121 | 333 | extents->original_mask_pattern = mask; |
|
122 | _cairo_pattern_get_extents (mask, &extents->mask); |
334 | _cairo_composite_reduce_pattern (mask, &extents->mask_pattern); |
123 | 335 | _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask); |
|
Line 124... | Line 336... | ||
124 | return _cairo_composite_rectangles_intersect (extents); |
336 | |
Line 125... | Line 337... | ||
125 | } |
337 | return _cairo_composite_rectangles_intersect (extents, clip); |
126 | 338 | } |
|
Line 127... | Line 339... | ||
127 | cairo_int_status_t |
339 | |
128 | _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents, |
340 | cairo_int_status_t |
129 | int surface_width, int surface_height, |
341 | _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents, |
130 | cairo_operator_t op, |
342 | cairo_surface_t *surface, |
131 | const cairo_pattern_t *source, |
343 | cairo_operator_t op, |
132 | cairo_path_fixed_t *path, |
344 | const cairo_pattern_t *source, |
133 | const cairo_stroke_style_t *style, |
345 | const cairo_path_fixed_t *path, |
134 | const cairo_matrix_t *ctm, |
346 | const cairo_stroke_style_t *style, |
135 | cairo_clip_t *clip) |
347 | const cairo_matrix_t *ctm, |
136 | { |
- | |
137 | if (! _cairo_composite_rectangles_init (extents, |
348 | const cairo_clip_t *clip) |
138 | surface_width, surface_height, |
349 | { |
139 | op, source, clip)) |
350 | if (! _cairo_composite_rectangles_init (extents, |
140 | { |
351 | surface, op, source, clip)) |
Line 141... | Line 352... | ||
141 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
352 | { |
Line -... | Line 353... | ||
- | 353 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 354 | } |
|
- | 355 | ||
- | 356 | _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask); |
|
- | 357 | ||
- | 358 | return _cairo_composite_rectangles_intersect (extents, clip); |
|
- | 359 | } |
|
- | 360 | ||
- | 361 | cairo_int_status_t |
|
- | 362 | _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents, |
|
- | 363 | cairo_surface_t *surface, |
|
- | 364 | cairo_operator_t op, |
|
- | 365 | const cairo_pattern_t *source, |
|
- | 366 | const cairo_path_fixed_t *path, |
|
- | 367 | const cairo_clip_t *clip) |
|
- | 368 | { |
|
- | 369 | if (! _cairo_composite_rectangles_init (extents, |
|
- | 370 | surface, op, source, clip)) |
|
- | 371 | { |
|
- | 372 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 373 | } |
|
- | 374 | ||
- | 375 | _cairo_path_fixed_approximate_fill_extents (path, &extents->mask); |
|
- | 376 | ||
- | 377 | return _cairo_composite_rectangles_intersect (extents, clip); |
|
- | 378 | } |
|
- | 379 | ||
- | 380 | cairo_int_status_t |
|
- | 381 | _cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents, |
|
- | 382 | cairo_surface_t *surface, |
|
- | 383 | cairo_operator_t op, |
|
- | 384 | const cairo_pattern_t *source, |
|
- | 385 | const cairo_polygon_t *polygon, |
|
- | 386 | const cairo_clip_t *clip) |
|
- | 387 | { |
|
- | 388 | if (! _cairo_composite_rectangles_init (extents, |
|
- | 389 | surface, op, source, clip)) |
|
- | 390 | { |
|
- | 391 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
142 | } |
392 | } |
143 | 393 | ||
Line 144... | Line 394... | ||
144 | _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask); |
394 | _cairo_box_round_to_rectangle (&polygon->extents, &extents->mask); |
145 | 395 | return _cairo_composite_rectangles_intersect (extents, clip); |
|
146 | return _cairo_composite_rectangles_intersect (extents); |
396 | } |
147 | } |
397 | |
148 | 398 | cairo_int_status_t |
|
149 | cairo_int_status_t |
399 | _cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents, |
150 | _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents, |
400 | cairo_surface_t *surface, |
151 | int surface_width, int surface_height, |
401 | cairo_operator_t op, |
152 | cairo_operator_t op, |
402 | const cairo_pattern_t *source, |
153 | const cairo_pattern_t *source, |
403 | const cairo_boxes_t *boxes, |
154 | cairo_path_fixed_t *path, |
404 | const cairo_clip_t *clip) |
155 | cairo_clip_t *clip) |
405 | { |
Line 156... | Line 406... | ||
156 | { |
406 | cairo_box_t box; |
- | 407 | ||
- | 408 | if (! _cairo_composite_rectangles_init (extents, |
|
- | 409 | surface, op, source, clip)) |
|
- | 410 | { |
|
- | 411 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 412 | } |
|
- | 413 | ||
157 | if (! _cairo_composite_rectangles_init (extents, |
414 | _cairo_boxes_extents (boxes, &box); |
158 | surface_width, surface_height, |
415 | _cairo_box_round_to_rectangle (&box, &extents->mask); |
159 | op, source, clip)) |
416 | return _cairo_composite_rectangles_intersect (extents, clip); |
- | 417 | } |
|
160 | { |
418 | |
161 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
419 | cairo_int_status_t |
Line 162... | Line 420... | ||
162 | } |
420 | _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents, |
163 | 421 | cairo_surface_t *surface, |
|
164 | _cairo_path_fixed_approximate_fill_extents (path, &extents->mask); |
422 | cairo_operator_t op, |
165 | 423 | const cairo_pattern_t *source, |
|
166 | return _cairo_composite_rectangles_intersect (extents); |
424 | cairo_scaled_font_t *scaled_font, |
167 | } |
425 | cairo_glyph_t *glyphs, |
Line -... | Line 426... | ||
- | 426 | int num_glyphs, |
|
- | 427 | const cairo_clip_t *clip, |
|
- | 428 | cairo_bool_t *overlap) |
|
- | 429 | { |
|
- | 430 | cairo_status_t status; |
|
- | 431 | ||
- | 432 | if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip)) |
|
168 | 433 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 434 | ||
- | 435 | /* Computing the exact bbox and the overlap is expensive. |
|
- | 436 | * First perform a cheap test to see if the glyphs are all clipped out. |
|
- | 437 | */ |
|
- | 438 | if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK && |
|
- | 439 | _cairo_scaled_font_glyph_approximate_extents (scaled_font, |
|
- | 440 | glyphs, num_glyphs, |
|
- | 441 | &extents->mask)) |
|
- | 442 | { |
|
- | 443 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask)) |
|
- | 444 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
- | 445 | } |
|
- | 446 | ||
- | 447 | status = _cairo_scaled_font_glyph_device_extents (scaled_font, |
|
- | 448 | glyphs, num_glyphs, |
|
- | 449 | &extents->mask, |
|
- | 450 | overlap); |
|
- | 451 | if (unlikely (status)) |
|
- | 452 | return status; |
|
- | 453 | ||
- | 454 | if (overlap && *overlap && |
|
- | 455 | scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE && |
|
- | 456 | _cairo_pattern_is_opaque_solid (&extents->source_pattern.base)) |
|
- | 457 | { |
|
- | 458 | *overlap = FALSE; |
|
- | 459 | } |
|
- | 460 | ||
- | 461 | return _cairo_composite_rectangles_intersect (extents, clip); |
|
- | 462 | } |
|
- | 463 | ||
- | 464 | cairo_bool_t |
|
- | 465 | _cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, |
|
- | 466 | cairo_clip_t *clip) |
|
- | 467 | { |
|
- | 468 | cairo_rectangle_int_t extents; |
|
- | 469 | cairo_box_t box; |
|
- | 470 | ||
- | 471 | if (clip == NULL) |
|
169 | cairo_int_status_t |
472 | return TRUE; |