| Draw Layers | ||
| Contents | |||||||
|
|||||||
CapeSoft Draw allows you to use multiple layers, each layer can be drawn on independently and data can be copied between layers. In addition, layers support both index transparency and alpha transparency, as well as a number of additional features. Some of the features provided by layers:
- Layers can be any size (not necessarily the same as the image control);
- Layers can be hidden, this means you can have hidden drawing surfaces that can be used as off screen buffers;
- Pixels can be copied in blocks of any size from any layer to any layer, with full control over the exact size and location of the block;
- Any layer can be drawn directly to the image control, and multiple layers can be composited into the image control.
- Drawing to a layer is as simple as selecting the layer with the WithLayer() method and then calling the Draw methods normally;
- Each layer supports index transparency (a single color can be selected as transparent);
- In addition each layer can have an associated alpha layer, which allows soft transparency effects. Alpha channels can be shared among multiple layers;
- Layers can be sorted in any order and and any number of layers can be displayed.
- Each alpha layer can store up to three alpha channels, each of which can be associated with as many layers as you like.
- In addition to copying block of pixels between layers you can copy sections of individual channels (the Red, Green and Blue components) between layer.
Each layer is an entry in the Draw.layers array. The size of the array (and hence the maximum number of layers that can be initialised) is determined by the Draw:numLayers equate in the Draw.inc file.
| layer data structure | |||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||
| Layer Methods | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
To create a new Layer call the InitLayer() method.
To draw to a layer call WithLayer() and then use the
Draw commands exactly as you would normally. When you call WithLayer() the current
layer number is stored in the Draw.activeLayer property.
This allows you to easily modify the currently layer simply by passing Draw.activeLayer
to any of the layer methods.
The first layer in the Draw.layers array is initialised when the Draw class
is initialised. If you prefer you can ignore the fact that layers exist and
just use Draw as you always have.
Draw automatically uses the alpha channel and index transparency settings for each layer when merging the layers for display.
You can set the displayMode (for index transparency, showing and hiding layers and alpha transparency) for each layer. The HideLayer() and ShowLayer() methods allow you to specify whether a layer is visible, the AddAlpha() method adds an alpha channel and automatically adds Draw:withAlpha flag to the displayMode variable for the selected layer. You can use IndexTransparency() to add an index transparency color to the layer and add Draw:indexTransparency to displayMode. In addition you can control all of the layer display attributes by calling the SetMode() method.
The actual layer display order is stored in the layerOrder array, which simply stores each of the layer numbers in the order that they are display in, basically this is the order that the layers are "stacked" in. This make it simple to rearrange the layer display order without changing the physical position of the layer in the layers array, which you should not do. See MoveLayer() and SwapLayers() for information. The first entry in the array is the bottom layer,and the layer at draw.numLayers is the top layer. Each time you create a new layer it is added after the last initialised layer, which means that it is on top of all other layers.
Although it is recommended that you use the methods provided, you can access any of the layer data directly, for example:
if
Drawer.layers[curLayer].init
!
check curLayer has been initialised
Drawer.layers[curLayer].displayMode = Draw:Hidden
! set the layer to hidden directly, rather than via SetMode()
end
If you choose to access the layer data directly it is advisable to understand the methods provided for layer data access, and how they manage the layer data. Often changing one layer variable necessitates a number of other changes.
The Draw object has a baseLayer property that you should treat as read only. It cannot be modified using any of the layer methods, however it is useful to access this layer's data, such as Draw.baseLayer.width and Draw.baseLayer.height, as this layer is the buffer onto which all layers are composited for display.
![]()
Click on the
(up)
icon to go back to the layer Method Index.
AddAlpha
(long layerNumber, long alphaLayer, byte channel)
Adds an alpha channel to an existing layer. Alpha channels are stored as the red, green and blue components of a layer. The alphaLayer and channel parameters are used to specify which layer to use as the alpha layer and which channel in the alpha layer to use for the alpha values. This method does not modify the display mode of the layer, so if the mode does not contain Draw:withAlpha you will need to call SetMode() to enable the alpha channel. You can call LayerMode() to query whether a particular display mode is enabled for a layer.
Parameters
| layerNumber | The layer to add the alpha channel to (no extra data is created, this is just a reference assignment). |
| alphaLayer | The source layer to be used. Typically an extra (hidden) layer would be created to be used as an alpha layer. |
| channel | Which of the RGB components should be used: Channel:Red,
Channel:Green or Channel:Blue. You can use a each channel in an alpha layer as the alpha channel for as many layers as you like, and each alpha layer can store three alpha channels, one in each of the RGB components. The alpha layer will automatically be set to hidden and have no index or alpha transparency when this method is called. |
Return Values
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap() with an error description.
Remarks
You can draw to an alpha layer the same as any other layer, simply by calling Draw.WithLayer(). The standard Draw methods can be used to manipulate a single channel by drawing in the relevant channel, or all three channels can be modified simultaneously (by drawing in a color that effects more than one channel, for example drawing in white will effect all three channels.). To Draw in the Red channel only colors from 000000h to 0000FFh can be used (Color:Black to Color:Red). To draw in the Green Channels colors with zero Red and Blue components can be used, eg.: 00FA00h, 006600h and 006B00h. The same goes for the blue channel, eg.: 0FF0000h, 0CB0000h and 0230000h.
Examples
alphaLayer
= 10 !
choose the layer to use as an alpha layer
if
drawer.LayerMode(layerNum, Draw:withAlpha) = 0 !
layer no alpha transparency
drawer.AddAlpha(layerNum, alphaLayer,
Channel:Red) !
use the red channel in alphaLayer
end
![]()
AlphaCopy(long src, long srcx, long srcy, long srcWidth, long
srcHeight, long dest, long destx, long desty),long
Internal Draw method. This method is called from CopyLayer to handle alpha blending when copying. This method should not be called directly, as all the functionality is encapsulated by CopyLayer.
![]()
CopyLayer
(long src, long srcX, long srcY, long srcWidth, long srcHeight, long dest, long
destX, long destY)
Copies a block of pixels from one layer to another. The block of pixels that is copied starts at the point (srcX, srcY) and the width and height are determined by the srcWidth and srcHeight parameters. The block is copied to the destination layer with the top left hand corner at the position (destX, destY). The method automatically handles clipping in both the source and destination layers. Automatically uses the index transparency and alpha settings of the layers. If a layer has index and alpha transparency, the index transparency is applied, and the alpha values are used for all pixels that are not the index color.
Parameters
|
src
|
The layer number of the source layer. |
|
srcX
|
The x-coordinate on the source layer of the top left hand corner of the block of pixels to copy |
|
srcY
|
The y-coordinate on the source layer of the top left hand corner of the block of pixels to copy |
|
srcWidth
|
The width of the block of pixels to copy from the source layer |
|
srcHeight
|
The height of the block of pixels to copy from the source layer |
|
dest
|
The layer number of the destination layer |
|
destX
|
The x-coordinate to copy the block of pixels to |
|
destY
|
The y-coordinate to copy the block of pixels to |
Return Values
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap() with an error description.
Remarks
If the source layer displayMode contains Draw:indexTransparency the index color is used, pixels that are the index color will not be copied into the destination buffer. Use IndexTransparency() to set the index color as well as turning index transparency on or off for the layer, or call SetMode() to turn index transparency on or off without modifying the layer's index color. To enable the use of an alpha channel call AddAlpha().
Examples
!
copy all the data in fromLayer to toLayer:
drawer.copyLayer(fromLayer,
1, 1, drawer.layers[fromLayer].width, drawer.layers[fromLayer].height, toLayer,
1, 1)
!
clipping is handled automatically, so only the data that fits onto the destination
layer is copied.
![]()
HideLayer
(long layerNumber)
Sets a layer to hidden.
Parameters:
|
layerNumber
|
The number of the layer to set to hidden. |
Return Values:
No return value. If the method fails it calls ErrorTrap()
with an error description.
Information:
Whether a layer is used when Display() is called
is determined by the layer's visibility. If the layer's displayMode
contains Draw:Hidden the layer is ignored, otherwise it is composited ("flattened")
with the rest of the layers when Display() is called. Use HideLayer()
to hide a layer and ShowLayer() to unhide it. Hidden
layers are useful as off screen buffers, temporary pixel storage areas and alpha
layers. Alpha layers are normally hidden, as you don't normally want to display
the pixel data they store directly.
Example:
if
drawer.LayerMode(layerNum, Draw:indexTransparency + Draw:withAlpha) !
layer has index and alpha transparency
drawer.HideLayer(layerNum) !
hide the layer
end
![]()
InitLayer
(long layerNumber, long width, long height, long xpos=1, long ypos=1, long indexColor=-1,
byte mode=0), long
Initialise a new layer. The numLayers property is incremented and the new layer is added at the first available entry in the Draw.layers array. The layer is added as the last entry in the Draw.displayOrder array, so it is below all the other layers in the display order. Call MoveLayer() or SwapLayer() to change the display order.
Parameters:
|
layerNumber
|
The number of the layer to initialise. If an existing
layer is specified, the layer is blanked, resized and the layer variable
set to the values passed.
|
|
width
|
The layer width in pixels
|
|
height
|
The layer height in pixels
|
|
xpos
|
The x-coordinate of the top left hand corner of the layer.
This is used when displaying layer to determine where the layer is place
in relation to the base layer.
|
|
ypos
|
The y-coordinate of the top left hand corner of the layer.
|
|
indexColor
|
The index color of the layer, optional
|
|
mode
|
The displayMode of the layer. Can be a combination of:
Draw:hidden, Draw:withAlpha and Draw:indexTransparency. To specify multiple
option simply add them together, for example: Draw:withAlpha + Draw:indexTransparency.
See the SetMode() method for a more detailed description
of the layer display mode.
|
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap() with an error description.
Information:
When a new layer is initialised the buffer is created, using the width and height parameters, and the layer variables are populated. Calling InitLayer() on an existing layer will dispose the old buffer an create a new buffer.
Example:
if
drawer.layers[curLayer].init = 0
! check
whether curLayer has been initialised
drawer.InitLayer(curLayer)
!
create the new layer
end
![]()
IndexTransparency
(long layerNumber, long indexColor, byte useIndex=1)
Set the color that should be treated as transparent for a particular layer,
you can use SetMode() to specify whether index transparency
is used or not without modifying the index color.
Parameters:
|
layerNumber
|
The number of the layer to set the index color for. Valid values are from two to Draw:numLayers. Layers[1] is the background layer and cannot use index transparency. If you pass the number of a layer that has not been initialised the Method will call ErrorTrap() and return 0. |
|
indexColor
|
The color that should be treated as transparent. Valid values are 0 to 0FFFFFFh (Color:black to Color:white). values outside this range will be ignored. |
|
useIndex
|
Allows you to set the layer's displayMode. Setting useIndex to zero will turn off index transparency, setting it to 1 will turn it on. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
The useIndex parameter is optional and allows you to set an index color
for future use, without currently enabling index transparency. If you don't
explicitly specify a value it defaults to enabling index transparency for the
layer.
Example:
if
drawer.LayerMode(Draw:indexTransparency) = 0 !
layer does not have index transparency
drawer.IndexTransparency(layerNum,
color:black, 1) !
all black pixels will be treated as transparent
end
![]()
HasAlpha (long layerNumber)
Returns 1 if the layer passed has an alpha layer assigned to it, returns zero
if it does not.
Parameters:
|
layerNumber
|
The number of the layer in the Draw.layers[] array to check for an associated alpha layer. |
Return Values:
Returns 1 if the layer passed has an alpha layer assigned to it, returns zero
if it does not.
![]()
KillLayer
(long layerNumber), long
Kill a layer and deallocate the memory that was used by the layer. This does
not kill any associated alpha channels. When Draw.Kill() is called it automatically
calls KillLayer() to destroy all existing layers, so it is not necessary to
do this manually.
Parameters:
|
layerNumber
|
The number of the layer to destroy. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Example:
if
drawer.layers[2].init !
layer 2 is initialised
if
drawer.KillLayer(2) = 0 !
all black pixels will be treated as transparent
!
error handling - the KillLayer() method failed
end
end
![]()
LayerMode
(long layerNumber, byte mode)
Returns 1 if the mode is enabled for the layer specified, and zero if the mode
is disabled.
Parameters:
|
layerNumber
|
The number of the layer to query the display mode for. |
|
mode
|
The mode, or combination of modes to query. |
Return Values:
Returns 1 is the layer has the mode enabled, and zero if it is disabled.
Example:
if
drawer.LayerMode(layerNum, Draw:indexTransparency + Draw:withAlpha) !
layer has index and alpha transparency
drawer.ShowLayer(layerNum) !
make sure the layer is visible
elsif drawer.LayerMode(layerMode,
Draw:indexTransparency) !
only index transparency
drawer.AddAlpha(layerNum, alphaLayer,
Channel:Red) !
add an alpha channel
else
drawer.HideLayer(layerNum) !
hide the layer
end
![]()
MoveLayer
(long layerNumber, long newPos), long
Changes the display order of a layer. Effectively this moves a layer up or down
in the "stack" of layers.
Parameters:
|
layerNumber
|
The number of the layer to move |
| newPos | The position in the array to move the layer to. The other entries are shifted to make space. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
The layer display order and the order in which the layers are stored in
the layers array is not related. The order in the layers array in maintained
by Draw and should not be changed, as layers can depend on one another. The
order in which the layers composited for display is determined by the order
of the layerOrder array. You can change the position of a layer by calling the
MoveLayer() to move a specific layer to a specific position, or call SwapLayers()
to swap the position of a pair of layers. The layerOrder array is a property
of the Draw class, it is an array of longs that stores the layer numbers in
the order that they should be displayed. Its size is determined by the Draw:numLayers
equate found in the Draw.inc file.
Example:
drawer.MoveLayer(layerNum, layerNum + 1) !
move the layer up one in the display order
![]()
NumLayers
( ), long
Returns the number of initialised layers. You can also use drawer.numLayers
property of the Draw object directly.
Return Values:
The number of initialised layers.
Information:
The NumLayers() method loops through the layers array and retrieves the
number of layers which have been initialised. In addition to the NumLayers()
method the Draw class has a numLayers property which
stores the current number of initialised layers and is incremented and decremented
by InitLayer() and KillLayer().
![]()
ResizeLayer
(long layerNumber, long width, long height), long
Resize a layer. ResizeLayer() resizes the layer buffer, while preserving the
data in the buffer, it also recalculates the layer properties, such as the bufferSize
and zeroPad.
Parameters:
|
layerNumber
|
The number of the layer to resize |
| width | The new layer width in pixels |
| height | The new layer height in pixels |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
Each layer is completely independent, so they can be any size that is
convenient. The Resize() method will perform the same
task, using the currently active layer (see Withlayer()).
ResizeLayer() allows you to resize any layer without having to make it active
first. If you increase the resolution of the primary layer it is advisable to
increase the resolution of other layers that you will be using. See Drawing
on Reports and Resize() for more information on resizing
and resolution.
![]()
SetMode
(long layerNumber, byte mode, byte value), long
SetMode allows you to change the layer's displayMode.
The displayMode is made up of a combination of Draw:Hidden, Draw:withAlpha and
Draw:indexTransparency. To turn any of the display options on or off for a layer
call SetMode with the layer number, the displayMode option and set the value
parameter to true or false, depending on whether
you would like to turn the mode on or off.
Parameters:
| layerNumber | The number of the layer that the displayMode should be set for. |
| mode | The mode to set. valid value are: Draw:Hidden, Draw:withAlpha and Draw:indexTransparency |
| value | If this is set to true the mode will be enable, if it is false it will be disabled. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
SetMode() allows you to temporarily turn display features on and off without
altering the layer itself. Note that Draw:withAlpha can only be set to true
if AddAlpha() has been called, similarly Draw:indexTransparency
can only be set to true if indexTransparency()
has been called. SetMode can be used to set whether the layer is hidden or not,
or you can simply call ShowLayer() and HideLayer().
Example:
Drawer.AddAlpha(pLayer,
alphaLayer, Channel:Red) !
Add an alpha channel
Drawer.SetMode(pLayer, Draw:withAlpha, false)
!
Don't use the alpha channel when displaying
Drawer.IndexTransparency(pLayer, Color:Black) !
Add an index transparency color
Drawer.HideLayer(pLayer)
!
Hide the layer
Drawer.Display() !
Display all visible layers,
!
pLayer is hidden and won't be displayed
Drawer.SetMode(pLayer, Draw:indexTransparency, false)
! Turn index Transparency off for
pLayer
Drawer.ShowLayer(pLayer) !
Unhide pLayer
Drawer.Display() !
Display all visible layers,
!
this time pLayer is visible and will be displayed.
Drawer.SetMode(pLayer, Draw:withAlpha, true)
!
Use the layer alpha channel
Drawer.Display()
!
Display all visible layers, including pLayer,
!
and use pLayer's alpha channel.
ShowLayer
(long layerNumber)
Sets the layer to visible.
Parameters:
|
layerNumber
|
The number of the layer to set to visible |
Return Values:
No return value. If the method fails it calls ErrorTrap()
with an error description.
Information:
Whether a layer is used when Display() is called
is determined by the layers visibility. If the layer's displayMode
contains Draw:Hidden the layer is ignored, otherwise it is composited ("flattened")
with the rest of the layers when Display() is called. Use HideLayer()
to hide a layer and ShowLayer() to unhide it. Hidden layers are useful as off
screen buffers, temporary pixel storage areas and alpha
layers. Alpha layers are hidden by default, as you don't normally want to display
the pixel data they store directly.
![]()
SwapLayers
(long layer1, long layer2)
Swap the display order of two layers.
Parameters:
|
layer1
|
The layer to swap with layer2 |
| layer2 | The layer to swap with layer1 |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
The layer display order and the order in which the layers are stored in
the layers array is not related. The order in the layers array in maintained
by Draw and should not be changed, as layers can depend on one another. The
order in which the layers composited for display is determined by the order
of the layerOrder array. You can change the position of a layer by calling the
MoveLayer() to move a specific layer to a specific
position, or call SwapLayers() to swap the position of a pair of layers. The
layerOrder array is a property of the Draw class, it is an array of longs that
stores the layer numbers in the order that they should be displayed. Its size
is determined by the Draw:numLayers equate found in the Draw.inc file.
![]()
ToAlpha
(long srcLayer, long destLayer, byte channel)
This copies a single channel from a source to a destination layer.
Parameters:
| srclayer | The layer to copy the data from (the source layer). |
| destLayer | The layer to copy the data to (the destination layer). |
| channel | Which of the RGB components should be copied, valid values are: Channel:Red, Channel:Green or Channel:Blue. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
Typically ToAlpha() is used for creating of modifying alpha channels. The
channel to be copied can be specified by setting the channel parameter
to Channel:Red, Channel:Green or Channel:Blue. This means three alpha channels
can be stored in a single layer, one in each of the RGB components, and all
three can be drawn to by simultaneously with the normal draw commands, after
calling WithLayer() to set the alpha layer as the currently
active layer for drawing to. See AddAlpha for more information
on alpha channels.
The effect of ToAlpha() is similar to CopyLayer(),
except that it only copies the RGB component specified, rather than all three
RGB components. Unlike CopyLayer() ToAlpha ignores any index transparency.
You can also get an alpha channel stored in a standard RGB bitmap using the
Image() method, or store an alpha channel in a bitmap by
calling WriteBMP() with the alpha channel as the active layer (call Withlayer()
to make a layer the current active layer).
Any standard 24 bit RGB bitmap can stored 3 alpha channels (one in each channel
in the bitmap: Red, Green and Blue), this also applies to any Draw layer, which
stores RGB information. To get the alpha channel from a bitmap simply make the
alpha layer active by calling Withlayer() and the use the Image() method to
draw the alpha values onto the layer. You can also use the Image() method to
draw the bitmap onto a temporary layer and just copy the desired alpha channel
onto the alpha layer by calling ToAlpha().
![]()
![]()
WithLayer
(ulong layerNumber)
Selects a layer to draw to.
Parameters:
|
layerNumber
|
Set the active layer for drawing to. |
Return Values:
Returns 1 for success and zero for failure. If the method fails it calls ErrorTrap()
with an error description.
Information:
When a layer is made active by calling WithLayer(),
all Draw commands are performed on that layer, with the exception of Display().
Display() will always display all non hidden layers.
If you wish to display a single layer simply set all other layers to hidden
(call SetMode()).
If layerNumber specifies an invalid layer the currently active layer is not
changed and the method returns zero. Initially the default layer of draw (Draw.layers[1])
is active, so regardless of how many layers you create using InitLayer(),
you only need to call WithLayer() when you want to change the active layer.
These are the Draw class properties that are useful when working with layers. You can access all these properties directly (they are not private and so you don't need accessor method). Unless otherwise stated you should avoid modifying the properties directly.
activeLayer
The currently active Draw layer, this is set by the WithLayer method
and is useful for calling method that need to be applied to the currently layer.
To set the current active layer call Draw.WithLayer().
This property should be treated as read only.
Example:
drawer.SetMode(drawer.activelayer,
Draw:withAlpha, false) !
Turn off the use of an alpha channel for the current layer
drawer.HideLayer(drawer.activeLayer) !
Hide the current layer
See Also:
SetMode( )
![]()
This is the layer onto which Draw composites all the layers together when Draw.Display() is called. The baseLayer is always the same size as the image control, so it is often useful to refer to its properties. The baseLayer should be treated as read only.
Examples
!
Create a new layer the same size as the base layer, with black as the index
transparency color
! and the displayMode set to draw:indexTransparency
drawer.InitLayer(drawer.numLayers + 1, drawer.baseLayer.width,
drawer.baseLayer.height, 1, 1, |
color:black,
draw:indexTransparency)
See Also
![]()
The number of initialised layers for the current Draw object. This property should be treated as read only. Don't confuse this with the Draw:numLayers equate, which is the maximum number of layers supported by the Draw Object, this is the number of layers that
Examples
! Initialise
a new layer with the same width and height as the base layer, positioned at
(1,1)
! and using black as the transparency index color.
if drawer.InitLayer(drawer.numlayers + 1, drawer.baseLayer.width, drawer.baseLayer.height,
|
1,
1, color:black, draw:indexTransparency)
!
Initialisation successful, drawer.numLayers will have been incremented
else
!
Layer initialisation failed, Draw.ErrorTrap() was called, handle error.
end
See Also
![]()
Copyright © 2008 CapeSoft Software (Pty) Ltd