2
* Copyright © 2004 David Reveman
4
* Permission to use, copy, modify, distribute, and sell this software
5
* and its documentation for any purpose is hereby granted without
6
* fee, provided that the above copyright notice appear in all copies
7
* and that both that copyright notice and this permission notice
8
* appear in supporting documentation, and that the name of
9
* David Reveman not be used in advertising or publicity pertaining to
10
* distribution of the software without specific, written prior permission.
11
* David Reveman makes no representations about the suitability of this
12
* software for any purpose. It is provided "as is" without express or
15
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: David Reveman <davidr@novell.com>
27
# include "../config.h"
32
#define REGION_ALLOC_CHUNK 16
34
#define BOX_SUBSUMS_BOX(b1, b2) \
35
((b2)->x1 >= (b1)->x1 && \
36
(b2)->x2 <= (b1)->x2 && \
37
(b2)->y1 >= (b1)->y1 && \
40
#define BOX_INTERSECTS_BOX(b1, b2) \
41
((b1)->x1 < (b2)->x2 && \
42
(b1)->x2 > (b2)->x1 && \
43
(b1)->y1 < (b2)->y2 && \
46
#define BOX_CLOSE_TO_BOX(b1, b2) \
47
((b1)->x1 < ((b2)->x2 + 1) && \
48
(b1)->x2 > ((b2)->x1 - 1) && \
49
(b1)->y1 < ((b2)->y2 + 1) && \
50
(b1)->y2 > ((b2)->y1 - 1))
52
#define BOX_NEXT_TO_BOX(b1, b2) \
53
((((b1)->x1 == (b2)->x2 || \
54
(b1)->x2 == (b2)->x1) && \
55
(b1)->y1 == (b2)->y1 && \
56
(b1)->y2 == (b2)->y2) || \
57
(((b1)->y1 == (b2)->y2 || \
58
(b1)->y2 == (b2)->y1) && \
59
(b1)->x1 == (b2)->x1 && \
60
(b1)->x2 == (b2)->x2))
62
#define MERGE_BOXES(d, b1, b2) \
64
(d)->x1 = MIN ((b1)->x1, (b2)->x1); \
65
(d)->y1 = MIN ((b1)->y1, (b2)->y1); \
66
(d)->x2 = MAX ((b1)->x2, (b2)->x2); \
67
(d)->y2 = MAX ((b1)->y2, (b2)->y2); \
71
* No real union, boxes that intersect are just joined into bigger boxes.
72
* This is OK for our needs and it keeps the number of boxes down to a
73
* minimum and makes it faster.
76
glitz_region_union (glitz_region_t *region,
79
if (region->n_box == 0) {
80
region->extents = *ubox;
81
region->box = ®ion->extents;
84
return GLITZ_STATUS_SUCCESS;
87
if (BOX_CLOSE_TO_BOX (ubox, ®ion->extents)) {
88
glitz_box_t *box, *new_box, *dst_box;
92
n_box = region->n_box;
95
if (BOX_SUBSUMS_BOX (box, ubox))
96
return GLITZ_STATUS_SUCCESS;
102
n_box = region->n_box;
108
if (BOX_INTERSECTS_BOX (box, new_box) ||
109
BOX_NEXT_TO_BOX (box, new_box)) {
113
* Remove box from region
116
if (region->n_box == 1) {
117
MERGE_BOXES (®ion->extents, box, new_box);
118
region->box = ®ion->extents;
120
return GLITZ_STATUS_SUCCESS;
122
MERGE_BOXES (dst_box, box, new_box);
124
memmove (box, box + 1,
125
n_box * sizeof (glitz_box_t));
130
MERGE_BOXES (dst_box, box, new_box);
138
if (region->n_box > 1)
139
MERGE_BOXES (®ion->extents, ®ion->extents, ubox);
141
return GLITZ_STATUS_SUCCESS;
148
if (region->size < (region->n_box + 1)) {
149
region->size += REGION_ALLOC_CHUNK;
150
region->data = (void *) realloc (region->data,
151
sizeof (glitz_box_t) * region->size);
153
return GLITZ_STATUS_NO_MEMORY;
156
region->box = (glitz_box_t *) region->data;
158
region->box[region->n_box] = *ubox;
159
if (region->n_box == 1)
160
region->box[0] = region->extents;
164
MERGE_BOXES (®ion->extents, ®ion->extents, ubox);
166
return GLITZ_STATUS_SUCCESS;