跳轉到內容

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) 
華夏公益教科書