2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
10 #include <aros/debug.h>
12 #include <aros/libcall.h>
13 #include <exec/types.h>
15 #include "layers_intern.h"
16 #include "basicfuncs.h"
17 /*****************************************************************************
20 #include <proto/layers.h>
22 AROS_LH3(void, DoHookClipRects
,
25 AROS_LHA(struct Hook
*, hook
, A0
),
26 AROS_LHA(struct RastPort
*, rport
, A1
),
27 AROS_LHA(struct Rectangle
*, rect
, A2
),
30 struct LayersBase
*, LayersBase
, 36, Layers
)
35 hook - pointer to the hook to be called for the cliprects of
38 rport - pointer to the rastport where the layers upon which the
41 rect - no operation is allowed outside this rectangle. If a layer
42 is bigger than this rectangle only operations in the
43 common area are allowed.
58 27-11-96 digulla automatically created from
59 layers_lib.fd and clib/layers_protos.h
61 *****************************************************************************/
67 D(bug("[Layers] %s(hook @ 0x%p, rport @ $%p, rect @ $%p)\n", __func__
, hook
, rport
, rect
));
69 /* if the hook is LAYERS_NOBACKFILL, there is nothing to do here. */
70 if(hook
== (struct Hook
*)LAYERS_NOBACKFILL
)
72 D(bug("[Layers] %s: NOBACKFILL\n", __func__
));
77 /* does this rastport have a layer?? */
80 D(bug("[Layers] %s: No Layer\n", __func__
));
82 /* non-layered rastport */
84 /* You MUST supply a rect to clip the hook's actions! */
85 _CallLayerHook(hook
, rport
, NULL
, rect
, rect
->MinX
, rect
->MinY
, LayersBase
);
89 struct Rectangle boundrect
;
91 /* layered rastport */
93 /* The input rectangle is relative to the upper left corner of the
94 * layer's rastport. */
98 D(bug("[Layers] %s: Layer > %d,%d -> %d,%d\n", __func__
, L
->bounds
.MinX
- L
->Scroll_X
, L
->bounds
.MinY
- L
->Scroll_Y
, L
->bounds
.MaxX
- L
->Scroll_X
, L
->bounds
.MaxY
- L
->Scroll_Y
);)
100 boundrect
.MinX
= rect
->MinX
+ L
->bounds
.MinX
- L
->Scroll_X
;
101 boundrect
.MinY
= rect
->MinY
+ L
->bounds
.MinY
- L
->Scroll_Y
;
102 boundrect
.MaxX
= rect
->MaxX
+ L
->bounds
.MinX
- L
->Scroll_X
;
103 boundrect
.MaxY
= rect
->MaxY
+ L
->bounds
.MinY
- L
->Scroll_Y
;
105 D(bug("[Layers] %s: %d,%d -> %d,%d\n", __func__
, boundrect
.MinX
, boundrect
.MinY
, boundrect
.MaxX
, boundrect
.MaxY
);)
107 /* first check whether this layer is to be considered at all */
108 if (!(boundrect
.MinX
> L
->bounds
.MaxX
||
109 boundrect
.MinY
> L
->bounds
.MaxY
||
110 boundrect
.MaxX
< L
->bounds
.MinX
||
111 boundrect
.MaxY
< L
->bounds
.MinY
))
113 /* yes, that's a layer to be considered */
114 /* I want nobody else to interrupt me while I call the hook for this layer */
115 struct ClipRect
* CR
;
118 CR
= L
->ClipRect
; /* must not read this before LockLayer!! */
120 /* process all ClipRects of this layer */
123 D(bug("[Layers] %s: CR @ 0x%p\n", __func__
, CR
));
124 /* The hook will be called for all visible cliprects, and
125 for hidden cliprects belonging to smart or superbitmap
127 Hidden cliprects belonging to simple layers are ignored.
130 if (!(NULL
!= CR
->lobs
&&
131 0 != (L
->Flags
& LAYERSIMPLE
)) )
133 struct Rectangle bounds
;
134 /* That's a ClipRect to visit, if it's inside the given rectangle */
135 /* Generate the bounds rectangle. This rectangle shows the part
136 of the clipRect that is supposed to be changed. So it might get
137 the coordinates of the ClipRect, but it can also be smaller. */
139 D(bug("[Layers] %s: CR > %d,%d -> %d,%d\n", __func__
, CR
->bounds
.MinX
, CR
->bounds
.MinY
, CR
->bounds
.MaxX
, CR
->bounds
.MaxY
);)
141 bounds
.MinX
= (boundrect
.MinX
> CR
->bounds
.MinX
) ? boundrect
.MinX
143 bounds
.MinY
= (boundrect
.MinY
> CR
->bounds
.MinY
) ? boundrect
.MinY
145 bounds
.MaxX
= (boundrect
.MaxX
< CR
->bounds
.MaxX
) ? boundrect
.MaxX
147 bounds
.MaxY
= (boundrect
.MaxY
< CR
->bounds
.MaxY
) ? boundrect
.MaxY
150 D(bug("[Layers] %s: %d,%d -> %d,%d\n", __func__
, bounds
.MinX
, bounds
.MinY
, bounds
.MaxX
, bounds
.MaxY
);)
152 /* Is the cliprect inside the bounds?... */
153 if (bounds
.MinX
<= bounds
.MaxX
&& bounds
.MinY
<= bounds
.MaxY
)
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
164 if (NULL
!= CR
->lobs
)
168 /* it's a smart layer -: */
169 if (0 != (L
->Flags
& LAYERSUPER
))
171 /* it's a superbitmap layer */
173 D(bug("[Layers] %s: SuperBitMap\n", __func__
));
175 bounds
.MinX
-= ( L
->bounds
.MinX
+ L
->Scroll_X
);
176 bounds
.MinY
-= ( L
->bounds
.MinY
+ L
->Scroll_Y
);
177 bounds
.MaxX
-= ( L
->bounds
.MinX
+ L
->Scroll_X
);
178 bounds
.MaxY
-= ( L
->bounds
.MinY
+ L
->Scroll_Y
);
179 rport
->BitMap
= L
->SuperBitMap
;
183 /* It's not a superbitmap, so it must be a hidden layer.
184 * The hook has to blit into the hidden cliprect's bitmap
185 * which has different offsets to the layers, so -:
186 * # adjust the bounds/offsets so that the rendering is
187 * relative to the correct location.
188 * # clear the rastports layer pointer so the hook isnt confused */
190 D(bug("[Layers] %s: Hidden\n", __func__
));
192 bounds
.MinX
-= CR
->bounds
.MinX
;
193 bounds
.MinX
+= ALIGN_OFFSET(CR
->bounds
.MinX
);
194 bounds
.MinY
-= CR
->bounds
.MinY
;
195 bounds
.MaxX
-= CR
->bounds
.MinX
;
196 bounds
.MaxX
+= ALIGN_OFFSET(CR
->bounds
.MinX
);
197 bounds
.MaxY
-= CR
->bounds
.MinY
;
199 rport
->BitMap
= CR
->BitMap
;
201 _CallLayerHook(hook
, rport
, rport
->Layer
, &bounds
, offsetX
, offsetY
, LayersBase
);
204 } /* hidden cliprect */
207 _CallLayerHook(hook
, rport
, rport
->Layer
, &bounds
, offsetX
, offsetY
, LayersBase
);
208 } /* visible cliprect */
209 } /* if (cliprect intersects rect in screen coords) */
210 } /* ignore hidden simple refresh cliprects */
212 /* Restore the RastPort's Layer, incase it was cleared
213 * in a rendering operation, but not restored, or we have rendered
220 } /* foreach cliprect */
221 } /* if (rect in screen coords interesects layer coords) */
224 } /* if (layered rastport) */
227 } /* DoHookClipRects */