Drawing PICTures

Now that the source transfer modes were added for drawing text, a logical next step was adding support for drawing the most basic bitmap-only PICT resources. For this purpose, we added a very simple test PICT resource into the Fake ROM resources, which we used to test this feature.

More than a bitmap

What makes the basic QuickDraw PICT format different from many other image formats is the fact, that it is actually not a pure bitmap container, but rather a recording of drawing commands, which can be played back at any time. Basically this allows majority of QuickDraw commands to be “recorded” into a picture, and later played back. Even better, these pictures can be “played” also on other devices besides screen, such as printers! This allows a picture with geometric shapes to have a rasterized on-screen representation, but appear as a sharp image on for example a laser printer. Furthermore, these pictures can be scaled during playback to a target rectangle, allowing them to adapt to different screen/device sizes as appropriate. Of course, all this makes displaying a simple scanned bitmap photo of a cat a bit more complex than one would expect.

A simple PICT image

Attempting to create the monochrome old-style PICT resource was a bit challenging on modern Macs, so we ended up transferring the photo on the reliable good old PowerBook G3, and exporting to resource from there using old version of PhotoShop.

Playback time!

So basically what we needed to display the cat picture, was just take the PICT resource and do the following:

  1. Read the picture size and picFrame from the header
  2. Save copy of content of current GrafPort
  3. Set up defaults for the GrafPort (including new clipping region)
  4. Initialize a playback state record
  5. Execute each picture opCode from picture data one by one
  6. Dispose playback state and restore original GrafPort state

Even in this simple format, the following opcodes were required for the test PICT: Version, LongComment, PackBitsRect, and EndOfPicture.

Type 1 picture opcodes encountered in the cat PICT

All other opcodes were trivial to implement, except PackBitsRect which ended up using UnpackBits trap, so we had good excuse for implementing it also at this point. With unpacking implemented, the drawing ended up with a simple call to StdBits, which was was already previously added for text drawing, and we got the cat quickly on the screen:

First appearance of the cat PICT

As clipping was already implemented, we were able to goof around by drawing the PICT in funky clipping region (with some text added for fun):

Cat PICT drawn masked by another, larger region, which was later framed with FrameRgn using different sizes and patterns to create gradient edge