2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Graphics function AndRectRegion()
8 #include "graphics_intern.h"
9 #include <graphics/regions.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <clib/macros.h>
13 #include "intregions.h"
15 /*****************************************************************************
18 #include <clib/graphics_protos.h>
20 AROS_LH2(void, AndRectRegion
,
23 AROS_LHA(struct Region
*, Reg
, A0
),
24 AROS_LHA(struct Rectangle
*, Rect
, A1
),
27 struct GfxBase
*, GfxBase
, 84, Graphics
)
30 Remove everything inside 'region' that is outside 'rectangle'
33 region - pointer to Region structure
34 rectangle - pointer to Rectangle structure
37 This is the only *RectRegion function that cannot fail
42 AndRegionRegion() OrRectRegion() XorRectRegion() ClearRectRegion()
48 27-11-96 digulla automatically created from
49 graphics_lib.fd and clib/graphics_protos.h
50 16-01-97 mreckt initial version
52 *****************************************************************************/
56 /* Is the region non-empty? */
57 if (Reg
->RegionRectangle
)
59 struct Rectangle OldBounds
= Reg
->bounds
;
62 /* Does the rectangle overlap with the region? */
63 if (!_AndRectRect(Rect
, &OldBounds
, &Reg
->bounds
))
65 /* If not then just clear the region */
69 /* Else check if the rectangle contains the region */
70 if (!_AreRectsEqual(Bounds(Reg
), &OldBounds
))
72 /* The region is not completely contained in the rectangle */
74 struct RegionRectangle
*rr
, *PtrToFirst
;
75 struct RegionRectangleExt RRE
;
76 struct Rectangle Rect2
;
82 Set the counter to its maximum value so that
83 Chunk(rr->Prev)->Rects[SIZERECTBUF-1].RR.Next = NextRR
84 can actually work out well.
86 RRE
.Counter
= SIZERECTBUF
- 1;
88 PtrToFirst
->Next
= Reg
->RegionRectangle
;
89 Reg
->RegionRectangle
->Prev
= PtrToFirst
;
91 Rect2
.MinX
= Rect
->MinX
- OldBounds
.MinX
;
92 Rect2
.MinY
= Rect
->MinY
- OldBounds
.MinY
;
93 Rect2
.MaxX
= Rect
->MaxX
- OldBounds
.MinX
;
94 Rect2
.MaxY
= Rect
->MaxY
- OldBounds
.MinY
;
96 OffX
= OldBounds
.MinX
- MinX(Reg
);
97 OffY
= OldBounds
.MinY
- MinY(Reg
);
101 rr
= Reg
->RegionRectangle
;
105 struct RegionRectangle
*NextRR
= rr
->Next
;
107 if (overlap(rr
->bounds
, Rect2
))
110 The rectangle overlaps with this RegionRectangle, so calculate the intersection
111 And add the offsets to adjust the result to the new region's bounds
113 MinX(rr
) = MAX(Rect2
.MinX
, MinX(rr
)) + OffX
;
114 MaxX(rr
) = MIN(Rect2
.MaxX
, MaxX(rr
)) + OffX
;
115 MinY(rr
) = MAX(Rect2
.MinY
, MinY(rr
)) + OffY
;
116 MaxY(rr
) = MIN(Rect2
.MaxY
, MaxY(rr
)) + OffY
;
120 /* The rectangle doesn't overlap with this RegionRectangle, thus
121 this Regionrectangle has to be eliminated from the region.
122 The way we handle RegionRectangles doesn't let us just free it,
123 we can just adjust the pointers of the previous and successive rectangles
124 to point to each other.
127 /* There's always a previous rectangle. Just fix its next pointer */
128 rr
->Prev
->Next
= NextRR
;
130 /* Fix the Next rectangle's Prev pointer */
133 NextRR
->Prev
= rr
->Prev
;
136 /* Is this RegionRectangle the last one in its chunk? */
137 if (Chunk(rr
->Prev
) != Chunk(rr
) && Chunk(NextRR
) != Chunk(rr
))
140 If so then update the previous chunk's pointer to the next chunk
141 to point to the correct chunk's rectangle.
143 Chunk(rr
->Prev
)->Rects
[SIZERECTBUF
-1].RR
.Next
= NextRR
;
144 /* And dispose this chunk. */
145 _DisposeRegionRectangleExtChunk(Chunk(rr
));
152 Reg
->RegionRectangle
= PtrToFirst
->Next
;
153 if (PtrToFirst
->Next
)
154 PtrToFirst
->Next
->Prev
= NULL
;
159 } /* AndRectRegion */