QuickDraw is the 2D graphics library which is a core part of the classic Macintosh operating system. It was initially written by Andy Hertzfeld and Bill Atkinson. QuickDraw still exists as part of the libraries of Mac OS X, but has been largely superseded by the more modern Quartz graphics system.
Principles of QuickDraw
QuickDraw, being grounded in the LisaGraf development work of the early 1980s, uses a data structures + algorithms programming paradigm (as opposed to the now more common object-oriented paradigm). This fitted well with the Pascal programming language based interfaces and development environments of the early Apple systems.
QuickDraw defines a key data structure, the graphics port, or GrafPort. This is a logical drawing area where graphics can be drawn. The most obvious on-screen "object" corresponding to a GrafPort is a window, though so is the entire desktop view and off-screen ports can also exist.
The GrafPort defines a coordinate system. In QuickDraw, this has a 16-bit resolution, giving 65,535 unique vertical and horizontal locations. These are numbered from -32,767 on the extreme left (or top), to +32,768 on the extreme right (or bottom). A window is usually set up so that its top, left corner is located at 0,0 in the associated GrafPort.
QuickDraw coordinates refer to the infinitely thin lines between pixel locations. An actual pixel is drawn in the space to the immediate right and below the coordinate. This eliminates the so-called "end-point paranoia" and associated off-by-one errors.
On the Macintosh, pixels are square and a GrafPort has a default resolution of 72 pixels to the inch, chosen to match conventions established by the printing industry of having 72 points to the inch.
QuickDraw also contains a number of scaling and mapping functions.
QuickDraw maintains a number of global variables per process, chief among these being the current port. This simplifies the API, since all operations pertain to "the current port", but as the OS has developed, this has made QuickDraw much harder to integrate with modern design approaches such as multi-threading, pre-emptive multitasking and so on.
Everything seen on a classic Mac OS screen is drawn by QuickDraw, but the library itself is quite low level. The primitive objects it can draw are:
- Round-cornered rectangles
- Ovals (including circles)
- Arcs (and wedges)
- Polygons (arbitrary closed shapes built from a list of points joined by lines)
- Regions (arbitrary sets of pixels)
Each of these objects (except text) may be drawn using a "pen", which can have any rectangular dimensions, pattern or colour. Note that, because the pen is rectangular and axis-aligned, diagonal lines will end up thicker than horizontal or vertical ones. Shapes may be drawn filled or framed, using any pattern or colour. A filled Arc forms a wedge. Text may be drawn in any installed font, in a variety of stylistic variations, and at any size and colour. Text is scaled in a variety of ways depending on how it is stored - TrueType fonts will scale smoothly to any size, whereas bitmap fonts do not usually scale well.
An important feature of QuickDraw was support for transfer modes, which governed how a destination pixel value was related to its previous value and the colour of the object being drawn.
The set of attributes of the pen and text drawing are associated with the GrafPort.
Regions are a key data structure in QuickDraw. They define an arbitrary set of pixels, rather like a bitmap, but in a compressed form which can be very rapidly manipulated in complex ways. Regions can be combined (union), subtracted (difference), and XORed to form other Regions. They can be used within a GrafPort for clipping, or drawn filled or framed like any other shape. A series of framed shapes and connected lines may be combined into a Region. A Region need not consist of a contiguous set of pixels - disconnected regions are possible and common. Regions underpin the rest of QuickDraw, permitting clipping to arbitrary shapes, essential for the implementation of multiple overlapping windows. Invented by Bill Atkinson, Regions were patented as a separate invention by Apple.
Higher level operations
Any series of graphics calls to QuickDraw can be recorded in a structure called a Picture. This can then be saved in memory and "played back" at any time, reproducing the graphics sequence. At playback time the picture may be placed at new coordinates or scaled. A picture can be saved to disk in which form it defines the Apple PICT format.
An entire BitMap (or PixMap, when referring to colour images) may be copied from one GrafPort to another, with scaling and clipping. Known as blitting, or CopyBits, after the name of the function, this operation is the basis for most animation and sprite-like effects on the Mac.
QuickDraw provides a similar blitting function which is designed to implement scrolling within a grafport - the image in the port can be shifted to a new location without scaling (but with clipping if desired).
Each graphics primitive operation is vectored through the StdProcs, a series of function pointers stored in the GrafPort. This permits individual operations to be overridden or replaced by custom functions (in this respect QuickDraw does offer some small degree of object-oriented design). This ability permits printer drivers to intercept graphics commands and translate them to suitable printer operations. In this way, QuickDraw can be rendered using PostScript, a fact that enabled the Macintosh to practically invent desktop publishing.
Similar to a subclass, the Window data structure began with the associated GrafPort, thus basically making windows exchangeable with any GrafPort. While convenient, this could be a source of programming errors.
QuickDraw started life as LisaGraf, as part of the Apple Lisa development. For the Macintosh it was initially simplified, but then later extended. Originally, QuickDraw GrafPorts only supported a bit depth of 1, that is one bit per pixel, or black and white. This suited the built-in screen of the early Macintosh, with its fixed size of 512 x 342 pixels. Limited colour was supported using a crude planar model, allowing QuickDraw to drive some types of dot-matrix printer that used multi-coloured ribbons, but very few applications supported this feature.
In 1986, the Macintosh II was developed and launched, which was designed as a more conventional three-box design - CPU, monitor and keyboard all separate. Because the monitor was separate, and larger than the original Mac, the video architecture had to necessarily change. In addition, the Mac II had colour. Apple also decided at this time to support a seamless desktop spanning multiple monitors, an industry first. Thus Colour QuickDraw, a significant extension of the original QuickDraw, was created. The original architecture lacked much provision for expandability, but using a series of inspired hacks, the Apple developers managed to make the addition of colour and the new video architecture virtually seamless to both developers and end users.
Colour QuickDraw introduced new data structures - GDevices to represent each attached video card/monitor, and a new colour GrafPort (CGrafPort) structure to handle colour, as well as PixMaps instead of BitMaps for multiple bits-per-pixel images. In addition, a Palette Manager was added which managed the arbitration of colours on indexed video devices. Most graphics primitives operations remained either unchanged (but would operate in colour), or else new colour versions of the black and white APIs were added.
Initially, Colour QuickDraw was only capable of operating with 8-bit (256 colour indices, from a total palette of 16,777,216 colours) video cards, which were all that was available at the time. Soon after however, 24-bit video cards appeared (so-called true colour), and QuickDraw was updated again to support up to 32 bits per pixel of colour data ("32-Bit QuickDraw"). The architecture always allowed for this however, so no new APIs were necessary.
The architecture of QuickDraw had always allowed the creation of GrafPorts and their associated BitMaps or PixMaps "offscreen", where graphics could be composed in memory without it being visible immediately on the screen. Pixels could be transferred between these offscreen ports and the screen using the QuickDraw blitting function CopyBits. Such offscreen compositing is the workhorse for games and graphics-intensive applications. However, until the advent of 32-Bit QuickDraw, such offscreen worlds had to be created and set up by hand by the programmer within his application, and involving as it did three or more separate and fairly complex data structures (CGrafPort, PixMap and GDevice, and for indexed devices, the colour look-up table and its inverse), could be error prone. With 32-Bit QuickDraw, OS support for handling this was added, with the "Offscreen Graphics World" or GWorld. The video buffer (PixMap) of a GWorld could be stored in main memory, or when available in unused parts of video ram where copying to the screen could be optimized for speed by avoiding the need to transfer a large amount of pixel data across the main memory bus.
With the advent of QuickTime, QuickDraw gained the ability to deal with compressed raster data, such as JPEG. The QuickTime Image Compression Manager integrated closely with QuickDraw: in particular, image decompression calls were full-fledged QuickDraw drawing calls, and if a picture was being recorded, the compressed data would be saved as part of the picture, for display when the picture was later drawn. The Image Compression Manager also added integration with ColorSync colour matching.
After this, apart from back-end changes to optimize for new processor architectures (PowerPC), QuickDraw remained largely unchanged throughout the rest of the life of the classic Mac OS. QuickDraw GX and QuickDraw 3D shared the QuickDraw name and were able to interoperate with QuickDraw PixMap and picture data structures, but were otherwise completely separate in functionality.