Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-boxes-intersect.c
Warning:line 254, column 1
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cairo-boxes-intersect.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_FT_LOAD_SFNT_TABLE -D PACKAGE_VERSION="moz" -D PACKAGE_BUGREPORT="http://bugzilla.mozilla.org/" -D CAIRO_HAS_PTHREAD -D _GNU_SOURCE -D MOZ_TREE_PIXMAN -D SIZEOF_VOID_P=__SIZEOF_POINTER__ -D SIZEOF_INT=__SIZEOF_INT__ -D SIZEOF_LONG=__SIZEOF_LONG__ -D SIZEOF_LONG_LONG=__SIZEOF_LONG_LONG__ -D HAVE_UINT64_T -D HAVE_CXX11_ATOMIC_PRIMITIVES -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/libpng16 -U NDEBUG -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-enum-compare -Wno-int-to-pointer-cast -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-sign-compare -Wno-type-limits -Wno-missing-field-initializers -Wno-conversion -Wno-narrowing -Wno-switch -Wno-unused -Wno-unused-variable -Wno-error=uninitialized -Wno-absolute-value -Wno-deprecated-register -Wno-incompatible-pointer-types -Wno-macro-redefined -Wno-shift-negative-value -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -Wno-unreachable-code -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c /root/firefox-clang/gfx/cairo/cairo/src/cairo-boxes-intersect.c
1/*
2 * Copyright © 2004 Carl Worth
3 * Copyright © 2006 Red Hat, Inc.
4 * Copyright © 2009 Chris Wilson
5 * Copyright © 2011 Intel Corporation
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
14 *
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
20 *
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
25 *
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
29 *
30 * The Original Code is the cairo graphics library.
31 *
32 * The Initial Developer of the Original Code is Carl Worth
33 *
34 * Contributor(s):
35 * Carl D. Worth <cworth@cworth.org>
36 * Chris Wilson <chris@chris-wilson.co.uk>
37 */
38
39/* Provide definitions for standalone compilation */
40#include "cairoint.h"
41
42#include "cairo-boxes-private.h"
43#include "cairo-error-private.h"
44#include "cairo-combsort-inline.h"
45#include "cairo-list-private.h"
46
47#include <setjmp.h>
48
49typedef struct _rectangle rectangle_t;
50typedef struct _edge edge_t;
51
52struct _edge {
53 edge_t *next, *prev;
54 edge_t *right;
55 cairo_fixed_t x, top;
56 int a_or_b;
57 int dir;
58};
59
60struct _rectangle {
61 edge_t left, right;
62 int32_t top, bottom;
63};
64
65#define UNROLL3(x)x x x x x x
66
67/* the parent is always given by index/2 */
68#define PQ_PARENT_INDEX(i)((i) >> 1) ((i) >> 1)
69#define PQ_FIRST_ENTRY1 1
70
71/* left and right children are index * 2 and (index * 2) +1 respectively */
72#define PQ_LEFT_CHILD_INDEX(i)((i) << 1) ((i) << 1)
73
74typedef struct _pqueue {
75 int size, max_size;
76
77 rectangle_t **elements;
78 rectangle_t *elements_embedded[1024];
79} pqueue_t;
80
81typedef struct _sweep_line {
82 rectangle_t **rectangles;
83 pqueue_t pq;
84 edge_t head, tail;
85 edge_t *insert_left, *insert_right;
86 int32_t current_y;
87 int32_t last_y;
88
89 jmp_buf unwind;
90} sweep_line_t;
91
92#define DEBUG_TRAPS0 0
93
94#if DEBUG_TRAPS0
95static void
96dump_traps (cairo_traps_t *traps, const char *filename)
97{
98 FILE *file;
99 int n;
100
101 if (getenv ("CAIRO_DEBUG_TRAPS") == NULL((void*)0))
102 return;
103
104 file = fopen (filename, "a");
105 if (file != NULL((void*)0)) {
106 for (n = 0; n < traps->num_traps; n++) {
107 fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n",
108 traps->traps[n].top,
109 traps->traps[n].bottom,
110 traps->traps[n].left.p1.x,
111 traps->traps[n].left.p1.y,
112 traps->traps[n].left.p2.x,
113 traps->traps[n].left.p2.y,
114 traps->traps[n].right.p1.x,
115 traps->traps[n].right.p1.y,
116 traps->traps[n].right.p2.x,
117 traps->traps[n].right.p2.y);
118 }
119 fprintf (file, "\n");
120 fclose (file);
121 }
122}
123#else
124#define dump_traps(traps, filename)
125#endif
126
127static inline int
128rectangle_compare_start (const rectangle_t *a,
129 const rectangle_t *b)
130{
131 return a->top - b->top;
132}
133
134static inline int
135rectangle_compare_stop (const rectangle_t *a,
136 const rectangle_t *b)
137{
138 return a->bottom - b->bottom;
139}
140
141static inline void
142pqueue_init (pqueue_t *pq)
143{
144 pq->max_size = ARRAY_LENGTH (pq->elements_embedded)((int) (sizeof (pq->elements_embedded) / sizeof (pq->elements_embedded
[0])))
;
145 pq->size = 0;
146
147 pq->elements = pq->elements_embedded;
148 pq->elements[PQ_FIRST_ENTRY1] = NULL((void*)0);
149}
150
151static inline void
152pqueue_fini (pqueue_t *pq)
153{
154 if (pq->elements != pq->elements_embedded)
155 free (pq->elements);
156}
157
158static cairo_bool_t
159pqueue_grow (pqueue_t *pq)
160{
161 rectangle_t **new_elements;
162 pq->max_size *= 2;
163
164 if (pq->elements == pq->elements_embedded) {
165 new_elements = _cairo_malloc_ab (pq->max_size,
166 sizeof (rectangle_t *));
167 if (unlikely (new_elements == NULL)(__builtin_expect (!!(new_elements == ((void*)0)), 0)))
168 return FALSE0;
169
170 memcpy (new_elements, pq->elements_embedded,
171 sizeof (pq->elements_embedded));
172 } else {
173 new_elements = _cairo_realloc_ab (pq->elements,
174 pq->max_size,
175 sizeof (rectangle_t *));
176 if (unlikely (new_elements == NULL)(__builtin_expect (!!(new_elements == ((void*)0)), 0)))
177 return FALSE0;
178 }
179
180 pq->elements = new_elements;
181 return TRUE1;
182}
183
184static inline void
185pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
186{
187 rectangle_t **elements;
188 int i, parent;
189
190 if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)(__builtin_expect (!!(sweep->pq.size + 1 == sweep->pq.max_size
), 0))
) {
191 if (unlikely (! pqueue_grow (&sweep->pq))(__builtin_expect (!!(! pqueue_grow (&sweep->pq)), 0))) {
192 longjmp (sweep->unwind,
193 _cairo_error (CAIRO_STATUS_NO_MEMORY));
194 }
195 }
196
197 elements = sweep->pq.elements;
198 for (i = ++sweep->pq.size;
199 i != PQ_FIRST_ENTRY1 &&
200 rectangle_compare_stop (rectangle,
201 elements[parent = PQ_PARENT_INDEX (i)((i) >> 1)]) < 0;
202 i = parent)
203 {
204 elements[i] = elements[parent];
205 }
206
207 elements[i] = rectangle;
208}
209
210static inline void
211pqueue_pop (pqueue_t *pq)
212{
213 rectangle_t **elements = pq->elements;
214 rectangle_t *tail;
215 int child, i;
216
217 tail = elements[pq->size--];
218 if (pq->size == 0) {
219 elements[PQ_FIRST_ENTRY1] = NULL((void*)0);
220 return;
221 }
222
223 for (i = PQ_FIRST_ENTRY1;
224 (child = PQ_LEFT_CHILD_INDEX (i)((i) << 1)) <= pq->size;
225 i = child)
226 {
227 if (child != pq->size &&
228 rectangle_compare_stop (elements[child+1],
229 elements[child]) < 0)
230 {
231 child++;
232 }
233
234 if (rectangle_compare_stop (elements[child], tail) >= 0)
235 break;
236
237 elements[i] = elements[child];
238 }
239 elements[i] = tail;
240}
241
242static inline rectangle_t *
243rectangle_pop_start (sweep_line_t *sweep_line)
244{
245 return *sweep_line->rectangles++;
246}
247
248static inline rectangle_t *
249rectangle_peek_stop (sweep_line_t *sweep_line)
250{
251 return sweep_line->pq.elements[PQ_FIRST_ENTRY1];
252}
253
254CAIRO_COMBSORT_DECLARE (_rectangle_sort,static void _rectangle_sort (rectangle_t * *base, unsigned int
nmemb) { unsigned int gap = nmemb; unsigned int i, j; int swapped
; do { gap = _cairo_combsort_newgap (gap); swapped = gap >
1; for (i = 0; i < nmemb-gap ; i++) { j = i + gap; if (rectangle_compare_start
(base[i], base[j]) > 0 ) { rectangle_t * tmp; tmp = base[
i]; base[i] = base[j]; base[j] = tmp; swapped = 1; } } } while
(swapped); }
25
The value 0 is assigned to 'i'
26
Loop condition is true. Entering loop body
27
1st function call argument is an uninitialized value
255 rectangle_t *,static void _rectangle_sort (rectangle_t * *base, unsigned int
nmemb) { unsigned int gap = nmemb; unsigned int i, j; int swapped
; do { gap = _cairo_combsort_newgap (gap); swapped = gap >
1; for (i = 0; i < nmemb-gap ; i++) { j = i + gap; if (rectangle_compare_start
(base[i], base[j]) > 0 ) { rectangle_t * tmp; tmp = base[
i]; base[i] = base[j]; base[j] = tmp; swapped = 1; } } } while
(swapped); }
256 rectangle_compare_start)static void _rectangle_sort (rectangle_t * *base, unsigned int
nmemb) { unsigned int gap = nmemb; unsigned int i, j; int swapped
; do { gap = _cairo_combsort_newgap (gap); swapped = gap >
1; for (i = 0; i < nmemb-gap ; i++) { j = i + gap; if (rectangle_compare_start
(base[i], base[j]) > 0 ) { rectangle_t * tmp; tmp = base[
i]; base[i] = base[j]; base[j] = tmp; swapped = 1; } } } while
(swapped); }
257
258static void
259sweep_line_init (sweep_line_t *sweep_line,
260 rectangle_t **rectangles,
261 int num_rectangles)
262{
263 _rectangle_sort (rectangles, num_rectangles);
24
Calling '_rectangle_sort'
264 rectangles[num_rectangles] = NULL((void*)0);
265 sweep_line->rectangles = rectangles;
266
267 sweep_line->head.x = INT32_MIN(-2147483647-1);
268 sweep_line->head.right = NULL((void*)0);
269 sweep_line->head.dir = 0;
270 sweep_line->head.prev = NULL((void*)0);
271 sweep_line->head.next = &sweep_line->tail;
272 sweep_line->tail.x = INT32_MAX(2147483647);
273 sweep_line->tail.right = NULL((void*)0);
274 sweep_line->tail.dir = 0;
275 sweep_line->tail.prev = &sweep_line->head;
276 sweep_line->tail.next = NULL((void*)0);
277
278 sweep_line->insert_left = &sweep_line->tail;
279 sweep_line->insert_right = &sweep_line->tail;
280
281 sweep_line->current_y = INT32_MIN(-2147483647-1);
282 sweep_line->last_y = INT32_MIN(-2147483647-1);
283
284 pqueue_init (&sweep_line->pq);
285}
286
287static void
288sweep_line_fini (sweep_line_t *sweep_line)
289{
290 pqueue_fini (&sweep_line->pq);
291}
292
293static void
294end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot, cairo_boxes_t *out)
295{
296 if (likely (left->top < bot)(__builtin_expect (!!(left->top < bot), 1))) {
297 cairo_status_t status;
298 cairo_box_t box;
299
300 box.p1.x = left->x;
301 box.p1.y = left->top;
302 box.p2.x = left->right->x;
303 box.p2.y = bot;
304
305 status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
306 if (unlikely (status)(__builtin_expect (!!(status), 0)))
307 longjmp (sweep_line->unwind, status);
308 }
309
310 left->right = NULL((void*)0);
311}
312
313/* Start a new trapezoid at the given top y coordinate, whose edges
314 * are `edge' and `edge->next'. If `edge' already has a trapezoid,
315 * then either add it to the traps in `traps', if the trapezoid's
316 * right edge differs from `edge->next', or do nothing if the new
317 * trapezoid would be a continuation of the existing one. */
318static inline void
319start_or_continue_box (sweep_line_t *sweep_line,
320 edge_t *left,
321 edge_t *right,
322 int top,
323 cairo_boxes_t *out)
324{
325 if (left->right == right)
326 return;
327
328 if (left->right != NULL((void*)0)) {
329 if (right != NULL((void*)0) && left->right->x == right->x) {
330 /* continuation on right, so just swap edges */
331 left->right = right;
332 return;
333 }
334
335 end_box (sweep_line, left, top, out);
336 }
337
338 if (right != NULL((void*)0) && left->x != right->x) {
339 left->top = top;
340 left->right = right;
341 }
342}
343
344static inline int is_zero(const int *winding)
345{
346 return winding[0] == 0 || winding[1] == 0;
347}
348
349static inline void
350active_edges (sweep_line_t *sweep, cairo_boxes_t *out)
351{
352 int top = sweep->current_y;
353 int winding[2] = { 0 };
354 edge_t *pos;
355
356 if (sweep->last_y == sweep->current_y)
357 return;
358
359 pos = sweep->head.next;
360 if (pos == &sweep->tail)
361 return;
362
363 do {
364 edge_t *left, *right;
365
366 left = pos;
367 do {
368 winding[left->a_or_b] += left->dir;
369 if (!is_zero (winding))
370 break;
371 if (left->next == &sweep->tail)
372 goto out;
373
374 if (unlikely (left->right != NULL)(__builtin_expect (!!(left->right != ((void*)0)), 0)))
375 end_box (sweep, left, top, out);
376
377 left = left->next;
378 } while (1);
379
380 right = left->next;
381 do {
382 if (unlikely (right->right != NULL)(__builtin_expect (!!(right->right != ((void*)0)), 0)))
383 end_box (sweep, right, top, out);
384
385 winding[right->a_or_b] += right->dir;
386 if (is_zero (winding)) {
387 /* skip co-linear edges */
388 if (likely (right->x != right->next->x)(__builtin_expect (!!(right->x != right->next->x), 1
))
)
389 break;
390 }
391
392 right = right->next;
393 } while (TRUE1);
394
395 start_or_continue_box (sweep, left, right, top, out);
396
397 pos = right->next;
398 } while (pos != &sweep->tail);
399
400out:
401 sweep->last_y = sweep->current_y;
402}
403
404static inline void
405sweep_line_delete_edge (sweep_line_t *sweep_line, edge_t *edge, cairo_boxes_t *out)
406{
407 if (edge->right != NULL((void*)0)) {
408 edge_t *next = edge->next;
409 if (next->x == edge->x) {
410 next->top = edge->top;
411 next->right = edge->right;
412 } else {
413 end_box (sweep_line, edge, sweep_line->current_y, out);
414 }
415 }
416
417 if (sweep_line->insert_left == edge)
418 sweep_line->insert_left = edge->next;
419 if (sweep_line->insert_right == edge)
420 sweep_line->insert_right = edge->next;
421
422 edge->prev->next = edge->next;
423 edge->next->prev = edge->prev;
424}
425
426static inline void
427sweep_line_delete (sweep_line_t *sweep,
428 rectangle_t *rectangle,
429 cairo_boxes_t *out)
430{
431 sweep_line_delete_edge (sweep, &rectangle->left, out);
432 sweep_line_delete_edge (sweep, &rectangle->right, out);
433
434 pqueue_pop (&sweep->pq);
435}
436
437static inline void
438insert_edge (edge_t *edge, edge_t *pos)
439{
440 if (pos->x != edge->x) {
441 if (pos->x > edge->x) {
442 do {
443 UNROLL3({{ if (pos->prev->x <= edge->x) break; pos = pos->
prev; } { if (pos->prev->x <= edge->x) break; pos
= pos->prev; } { if (pos->prev->x <= edge->x)
break; pos = pos->prev; }
444 if (pos->prev->x <= edge->x){ if (pos->prev->x <= edge->x) break; pos = pos->
prev; } { if (pos->prev->x <= edge->x) break; pos
= pos->prev; } { if (pos->prev->x <= edge->x)
break; pos = pos->prev; }
445 break;{ if (pos->prev->x <= edge->x) break; pos = pos->
prev; } { if (pos->prev->x <= edge->x) break; pos
= pos->prev; } { if (pos->prev->x <= edge->x)
break; pos = pos->prev; }
446 pos = pos->prev;{ if (pos->prev->x <= edge->x) break; pos = pos->
prev; } { if (pos->prev->x <= edge->x) break; pos
= pos->prev; } { if (pos->prev->x <= edge->x)
break; pos = pos->prev; }
447 }){ if (pos->prev->x <= edge->x) break; pos = pos->
prev; } { if (pos->prev->x <= edge->x) break; pos
= pos->prev; } { if (pos->prev->x <= edge->x)
break; pos = pos->prev; }
448 } while (TRUE1);
449 } else {
450 do {
451 UNROLL3({{ pos = pos->next; if (pos->x >= edge->x) break; }
{ pos = pos->next; if (pos->x >= edge->x) break;
} { pos = pos->next; if (pos->x >= edge->x) break
; }
452 pos = pos->next;{ pos = pos->next; if (pos->x >= edge->x) break; }
{ pos = pos->next; if (pos->x >= edge->x) break;
} { pos = pos->next; if (pos->x >= edge->x) break
; }
453 if (pos->x >= edge->x){ pos = pos->next; if (pos->x >= edge->x) break; }
{ pos = pos->next; if (pos->x >= edge->x) break;
} { pos = pos->next; if (pos->x >= edge->x) break
; }
454 break;{ pos = pos->next; if (pos->x >= edge->x) break; }
{ pos = pos->next; if (pos->x >= edge->x) break;
} { pos = pos->next; if (pos->x >= edge->x) break
; }
455 }){ pos = pos->next; if (pos->x >= edge->x) break; }
{ pos = pos->next; if (pos->x >= edge->x) break;
} { pos = pos->next; if (pos->x >= edge->x) break
; }
456 } while (TRUE1);
457 }
458 }
459
460 pos->prev->next = edge;
461 edge->prev = pos->prev;
462 edge->next = pos;
463 pos->prev = edge;
464}
465
466static inline void
467sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle)
468{
469 edge_t *pos;
470
471 /* right edge */
472 pos = sweep->insert_right;
473 insert_edge (&rectangle->right, pos);
474 sweep->insert_right = &rectangle->right;
475
476 /* left edge */
477 pos = sweep->insert_left;
478 if (pos->x > sweep->insert_right->x)
479 pos = sweep->insert_right->prev;
480 if (pos == &sweep->head)
481 pos = pos->next;
482 insert_edge (&rectangle->left, pos);
483 sweep->insert_left = &rectangle->left;
484
485 pqueue_push (sweep, rectangle);
486}
487
488static cairo_status_t
489intersect (rectangle_t **rectangles, int num_rectangles, cairo_boxes_t *out)
490{
491 sweep_line_t sweep_line;
492 rectangle_t *rectangle;
493 cairo_status_t status;
494
495 sweep_line_init (&sweep_line, rectangles, num_rectangles);
23
Calling 'sweep_line_init'
496 if ((status = setjmp (sweep_line.unwind)_setjmp (sweep_line.unwind)))
497 goto unwind;
498
499 rectangle = rectangle_pop_start (&sweep_line);
500 do {
501 if (rectangle->top != sweep_line.current_y) {
502 rectangle_t *stop;
503
504 stop = rectangle_peek_stop (&sweep_line);
505 while (stop != NULL((void*)0) && stop->bottom < rectangle->top) {
506 if (stop->bottom != sweep_line.current_y) {
507 active_edges (&sweep_line, out);
508 sweep_line.current_y = stop->bottom;
509 }
510
511 sweep_line_delete (&sweep_line, stop, out);
512
513 stop = rectangle_peek_stop (&sweep_line);
514 }
515
516 active_edges (&sweep_line, out);
517 sweep_line.current_y = rectangle->top;
518 }
519
520 sweep_line_insert (&sweep_line, rectangle);
521 } while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL((void*)0));
522
523 while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL((void*)0)) {
524 if (rectangle->bottom != sweep_line.current_y) {
525 active_edges (&sweep_line, out);
526 sweep_line.current_y = rectangle->bottom;
527 }
528
529 sweep_line_delete (&sweep_line, rectangle, out);
530 }
531
532unwind:
533 sweep_line_fini (&sweep_line);
534 return status;
535}
536
537static cairo_status_t
538_cairo_boxes_intersect_with_box (const cairo_boxes_t *boxes,
539 const cairo_box_t *box,
540 cairo_boxes_t *out)
541{
542 cairo_status_t status;
543 int i, j;
544
545 if (out == boxes) { /* inplace update */
546 struct _cairo_boxes_chunk *chunk;
547
548 out->num_boxes = 0;
549 for (chunk = &out->chunks; chunk != NULL((void*)0); chunk = chunk->next) {
550 for (i = j = 0; i < chunk->count; i++) {
551 cairo_box_t *b = &chunk->base[i];
552
553 b->p1.x = MAX (b->p1.x, box->p1.x)((b->p1.x) > (box->p1.x) ? (b->p1.x) : (box->p1
.x))
;
554 b->p1.y = MAX (b->p1.y, box->p1.y)((b->p1.y) > (box->p1.y) ? (b->p1.y) : (box->p1
.y))
;
555 b->p2.x = MIN (b->p2.x, box->p2.x)((b->p2.x) < (box->p2.x) ? (b->p2.x) : (box->p2
.x))
;
556 b->p2.y = MIN (b->p2.y, box->p2.y)((b->p2.y) < (box->p2.y) ? (b->p2.y) : (box->p2
.y))
;
557 if (b->p1.x < b->p2.x && b->p1.y < b->p2.y) {
558 if (i != j)
559 chunk->base[j] = *b;
560 j++;
561 }
562 }
563 /* XXX unlink empty chains? */
564 chunk->count = j;
565 out->num_boxes += j;
566 }
567 } else {
568 const struct _cairo_boxes_chunk *chunk;
569
570 _cairo_boxes_clear (out);
571 _cairo_boxes_limit (out, box, 1);
572 for (chunk = &boxes->chunks; chunk != NULL((void*)0); chunk = chunk->next) {
573 for (i = 0; i < chunk->count; i++) {
574 status = _cairo_boxes_add (out,
575 CAIRO_ANTIALIAS_DEFAULT,
576 &chunk->base[i]);
577 if (unlikely (status)(__builtin_expect (!!(status), 0)))
578 return status;
579 }
580 }
581 }
582
583 return CAIRO_STATUS_SUCCESS;
584}
585
586cairo_status_t
587_cairo_boxes_intersect (const cairo_boxes_t *a,
588 const cairo_boxes_t *b,
589 cairo_boxes_t *out)
590{
591 rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)((512 * sizeof (int)) / sizeof(rectangle_t))];
592 rectangle_t *rectangles;
593 rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles)((int) (sizeof (stack_rectangles) / sizeof (stack_rectangles[
0])))
+ 1];
594 rectangle_t **rectangles_ptrs;
595 const struct _cairo_boxes_chunk *chunk;
596 cairo_status_t status;
597 int i, j, count;
598
599 if (unlikely (a->num_boxes == 0 || b->num_boxes == 0)(__builtin_expect (!!(a->num_boxes == 0 || b->num_boxes
== 0), 0))
) {
1
Assuming field 'num_boxes' is not equal to 0
2
Assuming field 'num_boxes' is not equal to 0
3
Taking false branch
600 _cairo_boxes_clear (out);
601 return CAIRO_STATUS_SUCCESS;
602 }
603
604 if (a->num_boxes == 1) {
4
Assuming field 'num_boxes' is not equal to 1
5
Taking false branch
605 cairo_box_t box = a->chunks.base[0];
606 return _cairo_boxes_intersect_with_box (b, &box, out);
607 }
608 if (b->num_boxes == 1) {
6
Assuming field 'num_boxes' is not equal to 1
7
Taking false branch
609 cairo_box_t box = b->chunks.base[0];
610 return _cairo_boxes_intersect_with_box (a, &box, out);
611 }
612
613 rectangles = stack_rectangles;
614 rectangles_ptrs = stack_rectangles_ptrs;
615 count = a->num_boxes + b->num_boxes;
616 if (count > ARRAY_LENGTH (stack_rectangles)((int) (sizeof (stack_rectangles) / sizeof (stack_rectangles[
0])))
) {
8
Assuming the condition is false
9
Taking false branch
617 rectangles = _cairo_malloc_ab_plus_c (count,
618 sizeof (rectangle_t) +
619 sizeof (rectangle_t *),
620 sizeof (rectangle_t *));
621 if (unlikely (rectangles == NULL)(__builtin_expect (!!(rectangles == ((void*)0)), 0)))
622 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
623
624 rectangles_ptrs = (rectangle_t **) (rectangles + count);
625 }
626
627 j = 0;
628 for (chunk = &a->chunks; chunk
9.1
'chunk' is not equal to NULL
!= NULL((void*)0)
; chunk = chunk->next) {
10
Loop condition is true. Entering loop body
13
Assuming 'chunk' is equal to NULL
14
Loop condition is false. Execution continues on line 657
629 const cairo_box_t *box = chunk->base;
630 for (i = 0; i < chunk->count; i++) {
11
Assuming 'i' is >= field 'count'
12
Loop condition is false. Execution continues on line 628
631 if (box[i].p1.x < box[i].p2.x) {
632 rectangles[j].left.x = box[i].p1.x;
633 rectangles[j].left.dir = 1;
634
635 rectangles[j].right.x = box[i].p2.x;
636 rectangles[j].right.dir = -1;
637 } else {
638 rectangles[j].right.x = box[i].p1.x;
639 rectangles[j].right.dir = 1;
640
641 rectangles[j].left.x = box[i].p2.x;
642 rectangles[j].left.dir = -1;
643 }
644
645 rectangles[j].left.a_or_b = 0;
646 rectangles[j].left.right = NULL((void*)0);
647 rectangles[j].right.a_or_b = 0;
648 rectangles[j].right.right = NULL((void*)0);
649
650 rectangles[j].top = box[i].p1.y;
651 rectangles[j].bottom = box[i].p2.y;
652
653 rectangles_ptrs[j] = &rectangles[j];
654 j++;
655 }
656 }
657 for (chunk = &b->chunks; chunk
14.1
'chunk' is not equal to NULL
!= NULL((void*)0)
; chunk = chunk->next) {
15
Loop condition is true. Entering loop body
18
Assuming 'chunk' is equal to NULL
19
Loop condition is false. Execution continues on line 686
658 const cairo_box_t *box = chunk->base;
659 for (i = 0; i < chunk->count; i++) {
16
Assuming 'i' is >= field 'count'
17
Loop condition is false. Execution continues on line 657
660 if (box[i].p1.x < box[i].p2.x) {
661 rectangles[j].left.x = box[i].p1.x;
662 rectangles[j].left.dir = 1;
663
664 rectangles[j].right.x = box[i].p2.x;
665 rectangles[j].right.dir = -1;
666 } else {
667 rectangles[j].right.x = box[i].p1.x;
668 rectangles[j].right.dir = 1;
669
670 rectangles[j].left.x = box[i].p2.x;
671 rectangles[j].left.dir = -1;
672 }
673
674 rectangles[j].left.a_or_b = 1;
675 rectangles[j].left.right = NULL((void*)0);
676 rectangles[j].right.a_or_b = 1;
677 rectangles[j].right.right = NULL((void*)0);
678
679 rectangles[j].top = box[i].p1.y;
680 rectangles[j].bottom = box[i].p2.y;
681
682 rectangles_ptrs[j] = &rectangles[j];
683 j++;
684 }
685 }
686 assert (j == count)((void) sizeof (__assert_single_arg (j == count)), __extension__
({ if (j == count) ; else __assert_fail ("j == count", "/root/firefox-clang/gfx/cairo/cairo/src/cairo-boxes-intersect.c"
, 686, __extension__ __PRETTY_FUNCTION__); }))
;
20
Assuming 'j' is equal to 'count'
21
Taking true branch
687
688 _cairo_boxes_clear (out);
689 status = intersect (rectangles_ptrs, j, out);
22
Calling 'intersect'
690 if (rectangles != stack_rectangles)
691 free (rectangles);
692
693 return status;
694}