QuickDraw GX - Description - Graphics

Graphics

QuickDraw GX is based on an object oriented model in which graphics objects are aware of and responsible for their own state. Unlike QuickDraw, there is no universal "state", every drawing command can re-construct the state from data stored within it, or various "parent" objects. For instance, a programmer could build a redBox object that first sets the color to red, and then draws a square. From that point on the program no longer has to explicitly set the color before drawing, the GX system itself will always correctly set the drawing color when asked to draw a redBox, and reset it when finished. Since this state was private, and sent to GX if and when needed, GX theoretically allowed the Mac OS to support protected memory, as state was no longer shared directly between the programs and graphics system.

This contrasts strongly with the original QuickDraw, where the programmer was responsible for all state changes. For instance, if one were to draw a redBox and then a series of lines, the lines would also appear in red unless the programmer explicitly changed the color first. The advantage to this approach is that it minimizes the number of commands needed to set state; the programmer can organize drawing to draw groups of similarly styled objects at the same time and thereby save time. The disadvantage of this approach is that it is easy to "forget" to change state and end up causing problems, so easy that programmers often saved and restored the complete state before every drawing command, thereby potentially lowering performance.

The drawing state under GX was hierarchical. A default drawing mode was created with every window, as it was under QD, and drawing objects with no other state changes would use these defaults. The programmer could then change state in the objects themselves, as in our redBox example, or alternately change the state of all drawing by setting the state in the window object. GX objects could be easily collected into groups, themselves objects, allowing the state to be set for an entire complex object.

One part of the overall drawing state was the gxMapping. This was a 3-by-3 matrix which could express arbitrary linear transformations in two dimensions, including perspective distortions. All GX objects had an associated mapping as part of its drawing state, which allowed for things like rotations and translations. Although all of this state was held in the gxMapping for that object, GX also provided "wrapper" commands like "rotate" to make the API simpler to use.

Unlike QuickDraw, QuickDraw GX allowed for fractional coordinates. However, these were fixed-point values, rather than floating-point. At the time GX was being developed (late 1980s to early 1990s), there was still a significant performance penalty in using floating-point arithmetic.

The GX graphics architecture was built around a number of types of objects which were premade, though a full set of API calls was available for examining and manipulating them:

  • a gxShape defined the basic geometry of a shape (for example, coordinates of control points for a curve, or the text content of a text object).
  • a gxStyle defined elaborations of the basic shape geometry, such as line thickness, cap and join styles, fill pattern and text font.
  • a gxInk specified how pixel values were to be computed when rendering the shape: besides specifying a basic color for the shape, this also included an elaborate transfer mode structure that could define a wide variety of functions of the initial and final destination pixel value.
  • a gxFont represented a font, either one installed for systemwide use, or one installed on-the-fly by the current application for its own use. API calls allowed the interrogation of the properties of a font, including the determination of what encodings (Unicode, language-specific etc.) it might support.
  • a gxProfile was a representation of a ColorSync color profile, used as part of the specification of a color for drawing. GX integrated full support for color matching at all stages of the drawing process, as well as support for non-RGB color specifications (such as HSV, YUV and CIE XYZ).
  • a gxTransform determined the relationship between the shape and the display device. Besides the Clipping path and the gxMapping that transformed the shape before displaying on the output device, this object also specified hit-testing information that controlled responses to user clicks within the area of the shape.
  • a gxViewDevice represented a block of pixel memory into which drawing would be rendered. This could be an actual on-screen display, or an offscreen block of memory. GX supported all the QuickDraw pixel layouts; this allowed both a GX view device and a QuickDraw GrafPort to point to the same pixels, thereby allowing applications to mix both sets of drawing calls.
  • a gxViewPort was a logical destination for drawing. A gxTransform could specify a list of more than one of these; the shape would be drawn into all of them in a single GXDrawShape call.
  • a gxViewGroup represented the connection between view devices and view ports. Each view port had a gxMapping specifying its relationship to the global coordinate system of the view group; and each view device had a gxMapping that specified its location and the size of its pixels with regard to view group coordinates. There was a single predefined view group which contained all on-screen view devices (and whose view ports effectively corresponded to on-screen windows); applications were free to create their own view groups for off-screen view devices and view ports.
  • a gxTag allowed the attachment of arbitrary application-defined information to most of the above object types. Each tag had an OSType type code, but there could be multiple tags of the same type attached to the same object.

Read more about this topic:  QuickDraw GX, Description