Aros/开发人员/文档/库/图层
图层是一个矩形的绘图区域。每个 Intuition 窗口都关联着一个图层结构。Intuition 窗口是将图层添加到 Intuition 屏幕的唯一支持方法。使用 Intuition 窗口调用
图层结构是只读的。应用程序绝不应直接修改图层结构的任何元素。此外,应用程序只能读取图层结构的 front、back、rp、bounds、Flags、SuperBitMap 和 DamageList 元素。
创建图层时,会自动创建一个 RastPort 与其关联。指向 RastPort 的指针包含在图层数据结构中。使用此 RastPort,应用程序可以在图层的边界矩形中绘制任何位置。如果应用程序尝试在该矩形外部绘制,图形例程将裁剪图形。
使用 layers.library 调用创建 rastport,您将获得裁剪。您只需将您的位图附加到由 layers.lib 创建的此 rastport。正常的图形操作仅在存在图层时才执行裁剪。
应仅指定一个图层类型标志(LAYERSIMPLE、LAYERSMART 和 LAYERSUPER)。
通过使用 InitVPort()、InitView()、MakeVPort()、MrgCop() 和 LoadView() 原语创建
layers.library 依赖于 graphics.library,graphics.library 依赖于 layers.library - 这种循环依赖是否预期?这是由于 layers.library 的自动生成的 __LIBS_LIST__ 造成的。graphics.library 明确调用 layers.library 的 OpenLibrary()
图形原语用于通过调用 CreateUpfrontLayer() 或 CreateBehindLayer() 在通用位图上创建低级图形显示
struct Layer_Info *NewLayerInfo( void );
void DisposeLayerInfo( struct Layer_Info *li );
如何在没有位图的情况下创建图层?
通常调用 NewLayerInfo 和 CreateUpfrontLayer(需要位图指针)并从 layer->rp 获取一个已初始化的 RastPort。
RastPort 宽度和高度为 15 位(struct Rectangle 包含 WORD,而不是 UWORD)。一个具有 32k 像素的正方形位图将超过 1000 兆像素。
使用例程 InstallClipRegion() 在图层内创建矩形裁剪(允许图形函数)
struct Region *NewRegion( void );
void DisposeRegion( struct Region *region );
Intuition 和 Layers,由于它们的根源在于 MorphOS(因为 MorphOS 的根源在于 AROS),但已经从 OS4 中添加了一些扩展。主要问题是窗口形状的实现。MOS 和 AOS4 都具有此机制,但 API 不同。我们自己的变体接近 AOS4(也许他们以它为基础),因此我将其修复以使其兼容(除了 ChangeLayerShape() 函数 - 尚未完成)。
1. 如果有人可以确认该实现与 OS4 兼容?我尝试使用 Google 搜索一些 AOS4 代码示例,但未能找到。
2. 有人可以帮助我完成 ChangeLayerShape() 吗?它应该使用相同的钩子,根据 OS4 自述文档。不幸的是,我对 Layers 的理解非常糟糕。
3. 我们的 API 更适合遵循 MorphOS 而不是 OS4。这主要是因为我们使用库向量进行函数调用,而不是接口。这使得将来能够与 MorphOS 保持二进制兼容性。因此,从逻辑上讲,应该实现 MorphOS 版本的整形。只有一个显着区别:MorphOS 版本是 AOS 版本的逆。即在 OS4 中,我们提供了一个描述可见区域的区域,在 MorphOS 中,我们提供了一个描述不可见区域的区域。因此,是否应该切换到 MorphOS 变体,还是实现对两者的支持?我认为这两个版本并非十分冗余,代码量将会很小。
使用 Thomas Rapp 的 backfill 示例 的稍微修改后的版本。尝试更改 backfill 钩子函数以使用
(msg->bounds.MinX - layer->bounds.MinX); (msg->bounds.MinY - layer->bounds.MinY);
在使用的地方
msg->offsetx msg->offsety
参见 workbench/demos/winbackfill.c。
#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;
}
void 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)