## Presentation Device Driver Reference for OS/2

[prev][next][parent][TOC]

### Style Ratio

The most obvious way to generate styled lines is to draw a circle at the origin, and then draw a dashed line from the origin to all points on the circle. The number of dashes in each line will be the same and the lengths of all the dashes drawn will be equal. This is executed on microcode on some devices. However, it is too costly in terms of processor time to implement it in software. Therefore, an alternative method called the " maximum metric" is used in the graphics engine. This method can be visualized by drawing a square centered at the origin, and then drawing a dashed line to any point on the square. The number of dashes in each line will be the same but the lengths of the dashes will vary.

The maximum metric states that:

If the line is Y-major as viewed on the device:

    {y-major = ABS(y1-y0) > ABS(x1-x0)
    where (x0, y0) and (x1, y1) are the endpoints of the line in
    device-coordinate space},
    add pDC -> usStyleRatioY to error-term value upon each
    increment of Y as the line is drawn

If the line is X-major as viewed on the device:

    {x-major = ABS(x1-x0) > ABS(y1-y0) in device-coordinate space},
    add pDC -> usStyleRatioX to error-term value upon each increment
    of X as line is drawn

The line style as viewed on the device is determined, as follows:

    if (ABS(pDC -> usStyleRatioX * sDeltaX) > ABS(pDC -> usStyleRatioY * sDeltaY))
        LineStyleAsItLooksOnTheDevice = X-MAJOR;
    else
        LineStyleAsItLooksOnTheDevice = Y-MAJOR;

This might be coded similar to the following:

    if (ABS(pDC -> usStyleRatioX * sDeltaX) > ABS(pDC -> usStyleRatioY * sDeltaY)) {
        usChangeInStateForOnePixel = pDC -> usStyleRatioX; fAddThisWhen = X_INCREMENTS;
    } else {
            usChangeInStateForOnePixel = pDC -> usStyleRatioY; fAddThisWhen = Y_INCREMENTS;
    }

It follows that for a line (AB), the total change in style state can be expressed as:

    usChangeInStateForWholeLine = MAX(ABS(pDC -> usStyleRatioX * sDeltaX),
                                  ABS(pDC -> usStyleRatioY * sDeltaY))
    where sDeltaX = Bx-Ax and sDeltaY = By-Ay

For example, an EGA device that has a 640 x 350 (X-to-Y) resolution is displayed on a display that has an X-to-Y ratio of 1-to-.75. To calculate the aspect ratio:

    X/Y Ratio = 350/(640*.75) = .72917   Therefore: X = Y*.72917 or Y = X/.72917

This indicates that a pel is taller than it is wide. The following figure visually describes the ratio. [Artwork not shown]

Pel Aspect Ratio

Assume that four pels in the X-direction is the desirable size of a styled- line dot. Because this display is 9.5 inches across and there are 640 pels across, the length of the four pels is:

    (9.5inches/640pels) * 4pels = .059375inches
    This results in a pDC -> usStyleRatioX = 64&:
                                        64 = 256/4

Note that 256 = 0x100, which corresponds to an overflow of the error-term byte into the mask position. To get the equivalent pDC usStyleRatioY value, use the desired distance and multiply it by Y pels per inch, as follows:

    (.059375inches * 350 pels)/7.125inches = 2.917pels
    Therefore:pDC  usStyleRatioY = 256/2.917 = 87.76 (rounded to 88)

An easier method is to calculate pDC usStyleRatioY from pDC usStyleRatioX, using the following aspect ratio:

    pDC  usStyleRatioY = pDC  usStyleRatioX / .72917 = 87.76 (rounded to 88)

Note that the values pDC usStyleRatioX and pDC usStyleRatioY are the same as those returned by GreGetStyleRatio.

An example of what is meant by "as viewed on the device" follows:

         If a line is drawn from (0, 0) to (100, 100) pels on the device, it is
         drawn as a diagonal line but does not look diagonal to an observer.
         Instead, it looks like a line drawn to (100, 73).

         This change of perspective is because of the aspect ratio.  Each unit
         (pel) in the X-direction covers only .72917 as much distance as a pel
         in the Y-direction.  The images on the device do not look skewed
         because this ratio is factored in when the application draws a diagonal
         line (for example, by drawing from (0, 0) to (73, 100)).

         The styled lines are affected when a line that is drawn in pels as
         X-major appears on the device as Y-major.  In this case, a line drawn
         from (0, 0) to (85, 64) is X-major as drawn in pels
         (because ABS(x1-x0) > ABS(y1-y0)), but appears on the device to be
         Y-major.  Notice that this line must be styled Y-major to look correct on
         the device, as follows:

    usChangeInStateForOnePixel = ABS(pDC -> usStyleRatioX * sDeltaX) > ABS(pDC -> usStyleRatioY
                                 * sDeltaY)?
                                 pDC -> usStyleRatioX :pDC -> usStyleRatioY;
    where:
         ABS(pDC -> usStyleRatioX * sDeltaX) = 64 * 85 = 5440
         ABS(pDC -> usStyleRatioY * sDeltaY) = 88 * 64 = 5632

         Because 5440 < 5632, the line is styled Y-major by using
         pDC  usStyleRatioY.  The X-major diagonal line drawing routine
         usually adds pDC  usStyleRatioX to the error-term byte for every
         increment of X.  This is correct if the aspect ratio is 1:1.

         However, because the aspect ratio is not 1:1, pDC
         usStyleRatioY must be used in this case for every increment of Y,
         although the line is drawn as an X-major line with the X-major routine.
         This means that regardless of which way the line is drawn, it must be
         styled according to how it looks on the device, which is determined by
         the maximum metric method described previously.

LINETYPE_ALTERNATE is a special case of styled line. When drawing a line of this type (pLbnd usType = LINETYPE_ALTERNATE), the X and Y style ratios are temporarily set to 256 to set every other pel on the line ON. Notice that changing the values returned by GreGetStyleRatio is not necessary because the graphics engine does not call this function if the line type is LINETYPE_ALTERNATE.