r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / andrectregion.c
blob1dc8d570433747176d8ed9e8ae1115f0c977c478
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function AndRectRegion()
6 Lang: english
7 */
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 /*****************************************************************************
17 NAME */
18 #include <clib/graphics_protos.h>
20 AROS_LH2(void, AndRectRegion,
22 /* SYNOPSIS */
23 AROS_LHA(struct Region *, Reg, A0),
24 AROS_LHA(struct Rectangle *, Rect, A1),
26 /* LOCATION */
27 struct GfxBase *, GfxBase, 84, Graphics)
29 /* FUNCTION
30 Remove everything inside 'region' that is outside 'rectangle'
32 INPUTS
33 region - pointer to Region structure
34 rectangle - pointer to Rectangle structure
36 NOTES
37 This is the only *RectRegion function that cannot fail
39 BUGS
41 SEE ALSO
42 AndRegionRegion() OrRectRegion() XorRectRegion() ClearRectRegion()
43 NewRegion()
45 INTERNALS
47 HISTORY
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 *****************************************************************************/
54 AROS_LIBFUNC_INIT
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 */
66 ClearRegion(Reg);
68 else
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;
77 LONG OffX, OffY;
79 PtrToFirst = &RRE.RR;
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);
99 for
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;
118 else
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 */
131 if (NextRR)
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));
149 rr = NextRR;
152 Reg->RegionRectangle = PtrToFirst->Next;
153 if (PtrToFirst->Next)
154 PtrToFirst->Next->Prev = NULL;
158 AROS_LIBFUNC_EXIT
159 } /* AndRectRegion */