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
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);
|
|
}
|
|
|