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
;
61 /* Does the rectangle overlap with the region? */
62 if (IS_RECT_EVIL(Rect
) || !_AndRectRect(Rect
, &OldBounds
, &Reg
->bounds
))
64 /* If not then just clear the region */
68 /* Else check if the rectangle contains the region */
69 if (!_AreRectsEqual(Bounds(Reg
), &OldBounds
))
71 /* The region is not completely contained in the rectangle */
73 struct RegionRectangle
*rr
, *PtrToFirst
;
74 struct RegionRectangleExt RRE
;
75 struct Rectangle Rect2
;
81 Set the counter to its maximum value so that
82 Chunk(rr->Prev)->Rects[SIZERECTBUF-1].RR.Next = NextRR
83 can actually work out well.
85 RRE
.Counter
= SIZERECTBUF
- 1;
87 PtrToFirst
->Next
= Reg
->RegionRectangle
;
88 Reg
->RegionRectangle
->Prev
= PtrToFirst
;
90 Rect2
.MinX
= Rect
->MinX
- OldBounds
.MinX
;
91 Rect2
.MinY
= Rect
->MinY
- OldBounds
.MinY
;
92 Rect2
.MaxX
= Rect
->MaxX
- OldBounds
.MinX
;
93 Rect2
.MaxY
= Rect
->MaxY
- OldBounds
.MinY
;
95 OffX
= OldBounds
.MinX
- MinX(Reg
);
96 OffY
= OldBounds
.MinY
- MinY(Reg
);
100 rr
= Reg
->RegionRectangle
;
104 struct RegionRectangle
*NextRR
= rr
->Next
;
106 if (overlap(rr
->bounds
, Rect2
))
109 The rectangle overlaps with this RegionRectangle, so calculate the intersection
110 And add the offsets to adjust the result to the new region's bounds
112 MinX(rr
) = MAX(Rect2
.MinX
, MinX(rr
)) + OffX
;
113 MaxX(rr
) = MIN(Rect2
.MaxX
, MaxX(rr
)) + OffX
;
114 MinY(rr
) = MAX(Rect2
.MinY
, MinY(rr
)) + OffY
;
115 MaxY(rr
) = MIN(Rect2
.MaxY
, MaxY(rr
)) + OffY
;
119 /* The rectangle doesn't overlap with this RegionRectangle, thus
120 this Regionrectangle has to be eliminated from the region.
121 The way we handle RegionRectangles doesn't let us just free it,
122 we can just adjust the pointers of the previous and successive rectangles
123 to point to each other.
126 /* There's always a previous rectangle. Just fix its next pointer */
127 rr
->Prev
->Next
= NextRR
;
129 /* Fix the Next rectangle's Prev pointer */
132 NextRR
->Prev
= rr
->Prev
;
135 /* Is this RegionRectangle the last one in its chunk? */
136 if (Chunk(rr
->Prev
) != Chunk(rr
) && Chunk(NextRR
) != Chunk(rr
))
139 If so then update the previous chunk's pointer to the next chunk
140 to point to the correct chunk's rectangle.
142 Chunk(rr
->Prev
)->Rects
[SIZERECTBUF
-1].RR
.Next
= NextRR
;
143 /* And dispose this chunk. */
144 _DisposeRegionRectangleExtChunk(Chunk(rr
));
151 Reg
->RegionRectangle
= PtrToFirst
->Next
;
152 if (PtrToFirst
->Next
)
153 PtrToFirst
->Next
->Prev
= NULL
;
158 } /* AndRectRegion */