File: | root/firefox-clang/gfx/cairo/cairo/src/cairo-tee-surface.c |
Warning: | line 499, column 2 Value stored to 'status' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* cairo - a vector graphics library with display and print output |
2 | * |
3 | * Copyright © 2005 Red Hat, Inc |
4 | * Copyright © 2009 Chris Wilson |
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 Red Hat, Inc. |
32 | * |
33 | * Contributor(s): |
34 | * Carl Worth <cworth@cworth.org> |
35 | * Chris Wilson <chris@chris-wilson.co.uk> |
36 | */ |
37 | |
38 | /** |
39 | * SECTION:cairo-tee |
40 | * @Title: Tee surface |
41 | * @Short_Description: Redirect input to multiple surfaces |
42 | * @See_Also: #cairo_surface_t |
43 | * |
44 | * The "tee" surface supports redirecting all its input to multiple surfaces. |
45 | **/ |
46 | |
47 | /** |
48 | * CAIRO_HAS_TEE_SURFACE: |
49 | * |
50 | * Defined if the tee surface backend is available. |
51 | * |
52 | * Since: 1.10 |
53 | **/ |
54 | |
55 | #include "cairoint.h" |
56 | |
57 | #include "cairo-tee.h" |
58 | |
59 | #include "cairo-default-context-private.h" |
60 | #include "cairo-error-private.h" |
61 | #include "cairo-recording-surface-inline.h" |
62 | #include "cairo-surface-wrapper-private.h" |
63 | #include "cairo-array-private.h" |
64 | #include "cairo-image-surface-inline.h" |
65 | |
66 | typedef struct _cairo_tee_surface { |
67 | cairo_surface_t base; |
68 | |
69 | cairo_surface_wrapper_t primary; |
70 | cairo_array_t replicas; |
71 | } cairo_tee_surface_t; |
72 | |
73 | static cairo_surface_t * |
74 | _cairo_tee_surface_create_similar (void *abstract_surface, |
75 | cairo_content_t content, |
76 | int width, |
77 | int height) |
78 | { |
79 | |
80 | cairo_tee_surface_t *other = abstract_surface; |
81 | cairo_surface_t *similar; |
82 | cairo_surface_t *surface; |
83 | cairo_surface_wrapper_t *replicas; |
84 | int n, num_replicas; |
85 | |
86 | similar = _cairo_surface_wrapper_create_similar (&other->primary, |
87 | content, width, height); |
88 | surface = cairo_tee_surface_create_moz_cairo_tee_surface_create (similar); |
89 | cairo_surface_destroy_moz_cairo_surface_destroy (similar); |
90 | if (unlikely (surface->status)(__builtin_expect (!!(surface->status), 0))) |
91 | return surface; |
92 | |
93 | num_replicas = _cairo_array_num_elements (&other->replicas); |
94 | replicas = _cairo_array_index (&other->replicas, 0); |
95 | for (n = 0; n < num_replicas; n++) { |
96 | |
97 | similar = _cairo_surface_wrapper_create_similar (&replicas[n], |
98 | content, |
99 | width, height); |
100 | cairo_tee_surface_add_moz_cairo_tee_surface_add (surface, similar); |
101 | cairo_surface_destroy_moz_cairo_surface_destroy (similar); |
102 | } |
103 | |
104 | if (unlikely (surface->status)(__builtin_expect (!!(surface->status), 0))) { |
105 | cairo_status_t status = surface->status; |
106 | cairo_surface_destroy_moz_cairo_surface_destroy (surface); |
107 | surface = _cairo_surface_create_in_error (status); |
108 | } |
109 | |
110 | return surface; |
111 | } |
112 | |
113 | static cairo_status_t |
114 | _cairo_tee_surface_finish (void *abstract_surface) |
115 | { |
116 | cairo_tee_surface_t *surface = abstract_surface; |
117 | cairo_surface_wrapper_t *replicas; |
118 | int n, num_replicas; |
119 | |
120 | _cairo_surface_wrapper_fini (&surface->primary); |
121 | |
122 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
123 | replicas = _cairo_array_index (&surface->replicas, 0); |
124 | for (n = 0; n < num_replicas; n++) |
125 | _cairo_surface_wrapper_fini (&replicas[n]); |
126 | |
127 | _cairo_array_fini (&surface->replicas); |
128 | |
129 | return CAIRO_STATUS_SUCCESS; |
130 | } |
131 | |
132 | static cairo_surface_t * |
133 | _cairo_tee_surface_source (void *abstract_surface, |
134 | cairo_rectangle_int_t *extents) |
135 | { |
136 | cairo_tee_surface_t *surface = abstract_surface; |
137 | return _cairo_surface_get_source (surface->primary.target, extents); |
138 | } |
139 | |
140 | static cairo_status_t |
141 | _cairo_tee_surface_acquire_source_image (void *abstract_surface, |
142 | cairo_image_surface_t **image_out, |
143 | void **image_extra) |
144 | { |
145 | cairo_tee_surface_t *surface = abstract_surface; |
146 | cairo_surface_wrapper_t *replicas; |
147 | int num_replicas, n; |
148 | |
149 | /* we prefer to use a real image surface if available */ |
150 | if (_cairo_surface_is_image (surface->primary.target)) { |
151 | return _cairo_surface_wrapper_acquire_source_image (&surface->primary, |
152 | image_out, image_extra); |
153 | } |
154 | |
155 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
156 | replicas = _cairo_array_index (&surface->replicas, 0); |
157 | for (n = 0; n < num_replicas; n++) { |
158 | if (_cairo_surface_is_image (replicas[n].target)) { |
159 | return _cairo_surface_wrapper_acquire_source_image (&replicas[n], |
160 | image_out, |
161 | image_extra); |
162 | } |
163 | } |
164 | |
165 | return _cairo_surface_wrapper_acquire_source_image (&surface->primary, |
166 | image_out, image_extra); |
167 | } |
168 | |
169 | static void |
170 | _cairo_tee_surface_release_source_image (void *abstract_surface, |
171 | cairo_image_surface_t *image, |
172 | void *image_extra) |
173 | { |
174 | cairo_tee_surface_t *surface = abstract_surface; |
175 | |
176 | _cairo_surface_wrapper_release_source_image (&surface->primary, |
177 | image, image_extra); |
178 | } |
179 | |
180 | static cairo_surface_t * |
181 | _cairo_tee_surface_snapshot (void *abstract_surface) |
182 | { |
183 | cairo_tee_surface_t *surface = abstract_surface; |
184 | cairo_surface_wrapper_t *replicas; |
185 | int num_replicas, n; |
186 | |
187 | /* we prefer to use a recording surface for our snapshots */ |
188 | if (_cairo_surface_is_recording (surface->primary.target)) |
189 | return _cairo_surface_wrapper_snapshot (&surface->primary); |
190 | |
191 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
192 | replicas = _cairo_array_index (&surface->replicas, 0); |
193 | for (n = 0; n < num_replicas; n++) { |
194 | if (_cairo_surface_is_recording (replicas[n].target)) |
195 | return _cairo_surface_wrapper_snapshot (&replicas[n]); |
196 | } |
197 | |
198 | return _cairo_surface_wrapper_snapshot (&surface->primary); |
199 | } |
200 | |
201 | static cairo_bool_t |
202 | _cairo_tee_surface_get_extents (void *abstract_surface, |
203 | cairo_rectangle_int_t *rectangle) |
204 | { |
205 | cairo_tee_surface_t *surface = abstract_surface; |
206 | |
207 | return _cairo_surface_wrapper_get_extents (&surface->primary, rectangle); |
208 | } |
209 | |
210 | static void |
211 | _cairo_tee_surface_get_font_options (void *abstract_surface, |
212 | cairo_font_options_t *options) |
213 | { |
214 | cairo_tee_surface_t *surface = abstract_surface; |
215 | |
216 | _cairo_surface_wrapper_get_font_options (&surface->primary, options); |
217 | } |
218 | |
219 | static cairo_int_status_t |
220 | _cairo_tee_surface_paint (void *abstract_surface, |
221 | cairo_operator_t op, |
222 | const cairo_pattern_t *source, |
223 | const cairo_clip_t *clip) |
224 | { |
225 | cairo_tee_surface_t *surface = abstract_surface; |
226 | cairo_surface_wrapper_t *replicas; |
227 | int n, num_replicas; |
228 | cairo_int_status_t status; |
229 | |
230 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
231 | replicas = _cairo_array_index (&surface->replicas, 0); |
232 | for (n = 0; n < num_replicas; n++) { |
233 | status = _cairo_surface_wrapper_paint (&replicas[n], op, source, 0, clip); |
234 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
235 | return status; |
236 | } |
237 | |
238 | return _cairo_surface_wrapper_paint (&surface->primary, op, source, 0, clip); |
239 | } |
240 | |
241 | static cairo_int_status_t |
242 | _cairo_tee_surface_mask (void *abstract_surface, |
243 | cairo_operator_t op, |
244 | const cairo_pattern_t *source, |
245 | const cairo_pattern_t *mask, |
246 | const cairo_clip_t *clip) |
247 | { |
248 | cairo_tee_surface_t *surface = abstract_surface; |
249 | cairo_surface_wrapper_t *replicas; |
250 | cairo_int_status_t status; |
251 | int n, num_replicas; |
252 | |
253 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
254 | replicas = _cairo_array_index (&surface->replicas, 0); |
255 | for (n = 0; n < num_replicas; n++) { |
256 | status = _cairo_surface_wrapper_mask (&replicas[n], |
257 | op, source, 0, |
258 | mask, 0, |
259 | clip); |
260 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
261 | return status; |
262 | } |
263 | |
264 | return _cairo_surface_wrapper_mask (&surface->primary, |
265 | op, source, 0, |
266 | mask, 0, |
267 | clip); |
268 | } |
269 | |
270 | static cairo_int_status_t |
271 | _cairo_tee_surface_stroke (void *abstract_surface, |
272 | cairo_operator_t op, |
273 | const cairo_pattern_t *source, |
274 | const cairo_path_fixed_t *path, |
275 | const cairo_stroke_style_t *style, |
276 | const cairo_matrix_t *ctm, |
277 | const cairo_matrix_t *ctm_inverse, |
278 | double tolerance, |
279 | cairo_antialias_t antialias, |
280 | const cairo_clip_t *clip) |
281 | { |
282 | cairo_tee_surface_t *surface = abstract_surface; |
283 | cairo_surface_wrapper_t *replicas; |
284 | cairo_int_status_t status; |
285 | int n, num_replicas; |
286 | |
287 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
288 | replicas = _cairo_array_index (&surface->replicas, 0); |
289 | for (n = 0; n < num_replicas; n++) { |
290 | status = _cairo_surface_wrapper_stroke (&replicas[n], |
291 | op, source, 0, |
292 | path, style, |
293 | ctm, ctm_inverse, |
294 | tolerance, antialias, |
295 | clip); |
296 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
297 | return status; |
298 | } |
299 | |
300 | return _cairo_surface_wrapper_stroke (&surface->primary, |
301 | op, source, 0, |
302 | path, style, |
303 | ctm, ctm_inverse, |
304 | tolerance, antialias, |
305 | clip); |
306 | } |
307 | |
308 | static cairo_int_status_t |
309 | _cairo_tee_surface_fill (void *abstract_surface, |
310 | cairo_operator_t op, |
311 | const cairo_pattern_t *source, |
312 | const cairo_path_fixed_t *path, |
313 | cairo_fill_rule_t fill_rule, |
314 | double tolerance, |
315 | cairo_antialias_t antialias, |
316 | const cairo_clip_t *clip) |
317 | { |
318 | cairo_tee_surface_t *surface = abstract_surface; |
319 | cairo_surface_wrapper_t *replicas; |
320 | cairo_int_status_t status; |
321 | int n, num_replicas; |
322 | |
323 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
324 | replicas = _cairo_array_index (&surface->replicas, 0); |
325 | for (n = 0; n < num_replicas; n++) { |
326 | status = _cairo_surface_wrapper_fill (&replicas[n], |
327 | op, source, 0, |
328 | path, fill_rule, |
329 | tolerance, antialias, |
330 | clip); |
331 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
332 | return status; |
333 | } |
334 | |
335 | return _cairo_surface_wrapper_fill (&surface->primary, |
336 | op, source, 0, |
337 | path, fill_rule, |
338 | tolerance, antialias, |
339 | clip); |
340 | } |
341 | |
342 | static cairo_bool_t |
343 | _cairo_tee_surface_has_show_text_glyphs (void *abstract_surface) |
344 | { |
345 | return TRUE1; |
346 | } |
347 | |
348 | static cairo_int_status_t |
349 | _cairo_tee_surface_show_text_glyphs (void *abstract_surface, |
350 | cairo_operator_t op, |
351 | const cairo_pattern_t *source, |
352 | const char *utf8, |
353 | int utf8_len, |
354 | cairo_glyph_t *glyphs, |
355 | int num_glyphs, |
356 | const cairo_text_cluster_t *clusters, |
357 | int num_clusters, |
358 | cairo_text_cluster_flags_t cluster_flags, |
359 | cairo_scaled_font_t *scaled_font, |
360 | const cairo_clip_t *clip) |
361 | { |
362 | cairo_tee_surface_t *surface = abstract_surface; |
363 | cairo_surface_wrapper_t *replicas; |
364 | cairo_int_status_t status; |
365 | int n, num_replicas; |
366 | cairo_glyph_t *glyphs_copy; |
367 | |
368 | /* XXX: This copying is ugly. */ |
369 | glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
370 | if (unlikely (glyphs_copy == NULL)(__builtin_expect (!!(glyphs_copy == ((void*)0)), 0))) |
371 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
372 | |
373 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
374 | replicas = _cairo_array_index (&surface->replicas, 0); |
375 | for (n = 0; n < num_replicas; n++) { |
376 | memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); |
377 | status = _cairo_surface_wrapper_show_text_glyphs (&replicas[n], op, |
378 | source, 0, |
379 | utf8, utf8_len, |
380 | glyphs_copy, num_glyphs, |
381 | clusters, num_clusters, |
382 | cluster_flags, |
383 | scaled_font, |
384 | clip); |
385 | if (unlikely (status)(__builtin_expect (!!(status), 0))) |
386 | goto CLEANUP; |
387 | } |
388 | |
389 | memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); |
390 | status = _cairo_surface_wrapper_show_text_glyphs (&surface->primary, op, |
391 | source, 0, |
392 | utf8, utf8_len, |
393 | glyphs_copy, num_glyphs, |
394 | clusters, num_clusters, |
395 | cluster_flags, |
396 | scaled_font, |
397 | clip); |
398 | CLEANUP: |
399 | free (glyphs_copy); |
400 | return status; |
401 | } |
402 | |
403 | static const cairo_surface_backend_t cairo_tee_surface_backend = { |
404 | CAIRO_SURFACE_TYPE_TEE, |
405 | _cairo_tee_surface_finish, |
406 | |
407 | _cairo_default_context_create, /* XXX */ |
408 | |
409 | _cairo_tee_surface_create_similar, |
410 | NULL((void*)0), /* create similar image */ |
411 | NULL((void*)0), /* map to image */ |
412 | NULL((void*)0), /* unmap image */ |
413 | |
414 | _cairo_tee_surface_source, |
415 | _cairo_tee_surface_acquire_source_image, |
416 | _cairo_tee_surface_release_source_image, |
417 | _cairo_tee_surface_snapshot, |
418 | NULL((void*)0), /* copy_page */ |
419 | NULL((void*)0), /* show_page */ |
420 | _cairo_tee_surface_get_extents, |
421 | _cairo_tee_surface_get_font_options, |
422 | NULL((void*)0), /* flush */ |
423 | NULL((void*)0), /* mark_dirty_rectangle */ |
424 | |
425 | _cairo_tee_surface_paint, |
426 | _cairo_tee_surface_mask, |
427 | _cairo_tee_surface_stroke, |
428 | _cairo_tee_surface_fill, |
429 | NULL((void*)0), /* fill_stroke */ |
430 | |
431 | NULL((void*)0), /* show_glyphs */ |
432 | |
433 | _cairo_tee_surface_has_show_text_glyphs, |
434 | _cairo_tee_surface_show_text_glyphs |
435 | }; |
436 | |
437 | /** |
438 | * cairo_tee_surface_create: |
439 | * @primary: the primary #cairo_surface_t |
440 | * |
441 | * Creates a new "tee" surface. |
442 | * |
443 | * The @primary surface is used when querying surface options, like |
444 | * font options and extents. |
445 | * |
446 | * Operations performed on the tee surface will be replayed on any |
447 | * surface added to it. |
448 | * |
449 | * Returns: the newly created surface |
450 | * |
451 | * Since: 1.10 |
452 | **/ |
453 | cairo_surface_t * |
454 | cairo_tee_surface_create_moz_cairo_tee_surface_create (cairo_surface_t *primary) |
455 | { |
456 | cairo_tee_surface_t *surface; |
457 | |
458 | if (unlikely (primary->status)(__builtin_expect (!!(primary->status), 0))) |
459 | return _cairo_surface_create_in_error (primary->status); |
460 | |
461 | surface = _cairo_malloc (sizeof (cairo_tee_surface_t))((sizeof (cairo_tee_surface_t)) != 0 ? malloc(sizeof (cairo_tee_surface_t )) : ((void*)0)); |
462 | if (unlikely (surface == NULL)(__builtin_expect (!!(surface == ((void*)0)), 0))) |
463 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
464 | |
465 | _cairo_surface_init (&surface->base, |
466 | &cairo_tee_surface_backend, |
467 | primary->device, |
468 | primary->content, |
469 | TRUE1); /* is_vector */ |
470 | |
471 | _cairo_surface_wrapper_init (&surface->primary, primary); |
472 | |
473 | _cairo_array_init (&surface->replicas, sizeof (cairo_surface_wrapper_t)); |
474 | |
475 | return &surface->base; |
476 | } |
477 | |
478 | /** |
479 | * cairo_tee_surface_add: |
480 | * @abstract_surface: a #cairo_tee_surface_t |
481 | * @target: the surface to add |
482 | * |
483 | * Adds a new target surface to the list of replicas of a |
484 | * tee surface. |
485 | * |
486 | * Since: 1.10 |
487 | **/ |
488 | void |
489 | cairo_tee_surface_add_moz_cairo_tee_surface_add (cairo_surface_t *abstract_surface, |
490 | cairo_surface_t *target) |
491 | { |
492 | cairo_tee_surface_t *surface; |
493 | cairo_surface_wrapper_t replica; |
494 | cairo_status_t status; |
495 | |
496 | if (unlikely (abstract_surface->status)(__builtin_expect (!!(abstract_surface->status), 0))) |
497 | return; |
498 | if (unlikely (abstract_surface->finished)(__builtin_expect (!!(abstract_surface->finished), 0))) { |
499 | status = _cairo_surface_set_error (abstract_surface, |
Value stored to 'status' is never read | |
500 | _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
501 | return; |
502 | } |
503 | |
504 | if (abstract_surface->backend != &cairo_tee_surface_backend) { |
505 | status = _cairo_surface_set_error (abstract_surface, |
506 | _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); |
507 | return; |
508 | } |
509 | |
510 | if (unlikely (target->status)(__builtin_expect (!!(target->status), 0))) { |
511 | status = _cairo_surface_set_error (abstract_surface, target->status); |
512 | return; |
513 | } |
514 | |
515 | surface = (cairo_tee_surface_t *) abstract_surface; |
516 | |
517 | _cairo_surface_wrapper_init (&replica, target); |
518 | status = _cairo_array_append (&surface->replicas, &replica); |
519 | if (unlikely (status)(__builtin_expect (!!(status), 0))) { |
520 | _cairo_surface_wrapper_fini (&replica); |
521 | status = _cairo_surface_set_error (&surface->base, status); |
522 | } |
523 | } |
524 | |
525 | /** |
526 | * cairo_tee_surface_remove: |
527 | * @abstract_surface: a #cairo_tee_surface_t |
528 | * @target: the surface to remove |
529 | * |
530 | * Removes the given surface from the list of replicas of a |
531 | * tee surface. |
532 | * |
533 | * Since: 1.10 |
534 | **/ |
535 | void |
536 | cairo_tee_surface_remove_moz_cairo_tee_surface_remove (cairo_surface_t *abstract_surface, |
537 | cairo_surface_t *target) |
538 | { |
539 | cairo_tee_surface_t *surface; |
540 | cairo_surface_wrapper_t *replicas; |
541 | int n, num_replicas; |
542 | |
543 | if (unlikely (abstract_surface->status)(__builtin_expect (!!(abstract_surface->status), 0))) |
544 | return; |
545 | if (unlikely (abstract_surface->finished)(__builtin_expect (!!(abstract_surface->finished), 0))) { |
546 | _cairo_surface_set_error (abstract_surface, |
547 | _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
548 | return; |
549 | } |
550 | |
551 | if (abstract_surface->backend != &cairo_tee_surface_backend) { |
552 | _cairo_surface_set_error (abstract_surface, |
553 | _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); |
554 | return; |
555 | } |
556 | |
557 | surface = (cairo_tee_surface_t *) abstract_surface; |
558 | if (target == surface->primary.target) { |
559 | _cairo_surface_set_error (abstract_surface, |
560 | _cairo_error (CAIRO_STATUS_INVALID_INDEX)); |
561 | return; |
562 | } |
563 | |
564 | num_replicas = _cairo_array_num_elements (&surface->replicas); |
565 | replicas = _cairo_array_index (&surface->replicas, 0); |
566 | for (n = 0; n < num_replicas; n++) { |
567 | if (replicas[n].target == target) |
568 | break; |
569 | } |
570 | |
571 | if (n == num_replicas) { |
572 | _cairo_surface_set_error (abstract_surface, |
573 | _cairo_error (CAIRO_STATUS_INVALID_INDEX)); |
574 | return; |
575 | } |
576 | |
577 | _cairo_surface_wrapper_fini (&replicas[n]); |
578 | for (n++; n < num_replicas; n++) |
579 | replicas[n-1] = replicas[n]; |
580 | surface->replicas.num_elements--; /* XXX: cairo_array_remove()? */ |
581 | } |
582 | |
583 | /** |
584 | * cairo_tee_surface_index: |
585 | * @abstract_surface: a #cairo_tee_surface_t |
586 | * @index: the index of the replica to retrieve |
587 | * |
588 | * Retrieves the replica surface at the given index. |
589 | * |
590 | * The primary surface used to create the #cairo_tee_surface_t is |
591 | * always set at the zero index. |
592 | * |
593 | * Returns: the surface at the given index |
594 | * |
595 | * Since: 1.10 |
596 | **/ |
597 | cairo_surface_t * |
598 | cairo_tee_surface_index_moz_cairo_tee_surface_index (cairo_surface_t *abstract_surface, |
599 | unsigned int index) |
600 | { |
601 | cairo_tee_surface_t *surface; |
602 | |
603 | if (unlikely (abstract_surface->status)(__builtin_expect (!!(abstract_surface->status), 0))) |
604 | return _cairo_surface_create_in_error (abstract_surface->status); |
605 | if (unlikely (abstract_surface->finished)(__builtin_expect (!!(abstract_surface->finished), 0))) |
606 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
607 | |
608 | if (abstract_surface->backend != &cairo_tee_surface_backend) |
609 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); |
610 | |
611 | surface = (cairo_tee_surface_t *) abstract_surface; |
612 | if (index == 0) { |
613 | return surface->primary.target; |
614 | } else { |
615 | cairo_surface_wrapper_t *replica; |
616 | |
617 | index--; |
618 | |
619 | if (index >= _cairo_array_num_elements (&surface->replicas)) |
620 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_INDEX)); |
621 | |
622 | replica = _cairo_array_index (&surface->replicas, index); |
623 | return replica->target; |
624 | } |
625 | } |