Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

547 lines
19 KiB

// Copyright (c) 1992-1993 Microsoft Corporation
/*============================================================================
This code module implements styled lines in the NT format.
05/29/81 v-BertD Initial code (used in RP_LineEE_Draw)
02/20/92 RodneyK Converted to Styled line code.
02/21/92 RodneyK Each bit in the Mask is used for two pixels.
03/20/92 RodneyK Converted to NT style format.
06/01/93 RajeevD Collapsed ROP handling from StyleLine* to Draw*.
(Reduces code size by 8K with no loss in speed.)
============================================================================*/
#include <windows.h>
#include "constant.h"
#include "frame.h" // driver header file, resource block format
#include "jtypes.h" /* Jumbo type definitions. */
#include "jres.h" // cartridge resource data type definition
#include "hretype.h" /* Slice Descriptor defs. */
// Table data for the predefined pen styles
ULONG ulWinStyles[] =
{
0x00000002, 0x00ffffff, 0x00000000, /* solid */
0x00000002, 0x00000028, 0x00000010, /* dash */ /* 28 */
0x00000002, 0x00000008, 0x00000008, /* dot */
0x00000004, 0x0000001c, 0x0000000f, 0x00000008, 0x0000000f, /* dash dot */
0x00000006, 0x0000001c, 0x0000000f, 0x00000008, 0x00000008,0x00000008, 0x0000000f,
0x00000002, 0x00000000, 0x00ffffff, /* NULL */
0x00000002, 0x00ffffff, 0x00000000 /* Inside border */
};
const BYTE ulStyleLookUp[7] =
{ 0x00, 0x03, 0x06, 0x09, 0x0e, 0x15, 0x18};
const USHORT usStyleSize[7] =
{0x0000, 0x0038, 0x0010, 0x0042, 0x0052, 0x0000, 0x0000 };
typedef void (*ROPPROC)(LPBYTE, WORD, BYTE);
//==============================================================================
void DrawANDDNR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
if (~(*lpbFrame & wColor) & bPos)
*lpbFrame |= bPos;
else
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawANDDR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawANDNDR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
if (((~*lpbFrame) & wColor) & bPos)
*lpbFrame |= bPos;
else
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawCOPY0 (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawCOPY1 (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
*lpbFrame |= bPos;
}
//==============================================================================
void DrawORDNR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
if ((~(*lpbFrame | wColor)) & bPos)
*lpbFrame |= bPos;
else
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawORDR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
*lpbFrame |= bPos;
}
//==============================================================================
void DrawORNDR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
if (((~*lpbFrame) | wColor) & bPos)
*lpbFrame |= bPos;
else
*lpbFrame &= ~bPos;
}
//==============================================================================
void DrawXOR (LPBYTE lpbFrame, WORD wColor, BYTE bPos)
{
if ((~*lpbFrame) & bPos)
*lpbFrame |= bPos;
else
*lpbFrame &= ~bPos;
}
//==============================================================================
void StyleLine
(
LPRESTATE lpREState, // resource executor context
RP_SLICE_DESC FAR*psdSlice, /* Line Slice descriptor */
ULONG *pulStyle, /* Line style pointer */
WORD wColor,
ROPPROC RopProc
)
/*==============================================================================
PURPOSE This function handle the OR Raster operations for
the styled line code. It draws a line based on the
Slice descriptor, current color, current ROP, and
the current linestyle.
The function runs through the slice and determine
whether a point is to drawn or not. The raster
operation is applied only the points which need to
be drawn.
ASSUMPTIONS & This code assumes that the slice descriptor and the
ASSERTIONS pointer to the style table are valid and correct.
No checks are performed to validate this data.
==============================================================================*/
{
LPBITMAP lpbm;
register UBYTE FAR *pbFrame; /* frame pointer */
SLONG lSlice_x, lSlice_y; /* Slice Run variables */
SLONG lSkip_x, lSkip_y; /* Slice skip variables */
register UBYTE usfPos; /* Bit in frame to modify */
register SHORT i; /* Slice variable */
ULONG *pulStyleTmp; /* Pointer to style data */
register ULONG ulDrawCount; /* Number of pixels to draw on */
ULONG ulStyleCount; /* Count of data in line style */
register BYTE bDraw; /* To draw or Not to draw */
pulStyleTmp = pulStyle + 1; /* Point to style data */
ulDrawCount = *pulStyleTmp++; /* Get the first count */
ulStyleCount = *(pulStyle) - 1; /* Pattern longs remaining */
bDraw = 0xFF; /* Start by drawing */
for ( i = 0 ; i < (SHORT)lpREState->usPenPhase; i++)
{
if(!ulDrawCount) /* Flip draw mask */
{
bDraw = (BYTE)~bDraw;
if (!ulStyleCount--) /* recycle the pattern? */
{
ulStyleCount = *(pulStyle) - 1;
pulStyleTmp = pulStyle + 1;
}
ulDrawCount = *pulStyleTmp++; /* Get next style count */
}
ulDrawCount--;
}
lpbm = lpREState->lpBandBuffer;
pbFrame = (UBYTE FAR*) lpbm->bmBits;
pbFrame += psdSlice->us_y1 * lpbm->bmWidthBytes;
pbFrame += psdSlice->us_x1 >> 3;
usfPos = (UBYTE)(0x80 >> (psdSlice->us_x1 & 0x7)); /* Calculate the bit mask */
lSlice_x = psdSlice->s_dx_draw;
lSlice_y = psdSlice->s_dy_draw * lpbm->bmWidthBytes;
lSkip_x = psdSlice->s_dx_skip;
lSkip_y = psdSlice->s_dy_skip * lpbm->bmWidthBytes;
// Do the first slice...
if (psdSlice->us_first)
{
for ( i = psdSlice->us_first ; i > 0 ; --i )
{
if(!ulDrawCount) /* Flip draw mask */
{
bDraw = (BYTE)~bDraw;
if (!ulStyleCount--) /* recycle the pattern? */
{
ulStyleCount = *(pulStyle) - 1;
pulStyleTmp = pulStyle + 1;
}
ulDrawCount = *pulStyleTmp++; /* Get next style count */
}
ulDrawCount--;
if (bDraw)
(*RopProc)(pbFrame, wColor, usfPos);
if (lSlice_x < 0)
{
usfPos <<= 1;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x01; /* Reset the bit mask */
pbFrame -= 1; /* move to next UBYTE */
}
}
else
{
usfPos >>= lSlice_x;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x80; /* Reset the bit mask */
pbFrame += 1; /* move to next UBYTE */
}
}
pbFrame += lSlice_y; /* advance to next row */
}
if ( lSkip_x < 0 ) /* going to the left? */
{
usfPos <<= 1; /* shift the mask */
if ( usfPos == 0 ) /* Check for over/under flow */
{
usfPos = 0x01; /* Reset Mask */
pbFrame -= 1; /* point to the next UBYTE */
}
}
else /* moving to the right */
{
usfPos >>= lSkip_x;
if ( usfPos == 0 )
{
usfPos = 0x80;
pbFrame += 1;
}
}
pbFrame += lSkip_y;
}
// Do the intermediate slices...
for ( ; psdSlice->us_n_slices > 0 ; --psdSlice->us_n_slices )
{
if ( psdSlice->s_dis < 0 )
{
i = psdSlice->us_small;
psdSlice->s_dis += psdSlice->s_dis_sm;
}
else
{
i = psdSlice->us_small + 1;
psdSlice->s_dis += psdSlice->s_dis_lg;
}
for ( ; i > 0 ; --i )
{
if(!ulDrawCount) /* Is it time to flip the draw state */
{
bDraw = (BYTE)~bDraw; /* Yes, Change it */
if (!ulStyleCount--) /* Recycle pattern? */
{
ulStyleCount = *(pulStyle) - 1;
pulStyleTmp = pulStyle + 1;
}
ulDrawCount = *pulStyleTmp++; /* Advance the pattern */
}
ulDrawCount--;
if (bDraw)
(*RopProc)(pbFrame, wColor, usfPos);
if (lSlice_x < 0)
{
usfPos <<= 1;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x01; /* Reset the bit mask */
pbFrame -= 1; /* move to next UBYTE */
}
}
else
{
usfPos >>= lSlice_x;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x80; /* Reset the bit mask */
pbFrame += 1; /* move to next UBYTE */
}
}
pbFrame += lSlice_y;
}
if ( lSkip_x < 0 ) /* Check for negative movement */
{
usfPos <<= 1;
if ( usfPos == 0 )
{
usfPos = 0x01;
pbFrame -= 1;
}
}
else
{
usfPos >>= lSkip_x; /* Do positive case */
if ( usfPos == 0 )
{
usfPos = 0x80;
pbFrame += 1;
}
}
pbFrame += lSkip_y;
}
// Do the last slice...
for ( i = psdSlice->us_last ; i > 0 ; --i )
{
if(!ulDrawCount) /* Check to see if draw status needs */
{ /* to be changed */
bDraw = (BYTE)~bDraw;
if (!ulStyleCount--)
{ /* update the style pointer */
ulStyleCount = *(pulStyle) - 1;
pulStyleTmp = pulStyle + 1;
}
ulDrawCount = *pulStyleTmp++;
}
ulDrawCount--; /* count down the style count */
if (bDraw)
(*RopProc)(pbFrame, wColor, usfPos);
if (lSlice_x < 0)
{
usfPos <<= 1;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x01; /* Reset the bit mask */
pbFrame -= 1; /* move to next UBYTE */
}
}
else
{
usfPos >>= lSlice_x;
if ( usfPos == 0 ) /* Check mask underflow and adjust */
{
usfPos = 0x80; /* Reset the bit mask */
pbFrame += 1; /* move to next UBYTE */
}
}
pbFrame += lSlice_y;
}
// AdjustPhase(psdSlice);
{
SHORT sDx, sDy;
USHORT usLength;
sDx = psdSlice->us_x2 - psdSlice->us_x1;
sDy = psdSlice->us_y2 - psdSlice->us_y1;
if (sDx < 0) sDx = -sDx;
if (sDy < 0) sDy = -sDy;
usLength = usStyleSize[lpREState->ubPenStyle];
if (usLength != 0)
{
if (sDx < sDy)
lpREState->usPenPhase += (USHORT)sDy + 1;
else
lpREState->usPenPhase += (USHORT)sDx + 1;
lpREState->usPenPhase %= usLength;
}
}
}
//==============================================================================
void GetTotalPixels
(
RP_SLICE_DESC FAR *psdSlice /* Line Slice descriptor */
)
//
// PURPOSE Caculate how many pixel are going to be drawn.
// Put the result in us_y2 = us_y1 + Total Pixels
// This function is called only in JG_RP_LineSlice
//
// ASSUMPTIONS & This code assumes that the slice descriptor and the
// ASSERTIONS pointer to the style table are valid and correct.
// No checks are performed to validate this data.
// If an unsupported ROP is sent ROP(0) BLACKNESS is
// used.
//
// INTERNAL STRUCTURES No complex internal data structure are used
//
//--------------------------------------------------------------------------*/
{
USHORT usTotalPixels;
SHORT sDis;
SHORT i;
usTotalPixels = psdSlice->us_first + psdSlice->us_last;
sDis = psdSlice->s_dis;
for (i = 0; i < (SHORT)psdSlice->us_n_slices; i++) {
if ( sDis < 0 )
{
usTotalPixels += psdSlice->us_small;
sDis += psdSlice->s_dis_sm;
}
else
{
usTotalPixels += psdSlice->us_small + 1;
sDis += psdSlice->s_dis_lg;
}
}
psdSlice->us_y2 = psdSlice->us_y1 + usTotalPixels - 1;
return;
}
//==============================================================================
BYTE StyleLineDraw
(
LPRESTATE lpREState, // resource executor context
RP_SLICE_DESC FAR *psdSlice, /* Line Slice descriptor */
UBYTE ubLineStyle, /* Line style pointer */
SHORT sRop,
SHORT usColor
)
/*
//
// PURPOSE This function calls the correct function to draw
// a single pixel styled line using the correct
// ROP, Linestyle, and color (pen).
//
// ASSUMPTIONS & This code assumes that the slice descriptor and the
// ASSERTIONS pointer to the style table are valid and correct.
// No checks are performed to validate this data.
// If an unsupported ROP is sent ROP(0) BLACKNESS is
// used.
//
// INTERNAL STRUCTURES No complex internal data structure are used
//
// UNRESOLVED ISSUES Banding problems???
//
// RETURNS 0 - use fast line, 1 - don't draw, 2 - style drawn
//
//--------------------------------------------------------------------------*/
{
BYTE bRetVal; /* Return value for optimizing certain cases */
ULONG *pulStyle; /* Line style pointer */
BYTE bSolid;
if (!ubLineStyle && ((psdSlice->s_dx_draw < 0) || (psdSlice->s_dx_skip <0)))
{
// JG_WARNING("Neg X with Solid Line");
ubLineStyle = 6; /* for style line code to do it */
}
if (ubLineStyle == 5)
bRetVal = 1;
else
{
/* Note style 6 will not be considered solid to simplify things */
bSolid = (BYTE)(ubLineStyle == 0);
pulStyle = &ulWinStyles[ulStyleLookUp[ubLineStyle]];
bRetVal = 2;
if (usStyleSize[ubLineStyle])
lpREState->usPenPhase %= usStyleSize[ubLineStyle];
switch (sRop)
{
case 0x00 : /* ROP BLACK */
if(bSolid) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY1);
break;
case 0x05 : /* DPon */
StyleLine (lpREState, psdSlice, pulStyle, usColor, DrawORDNR);
break;
case 0x0a : /* DPna */
if(!usColor) bRetVal = 1;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawANDDR);
break;
case 0x0f : /* Pn */
if(bSolid && !usColor)
bRetVal = 0;
else
if (usColor)
StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY0);
else
StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY1);
break;
case 0x50 : /* PDna */
StyleLine (lpREState, psdSlice, pulStyle, usColor, DrawANDNDR);
break;
case 0x55 : /* Dn */
usColor = 0x0000;
StyleLine (lpREState, psdSlice, pulStyle, usColor, DrawORNDR);
break;
case 0x5a : /* DPx */
if(!usColor) bRetVal = 1;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawXOR);
break;
case 0x5f : /* DPan */
if(bSolid && !usColor) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, usColor, DrawANDDNR);
break;
case 0xa0 : /* DPa */
if(usColor) bRetVal = 1;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawANDDR);
break;
case 0xa5 : /* PDxn */
if(usColor) bRetVal = 1;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawXOR);
break;
case 0xaa : /* D */
bRetVal = 1;
break;
case 0xaf : /* DPno */
if (usColor) bRetVal = 1;
else if(bSolid) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawORDR);
break;
case 0xf0 : /* P */
if(bSolid && usColor) bRetVal = 0;
else if (usColor)
StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY1);
else
StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY0);
break;
case 0xf5 : /* PDno */
if(bSolid && usColor) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, usColor, DrawORNDR);
break;
case 0xfa : /* PDo */
if (!usColor) bRetVal = 1;
else if(bSolid) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawORDR);
break;
case 0xFF : /* WHITENESS */
StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY0);
break;
default: /* BLACKNESS */
if(bSolid) bRetVal = 0;
else StyleLine (lpREState, psdSlice, pulStyle, 0, DrawCOPY1);
}
}
return (bRetVal);
}