NListtree.mcc: fix sorted insert
[AROS.git] / rom / graphics / andrectregion.c
blob43b235b6838703c4c80049e7662d2628ffe24986
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;
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 */
65 ClearRegion(Reg);
67 else
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;
76 LONG OffX, OffY;
78 PtrToFirst = &RRE.RR;
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);
98 for
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;
117 else
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 */
130 if (NextRR)
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));
148 rr = NextRR;
151 Reg->RegionRectangle = PtrToFirst->Next;
152 if (PtrToFirst->Next)
153 PtrToFirst->Next->Prev = NULL;
157 AROS_LIBFUNC_EXIT
158 } /* AndRectRegion */