QuickDraw regions

As I mentioned on my post on trying out the Swift language, I decided to write a QuickDraw parser in Swift. One feature I never managed to get working on the Java version is regions.

QuickDraw regions were basically arbitrary masks for drawing operations, this is a standard feature of graphical user interfaces, but in the 80s, this was far from trivial. While most of the QuickDraw operations are pretty well described in the Inside Macintosh books, the region format was not documented. I found two good sources of information: first an article about Regions on the Long View web-site, and second an e-mail by Jack Palevich explaining the format.

While regions were a powerful mechanism, it seems its support was random, Apple’s documentation mentions that they were not supported by some printer drivers. The Preview Application on Mac OS X Sonoma (14.2) still opens QuickDraw pict files, but has trouble rendering them. I found a file called EDUC0052.pict representing King Harold death from the Bayeux Tapestry, the file is interesting because the outlines and coloured areas are encoded as regions, a perfect test file.

This is how Preview renders it.

King Harold's Death – Preview rendering

This is how my code renders it into a Core Graphics context

Quickdraw rendering of King Harold death's from the Bayeux Tapestry

So how are regions encoded? Basically, a region is size field (2 bytes), followed by the bounding rectangle (8 bytes), and then the actual data region (assuming it is not just a plain rectangle).

  • Data is encoded as sequence of 2 bytes integers (I assume unsigned).
  • Data is encoded on a per line basis.
  • Each line starts with the row number, this is an absolute coordinate (not relative to the bounding rect).
  • Empty rows are not not encoded.
  • Each line consists of start-end pairs, again in absolute coordinates.
  • Each line ends with the 0x7FFF end-marker.
  • The region ends with two consecutive end-markers

The decode data is not the actual bitmap of the region, you need to now XoR each line with the previous one to get the actual bitmap. In my case, I convert this bitmap into a sequence of rectangles, currently the code just encodes each consecutive run on a line as a rectangle, hardly optimal, but this works.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.