Copyright (c) Hyperion Entertainment and contributors.
Difference between revisions of "Graphics Regions"
(Regions Example: code corrections by Doug Stastny) |
(Added links to library pages; fixed a few minor things) |
||
(One intermediate revision by the same user not shown) | |||
Line 3: | Line 3: | ||
Regions allow the application to install clipping rectangles into layers. A clipping rectangle is a rectangular area into which the graphics routines will draw. All drawing that would fall outside of that rectangular area is clipped (not rendered). |
Regions allow the application to install clipping rectangles into layers. A clipping rectangle is a rectangular area into which the graphics routines will draw. All drawing that would fall outside of that rectangular area is clipped (not rendered). |
||
− | User clipping regions are linked lists of clipping rectangles created by an application program through the |
+ | User clipping regions are linked lists of clipping rectangles created by an application program through the [[Graphics Library]] routines described below. By combining together various clipping rectangles, any arbitrary clipping shape can be created. Once the region is set up, you use the [[Layers Library]] call InstallClipRegion() to make the clipping region active in a layer. |
− | Regions are safe to use with layers created by Intuition (i.e. |
+ | Regions are safe to use with layers created by Intuition (i.e. windows). |
The application can selectively update a custom-shaped part of a layer without disturbing any of the other layers that might be present. |
The application can selectively update a custom-shaped part of a layer without disturbing any of the other layers that might be present. |
||
− | {{Note|title=Never |
+ | {{Note|title=Never modify the DamageList of a layer directly|text=Use the routine InstallClipRegion() to add clipping to the layer. The regions installed by InstallClipRegion() are independent of the layer's DamageList and use of user clipping regions will not interfere with optimized window refreshing.}} |
− | {{Note|title=Do |
+ | {{Note|title=Do not modify a region after it has been added|text=After a region has been added with InstallClipRegion(), the program may not modify it until the region has been removed with another call to InstallClipRegion().}} |
=== Creating and Deleting Regions === |
=== Creating and Deleting Regions === |
||
Line 31: | Line 31: | ||
DisposeRegion() returns all memory associated with a region to the system and deallocates all rectangles that have been linked to it. |
DisposeRegion() returns all memory associated with a region to the system and deallocates all rectangles that have been linked to it. |
||
− | {{Note|title=Don't |
+ | {{Note|title=Don't forget to free your rectangles|text=All of the functions that add rectangles to the region make copies of the rectangles. If the program allocates a rectangle, then adds it to a region, it still must deallocate the rectangle. The call to DisposeRegion() will not deallocate rectangles ''explicitly allocated'' by the application.}} |
=== Installing Regions === |
=== Installing Regions === |
||
Line 66: | Line 66: | ||
</syntaxhighlight> |
</syntaxhighlight> |
||
− | {{Note|title=A |
+ | {{Note|title=A warning about InstallClipRegion()|text=The program must not call InstallClipRegion() inside of a Begin/EndRefresh() or Begin/EndUpdate() pair. The following code segment shows how to modify the user clipping region when using these calls. See the Autodoc for BeginRefresh() for more details.}} |
<syntaxhighlight> |
<syntaxhighlight> |
||
Line 107: | Line 107: | ||
Regions may be modified by performing logical operations with rectangles, or with other regions. |
Regions may be modified by performing logical operations with rectangles, or with other regions. |
||
− | {{Note|title=Reuse |
+ | {{Note|title=Reuse your rectangles|text=In all of the rectangle and region routines the clipping rectangle is copied into the region. This means that a single clipping rectangle (Rectangle structure) may be used many times by simply changing the ''x'' and ''y'' values. The application need ''not'' create a new instance of the Rectangle structure for each rectangle added to a region.}} |
For instance: |
For instance: |
||
Line 124: | Line 124: | ||
rect.MaxY = (ktr * 10); |
rect.MaxY = (ktr * 10); |
||
− | if (! |
+ | if (!IGraphics->OrRectRegion(RowRegion, &rect)) |
clean_exit(RETURN_WARN); |
clean_exit(RETURN_WARN); |
||
} |
} |
||
Line 131: | Line 131: | ||
==== Rectangles and Regions ==== |
==== Rectangles and Regions ==== |
||
− | There are four functions for changing a region through logical operations with a rectangle. |
+ | There are four [[Graphics Library]] functions for changing a region through logical operations with a rectangle. |
<syntaxhighlight> |
<syntaxhighlight> |
||
Line 150: | Line 150: | ||
==== Regions and Regions ==== |
==== Regions and Regions ==== |
||
− | As with rectangles and regions, there are four |
+ | As with rectangles and regions, there are four functions for combining regions with regions: |
<syntaxhighlight> |
<syntaxhighlight> |
||
Line 169: | Line 169: | ||
=== Regions Example === |
=== Regions Example === |
||
− | The following example shows the use of the |
+ | The following example shows the use of the [[Layers Library]] call InstallClipRegion(), as well as simple use of the [[Graphics Library]] regions functions. |
<syntaxhighlight> |
<syntaxhighlight> |
||
/* clipping.c */ |
/* clipping.c */ |
||
+ | |||
− | |||
/* Force use of new variable names to help prevent errors */ |
/* Force use of new variable names to help prevent errors */ |
||
#define INTUI_V36_NAMES_ONLY |
#define INTUI_V36_NAMES_ONLY |
||
+ | |||
− | |||
#include <exec/types.h> |
#include <exec/types.h> |
||
#include <intuition/intuition.h> |
#include <intuition/intuition.h> |
||
#include <intuition/intuitionbase.h> |
#include <intuition/intuitionbase.h> |
||
#include <graphics/displayinfo.h> |
#include <graphics/displayinfo.h> |
||
+ | |||
− | |||
#include <proto/exec.h> |
#include <proto/exec.h> |
||
#include <proto/dos.h> |
#include <proto/dos.h> |
||
Line 187: | Line 187: | ||
#include <proto/graphics.h> |
#include <proto/graphics.h> |
||
#include <proto/layers.h> |
#include <proto/layers.h> |
||
+ | |||
− | |||
#define MY_WIN_WIDTH (300) |
#define MY_WIN_WIDTH (300) |
||
#define MY_WIN_HEIGHT (100) |
#define MY_WIN_HEIGHT (100) |
||
+ | |||
− | |||
struct IntuitionIFace *IIntuition; |
struct IntuitionIFace *IIntuition; |
||
struct GraphicsIFace *IGraphics; |
struct GraphicsIFace *IGraphics; |
||
struct LayersIFace *ILayers; |
struct LayersIFace *ILayers; |
||
+ | |||
− | |||
/* |
/* |
||
** unclipWindow() |
** unclipWindow() |
||
Line 205: | Line 205: | ||
{ |
{ |
||
struct Region *old_region; |
struct Region *old_region; |
||
+ | |||
− | |||
/* Remove any old region by installing a NULL region, |
/* Remove any old region by installing a NULL region, |
||
** then dispose of the old region if one was installed. |
** then dispose of the old region if one was installed. |
||
Line 212: | Line 212: | ||
IGraphics->DisposeRegion(old_region); |
IGraphics->DisposeRegion(old_region); |
||
} |
} |
||
+ | |||
− | |||
/* |
/* |
||
** clipWindow() |
** clipWindow() |
||
Line 224: | Line 224: | ||
struct Region *new_region; |
struct Region *new_region; |
||
struct Rectangle my_rectangle; |
struct Rectangle my_rectangle; |
||
+ | |||
− | |||
/* set up the limits for the clip */ |
/* set up the limits for the clip */ |
||
my_rectangle.MinX = minX; |
my_rectangle.MinX = minX; |
||
Line 230: | Line 230: | ||
my_rectangle.MaxX = maxX; |
my_rectangle.MaxX = maxX; |
||
my_rectangle.MaxY = maxY; |
my_rectangle.MaxY = maxY; |
||
+ | |||
− | |||
/* get a new region and OR in the limits. */ |
/* get a new region and OR in the limits. */ |
||
if (NULL != (new_region = IGraphics->NewRegion())) |
if (NULL != (new_region = IGraphics->NewRegion())) |
||
Line 240: | Line 240: | ||
} |
} |
||
} |
} |
||
+ | |||
− | |||
/* Install the new region, and return any existing region. |
/* Install the new region, and return any existing region. |
||
** If the above allocation and region processing failed, then |
** If the above allocation and region processing failed, then |
||
Line 247: | Line 247: | ||
return(ILayers->InstallClipRegion(win->WLayer, new_region)); |
return(ILayers->InstallClipRegion(win->WLayer, new_region)); |
||
} |
} |
||
+ | |||
− | |||
/* |
/* |
||
** clipWindowToBorders() |
** clipWindowToBorders() |
||
Line 258: | Line 258: | ||
win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1)); |
win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1)); |
||
} |
} |
||
+ | |||
− | |||
/* |
/* |
||
** Wait for the user to select the close gadget. |
** Wait for the user to select the close gadget. |
||
Line 265: | Line 265: | ||
{ |
{ |
||
struct IntuiMessage *msg; |
struct IntuiMessage *msg; |
||
− | + | BOOL done; |
|
+ | |||
− | |||
done = FALSE; |
done = FALSE; |
||
+ | |||
while (FALSE == done) |
while (FALSE == done) |
||
{ |
{ |
||
Line 274: | Line 275: | ||
*/ |
*/ |
||
IExec->Wait(1L << win->UserPort->mp_SigBit); |
IExec->Wait(1L << win->UserPort->mp_SigBit); |
||
+ | |||
− | |||
while ( (FALSE == done) && |
while ( (FALSE == done) && |
||
(NULL != (msg = (struct IntuiMessage *)IExec->GetMsg(win->UserPort)))) |
(NULL != (msg = (struct IntuiMessage *)IExec->GetMsg(win->UserPort)))) |
||
Line 281: | Line 282: | ||
if (msg->Class == IDCMP_CLOSEWINDOW) |
if (msg->Class == IDCMP_CLOSEWINDOW) |
||
done = TRUE; |
done = TRUE; |
||
+ | |||
− | |||
IExec->ReplyMsg((struct Message *)msg); |
IExec->ReplyMsg((struct Message *)msg); |
||
} |
} |
||
} |
} |
||
} |
} |
||
+ | |||
− | |||
/* |
/* |
||
** Simple routine to blast all bits in a window with color three to show |
** Simple routine to blast all bits in a window with color three to show |
||
Line 301: | Line 302: | ||
IDOS->Printf("done\n"); |
IDOS->Printf("done\n"); |
||
} |
} |
||
+ | |||
− | |||
+ | |||
− | |||
/* |
/* |
||
** Show drawing into an unclipped window, a window clipped to the |
** Show drawing into an unclipped window, a window clipped to the |
||
Line 315: | Line 316: | ||
{ |
{ |
||
struct Region *old_region; |
struct Region *old_region; |
||
+ | |||
− | |||
draw_in_window(win,"Window with no clipping"); |
draw_in_window(win,"Window with no clipping"); |
||
+ | |||
− | |||
/* if the application has never installed a user clip region, |
/* if the application has never installed a user clip region, |
||
** then old_region will be NULL here. Otherwise, delete the |
** then old_region will be NULL here. Otherwise, delete the |
||
Line 326: | Line 327: | ||
draw_in_window(win,"Window clipped to window borders"); |
draw_in_window(win,"Window clipped to window borders"); |
||
unclipWindow(win); |
unclipWindow(win); |
||
+ | |||
− | |||
/* here we know old_region will be NULL, as that is what we |
/* here we know old_region will be NULL, as that is what we |
||
** installed with unclipWindow()... |
** installed with unclipWindow()... |
||
Line 334: | Line 335: | ||
draw_in_window(win,"Window clipped from (20,20) to (100,50)"); |
draw_in_window(win,"Window clipped from (20,20) to (100,50)"); |
||
unclipWindow(win); |
unclipWindow(win); |
||
+ | |||
− | |||
wait_for_close(win); |
wait_for_close(win); |
||
} |
} |
||
+ | |||
− | |||
+ | |||
− | |||
+ | |||
− | |||
/* |
/* |
||
** Open and close resources, call the test routine when ready. |
** Open and close resources, call the test routine when ready. |
||
Line 346: | Line 347: | ||
{ |
{ |
||
struct Window *win; |
struct Window *win; |
||
+ | |||
− | |||
struct Library *IntuitionBase = IExec->OpenLibrary("intuition.library", 50); |
struct Library *IntuitionBase = IExec->OpenLibrary("intuition.library", 50); |
||
IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase, "main", 1, NULL); |
IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase, "main", 1, NULL); |
||
+ | |||
− | |||
struct Library *GfxBase = IExec->OpenLibrary("graphics.library", 50); |
struct Library *GfxBase = IExec->OpenLibrary("graphics.library", 50); |
||
IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL); |
IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL); |
||
+ | |||
− | |||
struct Library *LayersBase = IExec->OpenLibrary("layers.library", 50); |
struct Library *LayersBase = IExec->OpenLibrary("layers.library", 50); |
||
ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL); |
ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL); |
||
+ | |||
− | |||
if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL) |
if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL) |
||
{ |
{ |
||
− | if (NULL != (win =IIntuition->OpenWindowTags(NULL, |
+ | if (NULL != (win = IIntuition->OpenWindowTags(NULL, |
WA_Width, MY_WIN_WIDTH, |
WA_Width, MY_WIN_WIDTH, |
||
WA_Height, MY_WIN_HEIGHT, |
WA_Height, MY_WIN_HEIGHT, |
||
Line 368: | Line 369: | ||
{ |
{ |
||
clip_test(win); |
clip_test(win); |
||
+ | |||
− | |||
IIntuition->CloseWindow(win); |
IIntuition->CloseWindow(win); |
||
} |
} |
||
} |
} |
||
+ | |||
− | |||
IExec->DropInterface((struct Interface*)ILayers); |
IExec->DropInterface((struct Interface*)ILayers); |
||
IExec->CloseLibrary(LayersBase); |
IExec->CloseLibrary(LayersBase); |
||
+ | |||
− | |||
IExec->DropInterface((struct Interface*)IGraphics); |
IExec->DropInterface((struct Interface*)IGraphics); |
||
IExec->CloseLibrary(GfxBase); |
IExec->CloseLibrary(GfxBase); |
||
+ | |||
− | |||
IExec->DropInterface((struct Interface*)IIntuition); |
IExec->DropInterface((struct Interface*)IIntuition); |
||
IExec->CloseLibrary(IntuitionBase); |
IExec->CloseLibrary(IntuitionBase); |
||
+ | |||
− | |||
return 0; |
return 0; |
||
} |
} |
||
Line 388: | Line 389: | ||
== Function Reference == |
== Function Reference == |
||
− | The following are brief descriptions of the |
+ | The following are brief descriptions of the [[Graphics Library]] functions related to regions. See the SDK for details on each function call. |
{| class="wikitable" |
{| class="wikitable" |
||
Line 395: | Line 396: | ||
|- |
|- |
||
| LockLayerRom() |
| LockLayerRom() |
||
− | | Same as LockLayer(), from |
+ | | Same as LockLayer(), from the [[Layers Library]]. |
|- |
|- |
||
| UnlockLayerRom() |
| UnlockLayerRom() |
Latest revision as of 11:45, 10 November 2017
Contents
Regions
Regions allow the application to install clipping rectangles into layers. A clipping rectangle is a rectangular area into which the graphics routines will draw. All drawing that would fall outside of that rectangular area is clipped (not rendered).
User clipping regions are linked lists of clipping rectangles created by an application program through the Graphics Library routines described below. By combining together various clipping rectangles, any arbitrary clipping shape can be created. Once the region is set up, you use the Layers Library call InstallClipRegion() to make the clipping region active in a layer.
Regions are safe to use with layers created by Intuition (i.e. windows).
The application can selectively update a custom-shaped part of a layer without disturbing any of the other layers that might be present.
Never modify the DamageList of a layer directly |
---|
Use the routine InstallClipRegion() to add clipping to the layer. The regions installed by InstallClipRegion() are independent of the layer's DamageList and use of user clipping regions will not interfere with optimized window refreshing. |
Do not modify a region after it has been added |
---|
After a region has been added with InstallClipRegion(), the program may not modify it until the region has been removed with another call to InstallClipRegion(). |
Creating and Deleting Regions
You allocate a Region data structure with the NewRegion() call.
struct Region *NewRegion( VOID );
The NewRegion() function allocates and initializes a Region structure that has no drawable areas defined in it. If the application draws through a new region, nothing will be drawn as the region is empty. The application must add rectangles to the region before any graphics will appear.
Use DisposeRegion() to free the Region structure when you are done with it.
VOID DisposeRegion( struct Region *region );
DisposeRegion() returns all memory associated with a region to the system and deallocates all rectangles that have been linked to it.
Don't forget to free your rectangles |
---|
All of the functions that add rectangles to the region make copies of the rectangles. If the program allocates a rectangle, then adds it to a region, it still must deallocate the rectangle. The call to DisposeRegion() will not deallocate rectangles explicitly allocated by the application. |
Installing Regions
Use the function InstallClipRegion() to install the region.
struct Region *InstallClipRegion( struct Layer *layer, struct Region *region );
This installs a transparent clipping region to a layer. All subsequent graphics calls will be clipped to this region. The region must be removed with a second call to InstallClipRegion() before removing the layer.
/* ** Sample installation and removal of a clipping region */ register struct Region *new_region ; register struct Region *old_region ; /* If the application owns the layer and has not installed a region, ** old_region will return NULL here. */ old_region = ILayers->InstallClipRegion(win->WLayer, new_region); /* draw into the layer or window */ if (NULL != (old_region = ILayers->InstallClipRegion(win->WLayer, old_region))) { /* throw the used region away. This region could be saved and ** used again later, if desired by the application. */ ILayers->DisposeRegion(new_region) ; }
A warning about InstallClipRegion() |
---|
The program must not call InstallClipRegion() inside of a Begin/EndRefresh() or Begin/EndUpdate() pair. The following code segment shows how to modify the user clipping region when using these calls. See the Autodoc for BeginRefresh() for more details. |
struct Region *new_region ; struct Region *old_region ; /* you have to have already setup the new_region and old_region */ IIntuition->BeginRefresh(window); /* draw through the damage list */ /* into the layer or window */ IIntuition->EndRefresh(window, FALSE); /* keep the damage list */ old_region = ILayers->InstallClipRegion(win->WLayer, new_region); IIntuition->BeginRefresh(window); /* draw through the damage list and the new_region */ /* into the layer or window */ IIntuition->EndRefresh(window, FALSE); /* keep the damage list */ /* put back the old region */ new_region = ILayers->InstallClipRegion(win->WLayer, old_region); IIntuition->BeginRefresh(window); IIntuition->EndRefresh(window, TRUE); /* remove the damage list */ old_region = ILayers->InstallClipRegion(win->WLayer, new_region); IIntuition->BeginRefresh(window); /* draw through the new_region only into the layer or window */ IIntuition->EndRefresh(window, FALSE); /* finally get rid of the new region, old_region still installed */ if (NULL != (new_region = ILayers->InstallClipRegion(win->WLayer, old_region))) ILayers->DisposeRegion(new_region) ;
Changing a Region
Regions may be modified by performing logical operations with rectangles, or with other regions.
Reuse your rectangles |
---|
In all of the rectangle and region routines the clipping rectangle is copied into the region. This means that a single clipping rectangle (Rectangle structure) may be used many times by simply changing the x and y values. The application need not create a new instance of the Rectangle structure for each rectangle added to a region. |
For instance:
extern struct Region *RowRegion; /* created elsewhere */ int16 ktr; struct Rectangle rect; for (ktr = 1; ktr < 6; ktr++) { rect.MinX = 50; rect.MaxX = 315; rect.MinY = (ktr * 10) - 5; rect.MaxY = (ktr * 10); if (!IGraphics->OrRectRegion(RowRegion, &rect)) clean_exit(RETURN_WARN); }
Rectangles and Regions
There are four Graphics Library functions for changing a region through logical operations with a rectangle.
BOOL OrRectRegion ( struct Region *region, struct Rectangle *rectangle ); VOID AndRectRegion ( struct Region *region, struct Rectangle *rectangle ); BOOL XorRectRegion ( struct Region *region, struct Rectangle *rectangle ); BOOL ClearRectRegion( struct Region *region, struct Rectangle *rectangle );
OrRectRegion() modifies a region structure by OR'ing a clipping rectangle into the region. When the application draws through this region (assuming that the region was originally empty), only the pixels within the clipping rectangle will be affected. If the region already has drawable areas, they will still exist, this rectangle is added to the drawable area.
AndRectRegion() modifies the region structure by AND'ing a clipping rectangle into the region. Only those pixels that were already drawable and within the rectangle will remain drawable, any that are outside of it will be clipped in future.
XorRectRegion() applies the rectangle to the region in an exclusive-or mode. Within the given rectangle, any areas that were drawable become clipped, any areas that were clipped become drawable. Areas outside of the rectangle are not affected.
ClearRectRegion() clears the rectangle from the region. Within the given rectangle, any areas that were drawable become clipped. Areas outside of the rectangle are not affected.
Regions and Regions
As with rectangles and regions, there are four functions for combining regions with regions:
BOOL AndRegionRegion( struct Region *srcRegion, struct Region *destRegion ); BOOL OrRegionRegion ( struct Region *srcRegion, struct Region *destRegion ); BOOL XorRegionRegion( struct Region *srcRegion, struct Region *destRegion ); VOID ClearRegion ( struct Region *region );
AndRegionRegion() performs a logical AND operation on the two regions, leaving the result in the second region. The operation leaves drawable areas wherever the regions drawable areas overlap. That is, where there are drawable areas in both region 1 AND region 2, there will be drawable areas left in the result region.
OrRegionRegion() performs a logical OR operation on the two regions, leaving the result in the second region. The operation leaves drawable areas wherever there are drawable areas in either region. That is, where there are drawable areas in either region 1 OR region 2, there will be drawable areas left in the result region.
XorRegionRegion() performs a logical exclusive-or operation on the two regions, leaving the result in the second region. The operation leaves drawable areas wherever there are drawable areas in either region but not both. That is, where there are drawable areas in either region 1 OR region 2, there will be drawable areas left in the result region. But where there are drawable areas in both region 1 AND region 2, there will not be drawable areas left in the result region.
ClearRegion() puts the region back to the same state it was in when the region was created with NewRegion(), that is, no areas are drawable.
Regions Example
The following example shows the use of the Layers Library call InstallClipRegion(), as well as simple use of the Graphics Library regions functions.
/* clipping.c */ /* Force use of new variable names to help prevent errors */ #define INTUI_V36_NAMES_ONLY #include <exec/types.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <graphics/displayinfo.h> #include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/layers.h> #define MY_WIN_WIDTH (300) #define MY_WIN_HEIGHT (100) struct IntuitionIFace *IIntuition; struct GraphicsIFace *IGraphics; struct LayersIFace *ILayers; /* ** unclipWindow() ** ** Used to remove a clipping region installed by clipWindow() or ** clipWindowToBorders(), disposing of the installed region and ** reinstalling the region removed. */ void unclipWindow(struct Window *win) { struct Region *old_region; /* Remove any old region by installing a NULL region, ** then dispose of the old region if one was installed. */ if (NULL != (old_region = ILayers->InstallClipRegion(win->WLayer, NULL))) IGraphics->DisposeRegion(old_region); } /* ** clipWindow() ** Clip a window to a specified rectangle (given by upper left and ** lower right corner.) the removed region is returned so that it ** may be re-installed later. */ struct Region *clipWindow(struct Window *win, LONG minX, LONG minY, LONG maxX, LONG maxY) { struct Region *new_region; struct Rectangle my_rectangle; /* set up the limits for the clip */ my_rectangle.MinX = minX; my_rectangle.MinY = minY; my_rectangle.MaxX = maxX; my_rectangle.MaxY = maxY; /* get a new region and OR in the limits. */ if (NULL != (new_region = IGraphics->NewRegion())) { if (FALSE == IGraphics->OrRectRegion(new_region, &my_rectangle)) { IGraphics->DisposeRegion(new_region); new_region = NULL; } } /* Install the new region, and return any existing region. ** If the above allocation and region processing failed, then ** new_region will be NULL and no clip region will be installed. */ return(ILayers->InstallClipRegion(win->WLayer, new_region)); } /* ** clipWindowToBorders() ** clip a window to its borders. ** The removed region is returned so that it may be re-installed later. */ struct Region *clipWindowToBorders(struct Window *win) { return(clipWindow(win, win->BorderLeft, win->BorderTop, win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1)); } /* ** Wait for the user to select the close gadget. */ VOID wait_for_close(struct Window *win) { struct IntuiMessage *msg; BOOL done; done = FALSE; while (FALSE == done) { /* we only have one signal bit, so we do not have to check which ** bit broke the Wait(). */ IExec->Wait(1L << win->UserPort->mp_SigBit); while ( (FALSE == done) && (NULL != (msg = (struct IntuiMessage *)IExec->GetMsg(win->UserPort)))) { /* use a switch statement if looking for multiple event types */ if (msg->Class == IDCMP_CLOSEWINDOW) done = TRUE; IExec->ReplyMsg((struct Message *)msg); } } } /* ** Simple routine to blast all bits in a window with color three to show ** where the window is clipped. After a delay, flush back to color zero ** and refresh the window borders. */ VOID draw_in_window(struct Window *win, UBYTE *message) { IDOS->Printf("%s...", message); IGraphics->SetRast(win->RPort, 3); IDOS->Delay(200); IGraphics->SetRast(win->RPort, 0); IIntuition->RefreshWindowFrame(win); IDOS->Printf("done\n"); } /* ** Show drawing into an unclipped window, a window clipped to the ** borders and a window clipped to a random rectangle. It is possible ** to clip more complex shapes by AND'ing, OR'ing and exclusive-OR'ing ** regions and rectangles to build a user clip region. ** ** This example assumes that old regions are not going to be re-used, ** so it simply throws them away. */ VOID clip_test(struct Window *win) { struct Region *old_region; draw_in_window(win,"Window with no clipping"); /* if the application has never installed a user clip region, ** then old_region will be NULL here. Otherwise, delete the ** old region (you could save it and re-install it later...) */ if (NULL != (old_region = clipWindowToBorders(win))) IGraphics->DisposeRegion(old_region); draw_in_window(win,"Window clipped to window borders"); unclipWindow(win); /* here we know old_region will be NULL, as that is what we ** installed with unclipWindow()... */ if (NULL != (old_region = clipWindow(win,20,20,100,50))) IGraphics->DisposeRegion(old_region); draw_in_window(win,"Window clipped from (20,20) to (100,50)"); unclipWindow(win); wait_for_close(win); } /* ** Open and close resources, call the test routine when ready. */ int main(int argc, char **argv) { struct Window *win; struct Library *IntuitionBase = IExec->OpenLibrary("intuition.library", 50); IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase, "main", 1, NULL); struct Library *GfxBase = IExec->OpenLibrary("graphics.library", 50); IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL); struct Library *LayersBase = IExec->OpenLibrary("layers.library", 50); ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL); if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL) { if (NULL != (win = IIntuition->OpenWindowTags(NULL, WA_Width, MY_WIN_WIDTH, WA_Height, MY_WIN_HEIGHT, WA_IDCMP, IDCMP_CLOSEWINDOW, WA_CloseGadget, TRUE, WA_DragBar, TRUE, WA_Activate, TRUE, TAG_END))) { clip_test(win); IIntuition->CloseWindow(win); } } IExec->DropInterface((struct Interface*)ILayers); IExec->CloseLibrary(LayersBase); IExec->DropInterface((struct Interface*)IGraphics); IExec->CloseLibrary(GfxBase); IExec->DropInterface((struct Interface*)IIntuition); IExec->CloseLibrary(IntuitionBase); return 0; }
Function Reference
The following are brief descriptions of the Graphics Library functions related to regions. See the SDK for details on each function call.
Routine | Description |
---|---|
LockLayerRom() | Same as LockLayer(), from the Layers Library. |
UnlockLayerRom() | Release LockLayerRom() lock. |
AttemptLockLayerRom() | Lock layer only if it is immediately available. |
NewRegion() | Create a new, empty region. |
DisposeRegion() | Dispose of an existing region and its rectangles. |
AndRectRegion() | And a rectangle into a region. |
OrRectRegion() | Or a rectangle into a region. |
XorRectRegion() | Exclusive-or a rectangle into a region. |
ClearRectRegion() | Clear a rectangular portion of a region. |
AndRegionRegion() | And two regions together. |
OrRegionRegion() | Or two regions together. |
XorRegionRegion() | Exclusive-or two regions together. |
ClearRegion() | Clear a region. |