THE GDI PHILOSOPHY

Graphics in Windows are handled primarily by functions exported from the GDI.EXE module (although some drawing functions actually have entry points in the USER.EXE file). The GDI.EXE module calls routines in the various driver files—a .DRV for the video display screen and possibly one or more other .DRV driver files that control printers or plotters. The video driver accesses the hardware of the video display. Different video display adapters and printers require different driver files.

The GDI system is constructed so that Windows can determine from the driver what the driver can handle itself and what it needs assistance with. For instance, if the video hardware includes a graphics coprocessor that can draw ellipses, then GDI can take advantage of that; otherwise, the GDI module must itself calculate the points of the ellipse and pass the points to the driver.

Because a large number of different display devices can be attached to the IBM PC and compatibles, one of the primary goals of GDI is to support device-independent graphics on output devices such as video displays, printers, and plotters. Windows programs should be able to run without problems on any graphics output device that Windows supports. GDI accomplishes this goal by providing facilities to insulate your programs from the particular characteristics of different output devices. In this way it is like other device-independent graphics programming languages. But where Windows GDI is different is in its strong support of pixel-level manipulation.

The world of graphics output devices is divided into two broad groups: raster devices and vector devices. Most PC output devices are raster devices, which means that they represent images as a pattern of dots. This category includes video display adapters, dot-matrix printers, and laser printers. Vector devices, which draw images using lines, are generally limited to plotters.

Although most video display adapters and printers are raster devices, most graphics interface languages are based solely on vectors. This means that a program using one of these graphics languages is a level of abstraction away from the hardware. The output device is using pixels for a graphics representation, but the program is not talking to the interface in terms of pixels. While you can certainly use Windows GDI as a high-level vector drawing system, you can also use it for relatively low-level pixel manipulation.

In this respect, Windows GDI is to other graphics interface languages what C is to other programming languages. C is well known for its high degree of portability among different operating systems and environments. Yet C is also well known for allowing a programmer to perform low-level system functions that are often impossible in other high-level languages. Just as C is sometimes thought of as a ”high-level assembly language,“ you can think of GDI as a high-level interface to the hardware of the graphics device.

As you've seen, by default Windows uses a coordinate system based on pixels. Most other graphics languages use a ”virtual“ coordinate system with horizontal and vertical axes that range (for instance) from 0 to 32,767. Although some graphics languages don't let you use pixel coordinates, Windows GDI lets you use either system (as well as additional coordinate systems based on physical measurements). You can use a virtual coordinate system and keep your program distanced from the hardware, or you can use the device coordinate system and snuggle right up to the hardware.

Some programmers think that after you start working in terms of pixels, you've abandoned device independence. We've already seen that this is not necessarily true. The trick is to use the pixels in a device-independent fashion. This requires that the graphics interface language provide facilities for a program to determine the hardware characteristics of the device and make appropriate adjustments. For instance, we've frequently used the pixel size of a standard system font character to space text on the screen. This approach allows our programs to adjust to different display adapters with different resolutions, text sizes, and aspect ratios. You'll see other methods in this chapter for determining display sizes.

Windows can run on either a monochrome display or a color display. If you choose, you can write a program without worrying very much about color. If you use color in your program and the program later runs on a monochrome display adapter, Windows will use a shade of gray to represent the color. However, you can also determine from your program how many colors are available on the particular display device and take best advantage of the hardware.

Of course, just as you can write C programs that have subtle portability problems when they run on other computers, you can also inadvertently let device dependencies creep into your Windows programs. That's part of the price of not being fully insulated from the hardware. We'll examine many of the device-dependent traps in the next few chapters.

You should also be aware of the limitations of Windows GDI. GDI is not (at this time) capable of doing everything you may want a graphics interface to do. Although you can move graphics objects around the display, GDI is generally a static display system with no real animation support. GDI provides no direct support for three-dimensional representations or for rotations of objects. For instance, when you draw an ellipse, the ellipse axes must be parallel to the horizontal and vertical coordinates. Although some graphics languages use floating-point numbers for virtual coordinates, Windows—for performance reasons—always uses 16-bit signed integers.