r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / hyperlayers / dohookcliprects.c
blob2f798abe0f9622e54341bd71e5d42302c4d6be6c
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include "layers_intern.h"
11 #include "basicfuncs.h"
12 #include <exec/types.h>
14 /*****************************************************************************
16 NAME */
17 #include <proto/layers.h>
19 AROS_LH3(void, DoHookClipRects,
21 /* SYNOPSIS */
22 AROS_LHA(struct Hook *, hook , A0),
23 AROS_LHA(struct RastPort *, rport, A1),
24 AROS_LHA(struct Rectangle *, rect , A2),
26 /* LOCATION */
27 struct LayersBase *, LayersBase, 36, Layers)
29 /* FUNCTION
31 INPUTS
32 hook - pointer to the hook to be called for the cliprects of
33 the given layer
35 rport - pointer to the rastport where the layers upon which the
36 hook is to be called
38 rect - no operation is allowed outside this rectangle. If a layer
39 is bigger than this rectangle only operations in the
40 common area are allowed.
42 RESULT
44 NOTES
46 EXAMPLE
48 BUGS
50 SEE ALSO
52 INTERNALS
54 HISTORY
55 27-11-96 digulla automatically created from
56 layers_lib.fd and clib/layers_protos.h
58 *****************************************************************************/
59 { /* sv */
60 AROS_LIBFUNC_INIT
61 AROS_LIBBASE_EXT_DECL(struct LayersBase *,LayersBase)
63 struct Layer *L;
65 D(bug("DoHookClipRects(hook @ $%lx, rport @ $%lx, rect @ $%lx)\n", hook, rport, rect));
67 /* if the hook is LAYERS_NOBACKFILL then I am not doing anything here. */
68 if(hook == (struct Hook *)LAYERS_NOBACKFILL)
70 return;
73 L = rport -> Layer;
74 /* does this rastport have a layer?? */
75 if( NULL == L )
77 /* non-layered rastport */
79 /* You MUST supply a rect to clip the hook's actions! */
80 _CallLayerHook(hook, rport, NULL, rect, rect->MinX, rect->MinY, LayersBase);
82 else
84 struct Rectangle boundrect;
86 /* layered rastport */
88 /* I assume that the given bounds rectangle is relative to the upper left corner of the
89 layer's rastport. This makes more sense than if it was relative to the rastport of
90 the screen where this layer is to be found in
93 LockLayer(0, L);
95 boundrect.MinX = rect->MinX + L->bounds.MinX - L->Scroll_X;
96 boundrect.MinY = rect->MinY + L->bounds.MinY - L->Scroll_Y;
97 boundrect.MaxX = rect->MaxX + L->bounds.MinX - L->Scroll_X;
98 boundrect.MaxY = rect->MaxY + L->bounds.MinY - L->Scroll_Y;
100 /* first check whether this layer is to be considered at all */
101 if (!(boundrect.MinX > L->bounds.MaxX ||
102 boundrect.MinY > L->bounds.MaxY ||
103 boundrect.MaxX < L->bounds.MinX ||
104 boundrect.MaxY < L->bounds.MinY))
106 /* yes, that's a layer to be considered */
107 /* I want nobody else to interrupt me while I call the hook for this layer */
108 struct ClipRect * CR;
110 CR = L->ClipRect; /* must not read this before LockLayer!! */
112 #if 0 /* stegerg: seems to have been crap idea/test. Where the hell did I get this from??? */
114 ** Set rport->Layer to NULL, so that the hook function does not
115 ** need to clone the rport and set clonerp->Layer to NULL in
116 ** order to used rastport based gfx functions
118 ** stegerg: AFAIK this is done only since Kickstart 3.1
121 rport->Layer = NULL;
122 #endif
124 /* process all ClipRects of this layer */
125 while (NULL != CR)
127 /* I am going to call the hook for all visible cliprects and
128 for invisible cliprects belonging to smart or superbitmap
129 layers =>
130 So I am not calling it for invisble cliprects belonging to
131 a simple layer.
134 if (!(NULL != CR->lobs &&
135 0 != (L->Flags & LAYERSIMPLE)) )
137 struct Rectangle bounds;
138 /* That's a ClipRect to visit, if it's inside the given rectangle */
139 /* Generate the bounds rectangle. This rectangle shows the part
140 of the clipRect that is supposed to be changed. So it might get
141 the coordinates of the ClipRect, but it can also be smaller. */
143 bounds.MinX = (boundrect.MinX > CR->bounds.MinX) ? boundrect.MinX
144 : CR->bounds.MinX;
145 bounds.MinY = (boundrect.MinY > CR->bounds.MinY) ? boundrect.MinY
146 : CR->bounds.MinY;
147 bounds.MaxX = (boundrect.MaxX < CR->bounds.MaxX) ? boundrect.MaxX
148 : CR->bounds.MaxX;
149 bounds.MaxY = (boundrect.MaxY < CR->bounds.MaxY) ? boundrect.MaxY
150 : CR->bounds.MaxY;
152 /* Is the cliprect inside the bounds... */
153 if (bounds.MinX <= bounds.MaxX && bounds.MinY <= bounds.MaxY)
155 struct BitMap * bm;
156 WORD offsetX = bounds.MinX - L->bounds.MinX + L->Scroll_X; /* + scrollx is correct! */
157 WORD offsetY = bounds.MinY - L->bounds.MinY + L->Scroll_Y; /* + scrolly is correct! */
159 /* Call the hook for the rectangle given by bounds. */
161 /* If the ClipRect is hidden, then this might get special..., but
162 only for non-simple layers, which are already ignored by an if
163 further above */
164 if (NULL != CR->lobs)
166 bm = rport->BitMap;
168 if (0 != (L->Flags & LAYERSUPER))
170 /* it's a superbitmap layer */
171 bounds.MinX -= ( L->bounds.MinX + L->Scroll_X );
172 bounds.MinY -= ( L->bounds.MinY + L->Scroll_Y );
173 bounds.MaxX -= ( L->bounds.MinX + L->Scroll_X );
174 bounds.MaxY -= ( L->bounds.MinY + L->Scroll_Y );
175 rport->BitMap = L->SuperBitMap;
177 else
179 /* it's a smart layer but not superbitmap */
180 /* it's hidden, the hook has to blit into the hidden cliprect's bitmap now */
181 /* adjust the bounds */
182 bounds.MinX = bounds.MinX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX);
183 bounds.MinY = bounds.MinY - CR->bounds.MinY;
184 bounds.MaxX = bounds.MaxX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX);
185 bounds.MaxY = bounds.MaxY - CR->bounds.MinY;
186 rport->BitMap = CR->BitMap;
189 _CallLayerHook(hook, rport, L, &bounds, offsetX, offsetY, LayersBase);
190 rport->BitMap = bm;
192 } /* hidden cliprect */
193 else
195 _CallLayerHook(hook, rport, L, &bounds, offsetX, offsetY, LayersBase);
196 } /* visible cliprect */
198 } /* if (cliprect intersects rect in screen coords) */
200 } /* ignore hidden simple refresh cliprects */
202 CR = CR->Next;
204 } /* foreach cliprect */
206 #if 0 /* stegerg: seems to have been crap idea/test. Where the hell did I get this from??? */
208 /* Restore RastPort->Layer which was set to NULL further above */
210 rport->Layer = L;
211 #endif
213 } /* if (rect in screen coords interesects layer coords) */
215 UnlockLayer(L);
217 } /* if (layered rastport) */
219 AROS_LIBFUNC_EXIT
220 } /* DoHookClipRects */