SuperPaint Plug-in
Volume Number: 8
Issue Number: 1
Column Tag: Pascal Workshop
Superpaint Airbrush Masking
A plug-in for creating & using masks
By Allen Stenger, Gardena, California
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
The airbrushes and spray cans included in paint programs tend to spatter areas
next to the one you want to paint, making it difficult to paint neatly. Artists using real
airbrushes have the same problem, but solve it with masks and shields. A mask is a
piece of acetate or similar material, cut to cover the areas to be protected from paint,
and pasted to the surface. The artist paints the exposed area with the airbrush, then
peels away the mask. A shield is similar, but it is held in one hand (instead of being
pasted down) and moved around while the other hand paints with the airbrush.
This article gives a plug-in program for creating and using masks in
SuperPaint.
Taking Liberties
Our masks are implemented by the slightly devious method of saving the area
under the mask, then restoring it later to “peel off” the mask. This is a kind of cut and
paste, and perhaps cut and paste could be used sometimes, although it is hard to control
exactly where the pasted object goes.
You define a mask using a selection tool. When SuperPaint calls the plug-in, it
describes the selection as a BitMap where the bit image has 1’s in the selected pixels
(like CalcMask’s output). We store this BitMap as the mask, offsetting its boundsRect
so that the mask is in document coordinates. (Selections made with the selection
rectangle are not described this way; we get the Rect and make our own BitMap.) You
also can cut out parts of the mask; this is handled the same way, except that we use
CopyBits with the srcBic transfer mode to remove the cut-out area from the saved
BitMap. Capturing the image under the mask is also done with CopyBits; restoring it
uses CopyMask to restore only those pixels under the mask.
One drawback of using selection tools to define the mask is that the mask is
invisible! To get around this I added a “Tint Mask” command that inverts all pixels
under the mask. By first capturing the area under the mask, you can then tint the mask
to see where you’re painting; restoring under the mask obliterates the tint.
SuperPaint painting commands are described formally as “Black and White
transformation commands,” and typically transform an area on a single call rather
than building up a transform across several calls, as we do here. There’s nothing wrong
with our approach, although the interface is clumsy since you must always select
something (usually an area containing the mask) for each call.
Example
This is an exercise from Vero’s book. Start by making the mask, which is an
outline of the drop. Draw a Bezier in the Draw layer (I start with an oval and bend it
into shape). Then cut this into the Paint layer.
First draw the shadow. Select the mask with the lasso, and command Outline A
Mask. Open a new window, command Capture Under Mask, then Tint Mask. (Note that the
Masker does not remember which window it was in.) Use the airbrush set for 25%
flow, 4 pixels and faded to paint the shadow with a 50% gray. Be sure the boundary is
well-defined; keep spraying until it is thick enough. Use the Command Restore Under
Mask to check your progress. Now mask the outside of the drop by going back to the mask
window, selecting the window (double-click on the selection rectangle), commanding
Outline A Mask, then selecting the outline with the lasso and commanding Remove From
Mask. Go back to the drop window, select the entire window, and command Capture Under
Mask. Fill the window with 12.5% gray, then Restore Under Mask to get the drop. Paint
the highlight with white, using a horizontal blade brush (1 x 8 pixels). Lighten the
bottom edge of the drop with the airbrush set for 25% flow, 8 pixels and faded. Touch
up with a white brush if needed.
Possible Improvements
I’ve tried to keep this program simple and therefore easily understandable. Some
additional complications that you might want to add are:
• Allow addition of areas to the mask. This was omitted because it might require
adjusting the size of the BitMap bounds, but it’s not e specially difficult to do. (A
neater way than using BitMaps would be to represent the mask as a region, using
QuickDraw routines to add to and subtract from the mask. Unfortunately, there is
no standard way to convert the BitMap passed to the plug-in by SuperPaint into a
region.)
• Nudge or shift a mask after creation. A little thought is needed to devise a
convenient human interface for commanding this, but the operation is simple
(offset the boundsRect).
• Allow the user to set the Tint pattern (e.g., as the current fill pattern, which is
also passed to the plug-in by SuperPaint).
• Form the complement of a mask. In physical terms this corresponds to cutting
holes from a mask and using both the mask and the cut-out portions as masks. This
can be done as in the example, but it would be easier to have a new command.
These are some miscellaneous notes that may be helpful in understanding the
program.
• All the Pascal files BWtc.p included in the Toolkit omit the fillPatNone and
linePatNone fields, causing all later fields to be at the wrong offset. (The C and
Asm files are correct.) This is corrected in the BWtc.p listing below.
• An important correspondence (not mentioned in the Toolkit documentation) is
that selectRect and the GrafPort’s portRect represent the same area; selectRect is
in document coordinates and portRect is in local coordinates. This correspondence
allows us to map between the current selection and the document’s coordinates.
• The statement in the Toolkit documentation that the GrafPort is set to the
selection is not completely correct. More accurately, the GrafPort is set to an
offscreen copy of part of the document containing the selection. After the plug-in
runs, SuperPaint copies the offscreen version back into the selected portion of the
document.
• The lassoMaskBits record is set correctly for all selection tools other than the
rectangle. The Toolkit documentation implies it is only valid for selections made
with the Lasso.
[Also note, after this article was submitted, Aldus released SuperPaint 3.0
presenting two problems. The first of which is that Aldus has evidently abandoned 2.0
plug-ins by redefining the interface and providing no support for earlier interfaces.
Second, 3.0 has some masking features. For the many users, who are choosing to not
move to 3.0 because it is so incredibly slow, this tool is still useful. More importantly,
it shows the basic methodology to using “plug-in tools”. - Ed.]
For Further Reading
If you are interested in further information on this topic, you might want to look
at the following sources.
• Radu Vero, Airbrush: The Complete Studio Handbook. Watson-Guptill
Publications, 1983. A good introduction to airbrush work. The example is on page
74 (exercise 14).
• Michael Ogawa, “BitMapper Utility For SuperPaint.” MacTutor, February
1990, pp. 28-40. Another example of a paint com-mand for SuperPaint. One of
three related articles in this issue.
• “SuperPaint Plug-In Developer’s Toolkit.” Distributed by Silicon Beach. Send
$15 to Silicon Beach Software, Inc., P.O. Box 262460, Dept. 20, San Diego, CA
92126. One disk, containing much documentation, source files defining the
interfaces, and examples.
• Macintosh Technical Note #193, “So Many Bitmaps, So Little Time,” December
1989. Describes a new trap, BitMapToRegion, which is included in 32-bit
QuickDraw and available separately under license from Apple. The trap is also
described in Inside Macintosh, v. VI, p. 17-25.
• Ted Cohn, “Convert PICTs to Regions.” MacTutor, June 1989 (reprinted in Best
of MacTutor v. 5, pp. 11-16). Gives routines for converting BitMaps and PICTs
to regions.
About the author
Allen Stenger is a programmer for a large metropolitan radar house. He may be
reached on AppleLink at “STENGER”.
Source Listings
Your first step is to set up a new THINK Pascal project that should look like the
one in Figure 1.
Figure 1: THINK Pascal Project Window
Remember, you are writing a code resource here, so you will need to set the
project type as in Figure 2.
Figure 2: Set Project Type Dialog Listing: BWtc.p
{ File: BWtc.p}
{ COPYRIGHT © 1989 Silicon Beach Software, Inc.}
{ All Rights Reserved}
{ Modified by Allen Stenger, July 1991, to add }
{ missing fields fillPatNone, linePatNone }
unit BWtc;
interface