跳转到内容

Aros/开发人员/文档/库/图层

来自维基教科书,开放的书籍,开放的世界
Aros 维基教科书的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题解答
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发人员文档
从 AmigaOS/SDL 移植软件
Zune 初学者
Zune .MUI 类
SDL 初学者
Aros 开发人员构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
Motorola 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
杂项
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 变体,还是实现对两者的支持?我认为这两个版本并非十分冗余,代码量将会很小。


BackFill 钩子

[编辑 | 编辑源代码]

使用 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) 
华夏公益教科书