The style of a line determines whether it is drawn solid, alternating, invisible, or as any one of a combination of dots and dashes. This style is determined by the usType parameter in the LINEBUND structure (see Line Attributes), which can have any one of the ten values shown in the following table. For each usType value, there is an associated 8-bit style mask whose bits form a template that corresponds to whether pels are set ON or OFF when the line is drawn on the device.
The 8-bit style masks used by OS/2 are as follows:
8-Bit Style Masks
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³usType ³Value³StyleMask ³Bits ³Comment ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_DEFAULT ³ 0 ³ 0xFF ³11111111 ³Solid line. ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_DOT ³ 1 ³ 0xAA ³10101010 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_SHORTDASH ³ 2 ³ 0xCC ³11001100 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_DASHDOT ³ 3 ³ 0xE4 ³11100100 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_DOUBLEDOT ³ 4 ³ 0xA0 ³10100000 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_LONGDASH ³ 5 ³ 0xE7 ³11100111 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_DASHDOUBLEDOT ³ 6 ³ 0xEA ³11101010 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_SOLID ³ 7 ³ 0xFF ³11111111 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_INVISIBLE ³ 8 ³ 0x00 ³00000000 ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´ ³LINETYPE_ALTERNATE ³ 9 ³ 0xAA ³10101010 ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ
The style masks can be put into an array of bytes as illustrated in the following code example:
const BYTE bStyleMask[ ] = { 0xFF,0xAA,0xCC,0xE4,0xA0,0xE7,0xEA,0xFF,0x00,0xAA };
Consider the following code example and comments:
DrawHorizontalLine( SHORT sY, /* Y-value */ SHORT sX0, /* Starting x-value */ SHORT sX1, /* Ending x-value */ USHORT usStyleRatio, /* Style ratio */ USHORT usState /* Current mask state */ PLINEBUNDLE pLbnd) /* pLbnd contains usType */ /* parameter */ { USHORT usStateOld; /* Used for test */ USHORT usOrigMask; /* Original mask */ USHORT usMask; /* Current mask */
The usState WORD structure is set up by the graphics engine. This structure is shown in the following table:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³5 bits (not ³3 bits (mask ³8 bits (error-term byte, value³ ³used) ³position, value³0-0xFF) ³ ³ ³0-7) ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Note: This format is different from the way the graphics engine stores this value. The graphics engine keeps the high and low bytes swapped, therefore, the calling routine must swap them before calling this function.
The mask position has three bits and eight possible values, 0-7, that correspond to the number of bits in the style mask. Notice that when the error-term byte overflows (exceeds 0xFF), it will increment the mask position value. To get the unshifted mask value:
usMask = usOrigMask = bStyleMasks[pLbnd -> usType];
The mask must be shifted to the current position as shown above:
usMask <<= ((usState & 0x700) >> 8);
For each pel:
for(sX = sX0; sX <= sX1; sX++){
Because many devices have small pel sizes, it is often necessary to set more than one pel ON per corresponding bit in the style mask. This setting is accomplished by using a style ratio, which determines how many pels on the line correspond to a bit in the style mask. As an example, for each pel on the line, the most significant bit of the style mask is consulted. If this bit is 1, the pel is drawn. If this bit is 0, the pel is not drawn, as shown in the following example:
if(usMask & 0x80) DrawPel(sX,sY); usStateOld = usState;
The style ratio is then added to the error-term byte of the usState parameter. When the error-term byte overflows, the mask position value (high byte of usState) is incremented to the next position. If the mask position exceeds 7, it is reset to 1.0:
usState = (usState + usStyleRatio) & 0x7ff;
The mask itself must now be shifted appropriately:
if(HIBYTE(usState) | = HIBYTE(usStateOld)){ /* Has it changed? */ if(HIBYTE(usState) == 0) /* Back to zero? */ usMask - usOrigMask; /* Yes, reset it */ else usMask <<= 1; /* Else shift it */ } . . . return(usState); /* Return the state /* for the next line */
Styled line information is usually maintained by the presentation driver in the Device Context (DC) instance data structure. See Device Context. Remember that the DC is a structure that the presentation driver creates. The definition of the DC data structure is specific and can be unique for each unique presentation driver. This information can include:
typedef struct _DC { . . . USHORT usStyleRatioX; /* X-style ratio */ USHORT usStyleRatioY; /* Y-style ratio */ ULONG lLineStyle; /* Current state information */ /* (GRE Backward Format) */ LINEBUNDLE lbnd; /* Linebundle information contains */ /* usType parameter */ BYTE bMyCurrentMask; /* Current style mask */ . . . DC; typedef DC *PDC;
The lLineStyle value has much of the same information as the usState parameter in the example function. Its value is concurrently maintained by the graphics engine but has a different format from the example above. The graphics engine can set or query this value by calling the functions GreSetLineOrigin or GreGetLineOrigin, respectively. It is therefore reasonable to keep a copy in the graphics engine format.
The graphics engine's format for this value consists of three values:
They are stored in the following manner:
High WORD
If two bytes of this low WORD are compared to the WORD in the previous example, they are swapped.