New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / hyperlayers / changelayershape.c
blob3053f8d0bfd91470f7ed8a5660d4117c0ddc56a7
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <proto/exec.h>
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include <layers_intern.h>
12 #include <aros/libcall.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <utility/hooks.h>
16 #include "basicfuncs.h"
18 /*****************************************************************************
20 NAME */
21 #include <proto/layers.h>
22 AROS_LH3(struct Region *, ChangeLayerShape,
24 /* SYNOPSIS */
25 AROS_LHA(struct Layer *, l , A0),
26 AROS_LHA(struct Region *, newshape , A1),
27 AROS_LHA(struct Hook *, callback , A2),
28 /* LOCATION */
29 struct LayersBase *, LayersBase, 41, Layers)
31 /* FUNCTION
32 Changes the shape of the layer on the fly.
33 When the shape of a layer is changed the current pixel content
34 is copied into its ClipRects so no information is lost.
35 The user can provide a callback hook that will be
36 called when the current layer's information is all backed up
37 in ClipRects. The signature of the callback should look as follows:
38 AROS_UFC4(struct Region *, callback,
39 AROS_UFCA(struct Hook * , hook , A0),
40 AROS_UFCA(struct Layer * , l , A2),
41 AROS_UFCA(struct ScaleLayerParam * , arg , A1));
44 INPUTS
45 L - pointer to layer
46 newshape - pointer to a region that comprises the new shape
47 of the layer. May be NULL if callback is provided.
48 callback - pointer to a callback hook. May be NULL if newshape
49 is given.
51 RESULT
52 Pointer to the previously installed region.
54 NOTES
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 HISTORY
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
69 AROS_LIBBASE_EXT_DECL(struct LayersBase *,LayersBase)
71 struct Region * returnshape = NULL;
73 LockLayers(l->LayerInfo);
76 struct Region r, cutoldshape, rtmp, cutnewshape;
77 struct Layer * lparent, * _l, * lfirst = NULL;
78 int behind_l = FALSE;
79 InitRegion(&r);
80 InitRegion(&rtmp);
81 InitRegion(&cutoldshape);
82 InitRegion(&cutnewshape);
85 if (IS_VISIBLE(l))
88 * Backup everything that is visible right now into
89 * cliprects.
91 lfirst = GetFirstFamilyMember(l);
92 SetRegion(lfirst->VisibleRegion, &r);
94 SetRegion(l->visibleshape, &cutoldshape);
95 _BackupPartsOfLayer(l, &cutoldshape, 0, TRUE, LayersBase);
99 * Get the current layer's shape as the paramter to return
100 * from this function.
102 returnshape = l->shaperegion;
104 if (NULL != callback)
106 struct ChangeLayerShapeMsg clsm;
107 clsm.newshape = newshape;
108 clsm.cliprect = l->ClipRect;
109 clsm.shape = l->shape;
111 * call the callback to the user to give me a new shape
112 * The user can manipulate the cliprects of the layer
113 * l and can have a look at the current shape.
115 l->shaperegion = (struct Region *)CallHookPkt(callback, l, &clsm);
117 else
120 * The user passed me the new shape but no callback.
122 l->shaperegion = newshape;
125 DisposeRegion(l->shape);
127 * At this point l->shaperegion holds the layer that is to be
128 * installed. Let's cut it down to the actually visible part.
131 l->shape = NewRectRegion(0,0,l->Width-1,l->Height-1);
133 if (l->shaperegion)
134 AndRegionRegion(l->shaperegion, l->shape);
136 _TranslateRect(&l->shape->bounds, l->bounds.MinX, l->bounds.MinY);
138 SetRegion(l->shape, l->visibleshape);
139 AndRegionRegion(l->parent->visibleshape, l->visibleshape);
141 if (IS_VISIBLE(l))
144 * Let me backup parts of the layers that are behind the
145 * layer l and the layers that are its family.
148 lparent = l->parent;
149 _l = lfirst;
151 while (1)
153 if ((l != _l))
155 if(IS_VISIBLE(_l) && DO_OVERLAP(&l->visibleshape->bounds, &_l->visibleshape->bounds))
156 _BackupPartsOfLayer(_l, l->visibleshape, 0, FALSE, LayersBase);
159 if (_l == lparent)
161 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
162 break;
163 else
164 lparent = lparent->parent;
167 _l = _l->back;
168 } /* while (1) */
172 * Make the new layer and its family visible
173 * Since the parent might have become bigger more
174 * of the children might become visible...
176 _l = lfirst;
177 lparent = l->parent;
179 while (1)
181 if (IS_VISIBLE(_l) &&
182 (DO_OVERLAP(&cutnewshape.bounds, &_l->visibleshape->bounds) ||
183 DO_OVERLAP(&cutoldshape.bounds, &_l->visibleshape->bounds)))
185 ClearRegion(_l->VisibleRegion);
186 _ShowPartsOfLayer(_l, &r, LayersBase);
188 else
189 SetRegion(&r, _l->VisibleRegion);
192 if ((TRUE == behind_l) && (IS_VISIBLE(_l) || IS_ROOTLAYER(_l)))
193 AndRegionRegion(_l->VisibleRegion, &cutoldshape);
195 if (_l == lparent)
197 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
198 break;
199 else
200 lparent = lparent->parent;
203 if (l == _l)
204 behind_l = TRUE;
206 if (FALSE == behind_l)
208 SetRegion(_l->shape, _l->visibleshape);
209 AndRegionRegion(_l->parent->visibleshape, _l->visibleshape);
212 if (IS_VISIBLE(_l))
213 ClearRegionRegion(_l->visibleshape, &r);
215 _l = _l->back;
216 } /* while(1) */
218 ClearRegion(&rtmp);
219 ClearRegion(&r);
221 if (!IS_EMPTYREGION(&cutoldshape))
223 if (lparent &&
224 (IS_SIMPLEREFRESH(lparent) || IS_ROOTLAYER(lparent)))
225 _BackFillRegion(l->parent, &cutoldshape, TRUE, LayersBase);
228 ClearRegion(&cutoldshape);
230 } /* if (IS_VISIBLE(l)) */
232 ClearRegion(&cutnewshape);
236 UnlockLayers(l->LayerInfo);
238 return returnshape;
240 AROS_LIBFUNC_EXIT
241 } /* ChangeLayerShape */