Screen Dump
Volume Number: 4
Issue Number: 2
Column Tag: Macintosh II
Screen Dump FKEY for Color Picts 
By Steven C. Sheets, Chicago, IL
In our first article, we saw how to create a plot in PICT format, complete with
the old style Quickdraw color. But, since our program did not include an open
command, how can we view the plot in color once it is made? If we try to snapshot the
color screen, we get a beep! What we need is a way to snapshot and view our plot
without having to turn off the color. Steve Sheets, from Apple’s Chicago technical
support office, shows us how to capture the screen on a Mac II with the color
enabled.And best of all, the picture is not rotated! Once we capture our plot, we want to
view it. Steve again comes to our rescue with a companion viewer DA for color PICTs.
Color Images: Saving and Loading
Since this column has given some examples of how to draw in Color on the Mac
//, now would be a good time to describe how to save and load color pictures. While a
specific file format can always be defined for an application, it is convenient to be able
to read generic file formats, so that various applications can share and port data.
When discussing graphics, the two generic file formats have always been MacPaint file
format and PICT file format. MacPaint format has always been considered the generic
Bitmap method of saving Mac graphics, while PICT format is the associated with object
oriented graphics programs (ie. MacDraw).
With the introduction of Color Quickdraw and the Mac //, things have changed
slightly. Unfortunately MacPaint file format can not be expanded to cover PixMap
graphics (ie. multiple colors per pixel). Nor is there any other PixMap file format
that has been widely accepted by developers (though there is a need). On the other
hand, PICT file format is nothing but an extension of a Quickdraw Picture Handle. With
the introduction of the Mac //, Quickdraw Pictures have been expanded to support
color. This article will talk about the new Color Quickdraw Picture format, the PICT
file format, and will touch briefly on using the Palette Manager to display a Picture in
the Color needed. The example sources, ColorImage DA and ColorImage FKEY, will
demonstrate how to save and read PICT file.
Quickdraw Picture Format
A Quickdraw Picture is a data structure that contains a sequence of Quickdraw
commands. To create a Picture, a program defines a Picture Frame (ie, a rectangle and
data structure) with the OpenPicture function. OpenPicture returns a handle to the
Picture data structure being created. At this point, the program can call any
Quickdraw command. Instead of being drawn on the current grafport, the command is
stored in the Picture for later use. A ClosePicture command needs to be issued to tell
Quickdraw to stop saving the commands into the Picture Handle. Once the program has
a Picture, it can display it using the DrawPicture call. This will draw the Picture (ie.
all the Quickdraw commands saved in the Picture) into a destination rectangle. If the
destination rectangle is not the same size as the picture frame, the picture will be
expanded or reduced to fit the destination rectangle. The Plotter program in this issue
illustrates this traditional use of the Quickdraw picture.
The Picture handle points to a data structure which contains the Picture Size
(Integer picSize), the Picture Frame (Rect picFrame) and various Opcodes describing
the Quickdraw calls. Always ignore picSize. With the expansion of the Memory
Manager so that it can handle sizes beyond 32K, picSize is now ignored by Quickdraw.
Instead, the picture is played out until the end. If the Picture size is needed, call
GetHandleSize. Generally beyond picSize and picFrame, a program should not read the
data structures directly. The internal structures beyond this point are documented in
Inside Macintosh, Vol 5 and the various tech notes cited in the Pascal column.
An image stored and drawn as a Picture (using DrawPicture) is much more
compressed than the same image drawn using individual Quickdraw commands in the
code. Also the program can pass a Picture through the clipboard and Scrapbook to
other Applications. Notice while the Picture is considered an Object Graphic type of
data structure, one of the commands it stores is CopyBits. A Picture can thus have
BitMapped graphics in it.
Version 1 vs Version 2 Format
With the introduction of the Mac //, the Picture Format has been extended. The
old Picture format (called Version 1 Format) contains only the non-Color Quickdraw
commands. The newer Picture format (called Version 2 Format) contains all the Color
Quickdraw commands. On a Mac //, which Format is created with an OpenPicture call
depends on the current GrafPort. If an OpenPicture call is made when the current
GrafPort is a Color GrafPort, the Picture created is a Version 2 format. If a call is
made on a normal GrafPort, a Version 1 Picture is created. Obviously non-Mac //
computers can not create a Version 2 Picture. However, due to a patch in System 4.1
and later, an Enhanced Mac 512K, a MacPlus or a Mac SE can display a Version 2
Picture (not in color, of course).
While checking the Opcodes (Quickdraw picture commands) directly is not a good
idea, a program can identify which version of Picture it has by checking the first
integer past the picSize and picFrame. If this integer is 4353 ($1101), the Picture
is Version 1. If the integer is 17 ($0011), the Picture is Version 2.
Just as a Version 1 Picture can have bitmap graphics in it, a Version 2 Picture
can have a PixMap in it. Any CopyBits calls made following an OpenPicture, but before
a ClosePicture call, will store the data into the Picture. If the source was a PixMap
instead of a BitMap, the Picture handle will have both the bit data (compressed
format) and a color table (Color Look Up Table or CLUT) describing the colors used in
the PixMap.
PICT File Format
Knowing the Picture format, the PICT File Format is simple. A PICT file (ie. one
that has the Filetype ‘PICT’) consists of a data fork with a 512 byte header followed by
a picture data structure. The header is usually specific to the application that made it
(most programs ignore it). After the header, the picture data contains picSize,
picFrame and then the variable length Opcodes. As stated above, do not use picSize to
determine how much data follows. Instead, check the size of the file with a File I/O
call. Subtract 512 and that should be the size of the handle that the data should be read
into.
ColorImage FKEY Code
The ColorImage FKEY was designed to save the current screen to file, similar to
the Screen Save FKEY (Command-Shift-3). Instead of a MacPaint file being created, a
PICT file is created instead. A CopyBits call on the current screen is used when
creating the picture handle, which is then saved to the file.
The FKEY will work on any Macintosh. If the Macintosh has Color Quickdraw (ie.
Macintosh //), the Color Window Manager GrafPort is temporarily set before creating
the picture handle. Thus a version 2 PICT file will be created and any color images on
the screen will be saved. On a non-Color Quickdraw Macintosh (ie. Mac SE and
before), the normal Window Manager Port is used and a version 1 PICT file is created.
If the Caps Lock key is pressed, the entire screen is saved to a file. If the Caps Lock
key is not pressed and a front window exists, only the current window is saved to a file.
The picture is not saved to a set file name like the Screen Save FKEY, instead the user
is prompted for the file name. The image is also not rotated on a Mac II monitor. Thus
you won’t need to edit your screen dumps before using them in your documentation,
nor will you need to turn off your color interface as is the case with the old style
shift-cmd-3.
Remember, if the Screen was a PixMap instead of a Bitmap, the CLUT will be
saved into the PICT file along with the compressed bit data. Color PICTs are amazingly
packed files.
Reading a PICT file, however, is only half the job of displaying a color image
correctly. If the Picture contained Color Quickdraw commands (for example, a Color
Window saved with ColorImage FKEY), the user will want to see the Picture drawn
again using the original colors. For this, the Palette Manager needs to be used.
The Palette Manager establishes the color environment of the Mac //. It uses the
Color Manager (which controls what colors are used) to select the best colors for a
given display. The idea is that each window can have a Color Palette associated with it.
These are the Colors that the window wants the screen to be showing, in order to view
the window at it’s best. Unless there are to many windows needing to many colors,
each window gets it’s Palette. If there are not enough colors, highest priority goes to
the top most window. Every time the top most window changes (and it has an associated
Palette), the colors may change to give the new window it’s best appearance. The
Palette Manager will then issue an update event for all Palette windows so that they can
be redrawn to their best appearance in the new colors.
While an Application could use the Color Manager directly and bypass the Palette
Manager, this is not recommended. Such programming would fall apart in a color
Multiple task environment. Remember, Multifinder is not the only such environment.
There are also color DAs like ColorImage.
Thus the DA takes the Picture (if it is Version 2), searches for a CLUT, and tries
to create a Color Palette from it. The program does all this by temporarily replacing
the low-level quickdraw procs (specifically StdBits) with one that checks for a
PixMap, then transfers the RGB colors into a temporary buffer. The low-level
routines are replaced and the buffer is converted to a Color Palette. Then the Palette is
attached to the window so every time that particular window becomes the top most, the
screen colors are set to the Palette. This also causes an update of the window so the
Picture can be shown in it’s best colors.
ColorImage DA Code
The ColorImage Desk Accessory contains the complementing code to Color FKEY,
and more. The DA creates a window (Color Window if the CPU has Color Quickdraw) to
display Pictures in. The user can then select a PICT file and have it read into a Picture
handle. Since a user may want to know what colors are being used for a specific
Picture, the DA allows the users to switch between looking at the Picture or the
current Palette.
Think of two ColorImage DA’s that are loaded into the system. Each opens a
Picture with a radically different CLUT (one is a 256 color RGB Picture while the
other is a 256 shade Gray Scaled one). When the RGB Picture is clicked on, it becomes
the front window. The Palette Manager sets the 256 RGB colors (assuming the Color
Video Card has 8 Bits per Pixel). Both pictures are completely redrawn using the
current screen colors. Notice the Palette Manager caused the update; the program does
not have to keep track. The RGB Picture appears perfect, while the Gray Picture
(which can be seen behind the front window) appears as best as it can using the
current screen colors. Then the user wants to look at the Gray Picture. He clicks on
that window. It becomes front window, and the Palette Manager sets the current screen
to 256 shades of gray. The windows are redrawn. The Gray Picture appears perfectly,
while the RGB one appears as best it can using these new gray tones.
Last Comments
The ColorImage FKEY and Desk Accessory were created with LightSpeed Pascal
(LSP). Macintosh Programming Workshop (MPW) has it’s points. It is an extremely
powerful development system perfect for large projects. Being from Apple, MPW is
the first development system that has any new Trap Listings or new code interfaces.
LSP only recently has released the Mac // libraries and interfaces. MPW is also the
best Object Pascal system around. However LSP may be the best environment to
develop code segments (ie. DA, FKEYs, Window or Control Panel Definition
Procedures) for the Macintosh. Both code examples were tested from inside a test
program (a simple program that called the FKEY and a modified version of LSP
DAShell). This decreases development time since the various codes could be tested
without having to insert the DA or FKEY into the System file. The code could even be
stepped through one line at a time, perhaps the best feature of LSP!
This program requires the Palette manager. When LS Pascal version 1.11 was
released in September, Think did not include the Palette manager, nor the MultiFinder
routines. We are still waiting for both Think and Borland to upgrade their products to
MPW version 2.0 interfaces. You can add the Palette manager by taking the MPW 2.0
interface and adding it to your project. Remove the USES MemTypes and replace with
USES ColorQuickdraw instead. Then add “Implementation” to the end of the file and
your in business.
ColorImage DA could be expanded to check not only the PixMap’s CLUT in a
Picture, but could check other Color Quickdraw commands. Since the DA was designed
to work with the FKEY, checking the CLUT is all that is needed to function. The
program could also check for colors that are in the CLUT, but are NOT present in the
PixMap. Such colors are not displayed and need not be in the Palette.
Yet to come a full blown explanation of the Palette Manager and Palette
Animation!
{ ColorImage DA / FKEY by Steve Sheets 12/87 }
{ Saves the current Screen to a PICT file. If Cap Lock }
{is down, saves the entire screen. If the key is not & a}
{ Window exists, saves the window.}
UNIT UColorImageFKEY;
INTERFACE
PROCEDURE main;
IMPLEMENTATION
{ Returns the Color Window Manager Port. }
PROCEDURE CGetWMgrPort (VAR CWPort : GrafPtr);
INLINE
$AA48;
{ Does this CPU have color Quickdraw? }
FUNCTION ColorQDExists : boolean;
CONST
ROM85Loc = $28E;
TwoHighMask = $C000;
TYPE
WordPtr = ^INTEGER;
VAR
Wd : WordPtr;
BEGIN
Wd := POINTER(ROM85Loc);
ColorQDExists := (BitAnd(Wd^, TwoHighMask) = 0);
END;
{ Is Cap Lock key down? }
FUNCTION CapLockDown : BOOLEAN;
VAR
theMap : KeyMap;
BEGIN
GetKeys(theMap);
CapLockDown := BitTst(@theMap[1], 30);
END;
{ Given a flag saying color Quickdraw exists, returns}
{the Handle of a Picture and a flag saying if the window }
{was saved or if the entire screen was. }
PROCEDURE GetPic (VAR thePic : PicHandle;
VAR IsWindow : BOOLEAN;
QDExists : BOOLEAN);
TYPE
BitMapPtr = ^BitMap;
BitMapHdl = ^BitMapPtr;
VAR
sorcRect, destRect, mapRect : Rect;
OldPort, WPort : GrafPtr;
clip, vis : RgnHandle;
FWin : WindowPtr;
PixH : BitMapHdl;