Aros/Developer/Docs/Libraries/Layers
Introduction
editA layer is a rectangular drawing area. Every Intuition window has an associated Layer structure. Intuition windows are the only supported method of adding layers to Intuition screens. Using Intuition window calls
Layers
editThe Layer Structure is Read-Only. Applications should never directly modify any of the elements of the Layer structure. In addition, applications should only read the front, back, rp, bounds, Flags, SuperBitMap and DamageList elements of the Layer structure.
When a layer is created, a RastPort is automatically to go along with it. The pointer to the RastPort is contained in the layer data structure. Using this RastPort, the application may draw anywhere into the layer’s bounds rectangle. If the application tries to draw outside of this rectangle, the graphics routines will clip the graphics.
Create rastport using layers.library calls and you get clipping. You just attach your bitmap to this rastport created by layers.lib. The normal graphics operations only perform clipping when there's a layer.
only one layer-type flag (LAYERSIMPLE, LAYERSMART and LAYERSUPER) should be specified.
created by using the primitives InitVPort(), InitView(), MakeVPort(), MrgCop(), and LoadView()
layers.library depends on graphics.library which depends on layers.library - this circular dependency expected?
It occurs due to the autogenerated __LIBS_LIST__ for layers.library. graphics.library explicitly calls OpenLibrary() on layers.library
Graphics Primitives for creating a low-level graphics display on the common bit map by calling CreateUpfrontLayer() or CreateBehindLayer()
struct Layer_Info *NewLayerInfo( void );
void DisposeLayerInfo( struct Layer_Info *li );
How do you create a layer without a bitmap?
Usually call NewLayerInfo and CreateUpfrontLayer (which needs the bitmap pointer) and get a readily initialized RastPort from layer->rp.
RastPort width and height are 15 bits (struct Rectangle contains WORDs, not UWORDs). A bitmap with 32k pixel in a square would be more than 1000 megapixel.
Regions
editUse the routine InstallClipRegion() creates rectangle clipping (which allows graphic functions) within a layer
struct Region *NewRegion( void );
void DisposeRegion( struct Region *region );
Misc
editABIv1
editIntuition and Layers, since they have their roots in MorphOS (because MorphOS has roots in AROS), but already have some extensions from OS4. The main question is window shaping implementation. Both MOS and AOS4 have this mechanism, with different API. Our own variant was close to AOS4 (perhaps they took it as base), so i fixed it up to be compatible (except ChangeLayerShape() function - not done yet).
1. If anyone can confirm that the implementation is OS4-compatible? I tried to google for some AOS4 code sample, but failed to find one.
2. Can anyone help me to complete ChangeLayerShape() ? It should use the same hook, according to OS4 autodocs. Unfortunately my understanding of Layers is very poor.
3. Our API better fits to follow MorphOS than OS4. This is mainly because we use library vectors for function calls, and not interfaces. This allows to have a binary compatibility with MorphOS in future. So, it's logical to implement MorphOS version of shaping. There's only one significant difference: MorphOS version is inverse of AOS one. I. e. in OS4 we provide a region describing visible area, in MorphOS we provide a region describing invisible one. So - would it be better to switch to MorphOS variant, or implement support for both? Both versions are not very redundant, i believe amount of code will be minimal.
BackFill Hooks
editWith a slightly modified version of Thomas Rapp's backfill example. Try to change the backfill hook function to use:
(msg->bounds.MinX - layer->bounds.MinX); (msg->bounds.MinY - layer->bounds.MinY);
in places where it used
msg->offsetx msg->offsety
See workbench/demos/winbackfill.c.
Examples
edit#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/layers.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <aros/oldprograms.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/regions.h>
#include <stdio.h>
struct NewWindow MyWin =
{
20,20,300,200,-1,-1,IDCMP_CLOSEWINDOW|/*IDCMP_DELTAMOVE|*/IDCMP_MOUSEMOVE,
WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|WINDOWSIZING|WFLG_SMART_REFRESH|WFLG_REPORTMOUSE,
NULL,NULL,(char *)"Testwindow",
NULL,NULL,0,0,0,0,WBENCHSCREEN
};
struct GfxBase * GfxBase;
struct Library * LayersBase;
void installClipRegion(struct Window * w)
{
int width, height;
struct Rectangle Rect;
ULONG x,y,line;
struct Region * R = NewRegion();
printf("Width of ClipRegion Rectangles: ");
scanf("%i",&width);
printf("Height of ClipRegion Rectangles: ");
scanf("%i",&height);
if (height == 0 || width == 0)
return;
y = 0;
line = 0;
while (y < w->Height)
{
x = (line & 1) * width;
while (x < w->Width)
{
Rect.MinX = x;
Rect.MinY = y;
Rect.MaxX = x+width-1;
Rect.MaxY = y+height-1;
OrRectRegion(R,&Rect);
x += (2*width);
}
y += height;
line ++;
}
InstallClipRegion(w->WLayer, R);
}
void uninstallClipRegion(struct Window * w)
{
struct Region * R = InstallClipRegion(w->WLayer, NULL);
if (NULL != R)
DisposeRegion(R);
}
int main(void)
{
LayersBase = OpenLibrary("layers.library",0);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
if (NULL != GfxBase)
{
struct IntuitionBase * IntuitionBase =
(struct IntuitionBase *)OpenLibrary("intuition.library",0);
if (NULL != IntuitionBase)
{
struct Window * TheDude = OpenWindow(&MyWin);
if (NULL != TheDude)
{
struct RastPort * rp = TheDude->RPort;
struct TmpRas tmpras;
struct IntuiMessage * Msg;
UWORD areabuffer[250];
char c;
struct AreaInfo myAreaInfo;
installClipRegion(TheDude);
InitArea(&myAreaInfo, &areabuffer[0], 50);
rp->AreaInfo = &myAreaInfo;
InitTmpRas(&tmpras, AllocRaster(320,200),RASSIZE(320,200));
rp->TmpRas = &tmpras;
/* Let's draw something */
SetAPen(rp,1);
SetOutlinePen(rp,3);
/*
AreaMove(rp,10,20);
AreaDraw(rp,110,30);
AreaDraw(rp,110,100);
AreaDraw(rp,10,110);
AreaEnd(rp);
*/
/**/
AreaMove(rp,10,20);
AreaDraw(rp,110,30);
AreaDraw(rp,110,100);
AreaDraw(rp,10,50);
AreaEnd(rp);
/**/
/*
AreaEllipse(rp, 110, 30, 50, 20);
AreaEnd(rp);
*/
/*
Move(rp,0,0);
Draw(rp,0,100);
Draw(rp,100,110);
Draw(rp,100,0);
Draw(rp,0,0);
SetAPen(rp, 1);
Flood(rp,0,50,50);
*/
/*
ScrollRaster(&IntuitionBase->ActiveScreen->RastPort,
-1,
-1,
10,
10,
100,
100);
*/
printf("press a key and hit return!");
scanf("%c",&c);
ScrollRaster(rp,
-10,
-10,
10,
10,
100,
100);
while (TRUE)
{
WaitPort(TheDude->UserPort);
Msg = (struct IntuiMessage *)GetMsg(TheDude->UserPort);
if (IDCMP_CLOSEWINDOW == Msg->Class)
break;
if (IDCMP_MOUSEMOVE == Msg->Class)
{
printf("Received a delta move message! (%i,%i)\n",Msg->MouseX,Msg->MouseY);
}
ReplyMsg((struct Message *)Msg);
}
uninstallClipRegion(TheDude);
CloseWindow(TheDude);
}
CloseLibrary((struct Library *)IntuitionBase);
}
CloseLibrary((struct Library *)GfxBase);
}
return 0;
}
References
editvoid InitLayers(struct Layer_Info *li) struct Layer *CreateUpfrontLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, LONG x1, LONG y1, LONG flags, struct BitMap *bm2) struct Layer *CreateBehindLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, LONG x1, LONG y1, LONG flags, struct BitMap *bm2) LONG UpfrontLayer(LONG dummy, struct Layer *l) LONG BehindLayer(LONG dummy, struct Layer *l) LONG MoveLayer(LONG dummy, struct Layer *l, LONG dx, LONG dy) LONG SizeLayer(LONG dummy, struct Layer *l, LONG dw, LONG dh) void ScrollLayer(LONG dummy, struct Layer *l, LONG dx, LONG dy) LONG BeginUpdate(struct Layer *l) void EndUpdate(struct Layer *l, UWORD flag) LONG DeleteLayer(LONG dummy, struct Layer *l) void LockLayer(LONG dummy, struct Layer *layer) void UnlockLayer(struct Layer *layer) void LockLayers(struct Layer_Info *li) void UnlockLayers(struct Layer_Info *li) void LockLayerInfo(struct Layer_Info *li) void SwapBitsRastPortClipRect(struct RastPort *rp, struct ClipRect *cr) struct Layer *WhichLayer(struct Layer_Info *li, LONG x, LONG y) void UnlockLayerInfo(struct Layer_Info *li) struct Layer_Info *NewLayerInfo() void DisposeLayerInfo(struct Layer_Info *li) LONG FattenLayerInfo(struct Layer_Info *li) void ThinLayerInfo(struct Layer_Info *li) LONG MoveLayerInFrontOf(struct Layer *layer_to_move, struct Layer *other_layer) struct Region *InstallClipRegion(struct Layer *l, struct Region *region) LONG MoveSizeLayer(struct Layer *l, LONG dx, LONG dy, LONG dw, LONG dh) struct Layer *CreateUpfrontHookLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, LONG x1, LONG y1, LONG flags, struct Hook *hook, struct BitMap *bm2) struct Layer *CreateBehindHookLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, LONG x1, LONG y1, LONG flags, struct Hook *hook, struct BitMap *bm2) struct Hook *InstallLayerHook(struct Layer *layer, struct Hook *hook) struct Hook *InstallLayerInfoHook(struct Layer_Info *li, struct Hook *hook) void SortLayerCR(struct Layer *layer, LONG dx, LONG dy) void DoHookClipRects(struct Hook *hook, struct RastPort *rport, struct Rectangle *rect) struct Layer *CreateLayerTagList(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, LONG x1, LONG y1, LONG flags, struct TagItem *tagList) struct Layer *GetFirstFamilyMember(struct Layer *l) LONG ChangeLayerVisibility(struct Layer *l, int visible) LONG IsLayerVisible(struct Layer *l) struct Region *ChangeLayerShape(struct Layer *l, struct Region *newshape, struct Hook *callback) ULONG ScaleLayer(struct Layer *l, struct TagItem *taglist) BOOL IsFrontmostLayer(struct Layer *l, BOOL check_invisible) BOOL IsLayerHiddenBySibling(struct Layer *l, BOOL check_invisible) (A0, void CollectPixelsLayer(struct Layer *l, struct Region *r, struct Hook *callback)