THE MAPPING MODE

One device context attribute that affects virtually all the drawing you do on the client area is the ”mapping mode.“ Four other device context attributes—the window origin, the viewport origin, the window extents, and the viewport extents—are closely related to the mapping mode attribute.

Most of the GDI drawing functions require coordinate values or sizes. For instance, this is the TextOut function:

TextOut (hdc, x, y, szBuffer, nLength) ;

The x and y parameters indicate the starting position of the text. The x parameter is the position on the horizontal axis, and the y parameter is the position on the vertical axis. Often the notation (x, y) is used to indicate this point.

In TextOut, as in virtually all GDI functions, these coordinate values are in terms of ”logical units.“ Windows must translate the logical units into ”device units,“ or pixels. This translation is governed by the mapping mode, the window and viewport origins, and the window and viewport extents. The mapping mode also implies an origin and orientation of the x-axis and the y-axis; that is, it determines whether values of x increase as you move toward the left or right side of the display and whether values of y increase as you move up or down the display.

Windows defines eight mapping modes. These are listed in the table on the following page using the WINDOW.H identifiers.

    Increasing Values  
Mapping Mode Logical Unit x-axis y-axis

MM_TEXT Pixel Right Down
MM_LOMETRIC 0.1 mm Right Up
MM_HIMETRIC 0.01 mm Right Up
MM_LOENGLISH 0.01 in. Right Up
MM_HIENGLISH 0.001 in. Right Up
MM_TWIPS* 1/1440 in. Right Up
MM_ISOTROPIC Arbitrary (x = y) Selectable Selectable
MM_ANISOTROPIC Arbitrary (x != y) Selectable Selectable

* Twip is a fabricated word meaning ”twentieth of a point.“ A point, which is a unit of measurement for type, is approximately 1/72 inch but often assumed in graphics systems such as GDI to be exactly 1/72 inch. A twip is 1/20 point and hence 1/1440 inch.

You can set the mapping mode by:

SetMapMode (hdc, nMapMode) ;

where nMapMode is one of the eight mapping mode identifiers. You can obtain the current mapping mode by calling:

nMapMode = GetMapMode (hdc) ;

The default mapping mode is MM_TEXT. In this mapping mode, logical units are the same as physical units, which allows us (or, depending on your perspective, forces us) to work directly in terms of pixels. In a TextOut call that looks like this:

TextOut (hdc, 8, 16, szBuffer, nLength) ;

the text begins 8 pixels from the left of the client area and 16 pixels from the top.

If the mapping mode is set to MM_LOENGLISH, then logical units are in terms of hundredths of an inch:

SetMapMode (hdc, MM_LOENGLISH) ;

Now the TextOut function call might look like this:

TextOut (hdc, 50, -100, szBuffer, nLength) ;

The text begins 0.5 inch from the left and 1 inch from the top of the client area. (The reason for the negative sign in front of the y-coordinate will become clear later when I discuss the mapping modes in more detail.) Other mapping modes allow programs to specify coordinates in terms of millimeters, a printer's point size, or an arbitrarily scaled axis.

If you feel comfortable working in terms of pixels, you don't need to use any mapping modes except the default MM_TEXT mode. If you need to display an image in actual inch or millimeter dimensions, you can obtain the information you need from GetDeviceCaps and do your own scaling. The other mapping modes are simply a convenient way to avoid doing your own scaling.

Regardless of the mapping mode, all coordinates you specify in Windows functions must be signed short integers in the range 32,767 through -32,768. Some Windows functions that use coordinates for the starting point and ending point of a rectangle also require that the width and height of the rectangle be 32,767 or less.