3452 lines
75 KiB
C++
3452 lines
75 KiB
C++
/******************************Module*Header*******************************\
|
||
* Module Name:
|
||
*
|
||
* solline.cxx
|
||
*
|
||
* Abstract
|
||
*
|
||
* This module draws solid color, single pixel wide, non-styled, trivial or
|
||
* rectangularly clipped lines to a DIB.
|
||
*
|
||
* Author:
|
||
*
|
||
* Mark Enstrom (marke) 12-1-93
|
||
*
|
||
* Copyright (c) 1993-1999 Microsoft Corporation
|
||
\**************************************************************************/
|
||
|
||
#include "precomp.hxx"
|
||
#include "solline.hxx"
|
||
|
||
#define DBG_LINE 0
|
||
|
||
|
||
#if DBG_LINE
|
||
ULONG DbgLine = 0;
|
||
#endif
|
||
|
||
//
|
||
// horizontal line accelerators
|
||
//
|
||
|
||
PFN_HORZ gapfnHorizontal[6] =
|
||
{
|
||
vHorizontalLine1,vHorizontalLine4,vHorizontalLine8,
|
||
vHorizontalLine16,vHorizontalLine24,vHorizontalLine32
|
||
};
|
||
|
||
|
||
//
|
||
// line DDA routines for each DIB format
|
||
//
|
||
|
||
PFN_OCTANT gapfnOctant[6][8] =
|
||
{
|
||
{
|
||
vLine1Octant07,vLine1Octant16,vLine1Octant07,vLine1Octant16,
|
||
vLine1Octant34,vLine1Octant25,vLine1Octant34,vLine1Octant25
|
||
},
|
||
{
|
||
vLine4Octant07,vLine4Octant16,vLine4Octant07,vLine4Octant16,
|
||
vLine4Octant34,vLine4Octant25,vLine4Octant34,vLine4Octant25
|
||
},
|
||
{
|
||
vLine8Octant07,vLine8Octant16,vLine8Octant07,vLine8Octant16,
|
||
vLine8Octant34,vLine8Octant25,vLine8Octant34,vLine8Octant25
|
||
},
|
||
{
|
||
vLine16Octant07,vLine16Octant16,vLine16Octant07,vLine16Octant16,
|
||
vLine16Octant34,vLine16Octant25,vLine16Octant34,vLine16Octant25
|
||
},
|
||
{
|
||
vLine24Octant07,vLine24Octant16,vLine24Octant07,vLine24Octant16,
|
||
vLine24Octant34,vLine24Octant25,vLine24Octant34,vLine24Octant25
|
||
},
|
||
{
|
||
vLine32Octant07,vLine32Octant16,vLine32Octant07,vLine32Octant16,
|
||
vLine32Octant34,vLine32Octant25,vLine32Octant34,vLine32Octant25
|
||
}
|
||
|
||
};
|
||
|
||
//
|
||
// mask for 4bpp pixels
|
||
//
|
||
|
||
UCHAR PixelLineMask4[2] = {0x0f,0xf0};
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* vSolidLine
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* Extract line end points from path object and call lower lever drawing
|
||
* routine
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pso - destination surface object
|
||
* ppo - path object
|
||
* pptfx - line coordinates if 'ppo' is NULL
|
||
* pco - clip object
|
||
* iSolidColor - solid color to draw
|
||
*
|
||
* Return Value:
|
||
*
|
||
* none
|
||
*
|
||
\**************************************************************************/
|
||
|
||
VOID
|
||
vSolidLine (
|
||
SURFACE *pSurf,
|
||
PATHOBJ *ppo,
|
||
POINTFIX*pptfx,
|
||
CLIPOBJ *pco,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
PATHDATA pd;
|
||
BOOL bMore;
|
||
ULONG cptfx;
|
||
POINTFIX ptfxStartFigure;
|
||
POINTFIX ptfxLast;
|
||
POINTFIX* pptfxFirst;
|
||
POINTFIX* pptfxBuf;
|
||
ULONG ulFormat;
|
||
LONG lDelta;
|
||
PBYTE pjDst;
|
||
RECTL arclClip[4];
|
||
PRECTL prclClip = (PRECTL) NULL;
|
||
|
||
//
|
||
// check out params
|
||
//
|
||
|
||
ASSERTGDI((pco == NULL) || (pco->iDComplexity != DC_COMPLEX),
|
||
"Routine does not handle complex clipping");
|
||
|
||
ulFormat = pSurf->iFormat();
|
||
lDelta = pSurf->lDelta();
|
||
pjDst = (PUCHAR)(pSurf->pvScan0());
|
||
|
||
//
|
||
// determine format and routines
|
||
//
|
||
|
||
switch (ulFormat)
|
||
{
|
||
case BMF_1BPP:
|
||
iSolidColor = iSolidColor ? 0xffffffff : 0x00000000;
|
||
break;
|
||
|
||
//
|
||
// rest fall through
|
||
//
|
||
|
||
case BMF_4BPP:
|
||
iSolidColor |= (iSolidColor << 4);
|
||
case BMF_8BPP:
|
||
iSolidColor |= (iSolidColor << 8);
|
||
case BMF_16BPP:
|
||
iSolidColor |= (iSolidColor << 16);
|
||
case BMF_24BPP:
|
||
case BMF_32BPP:
|
||
break;
|
||
default:
|
||
RIP("Invalid bitmap format");
|
||
}
|
||
|
||
//
|
||
// get clipping rectangle if needed, copy the rectangle into several
|
||
// formats for use by the GIQ clipping routine
|
||
//
|
||
|
||
if ((pco != NULL) && (pco->iDComplexity == DC_RECT))
|
||
{
|
||
//
|
||
// assign temp rectangles to clipping bounds
|
||
//
|
||
|
||
arclClip[0] = pco->rclBounds;
|
||
|
||
#if DBG_LINE
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Clipping rect = %li,%li to %li,%li\n",
|
||
arclClip[0].left,
|
||
arclClip[0].top,
|
||
arclClip[0].right,
|
||
arclClip[0].bottom);
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// generate clipping rect variants for use in
|
||
// GIQ line routines
|
||
//
|
||
|
||
arclClip[1].top = pco->rclBounds.left;
|
||
arclClip[2].left = pco->rclBounds.left;
|
||
arclClip[3].top = pco->rclBounds.left;
|
||
|
||
arclClip[1].left = pco->rclBounds.top;
|
||
arclClip[2].bottom = -pco->rclBounds.top + 1;
|
||
arclClip[3].right = arclClip[2].bottom;
|
||
|
||
arclClip[1].bottom = pco->rclBounds.right;
|
||
arclClip[2].right = pco->rclBounds.right;
|
||
arclClip[3].bottom = pco->rclBounds.right;
|
||
|
||
arclClip[1].right = pco->rclBounds.bottom;
|
||
arclClip[2].top = -pco->rclBounds.bottom + 1;
|
||
arclClip[3].left = arclClip[2].top;
|
||
|
||
prclClip = arclClip;
|
||
|
||
}
|
||
|
||
//
|
||
// subtract 1 from ulFormat to use as array index
|
||
//
|
||
|
||
ulFormat --;
|
||
|
||
//
|
||
// if the path pointer 'ppo' is NULL, then we must use the vertice
|
||
// pointer 'pptfx':
|
||
//
|
||
|
||
if (ppo == NULL)
|
||
{
|
||
vDrawLine(pptfx,pptfx + 1,pjDst,lDelta,iSolidColor,prclClip,ulFormat);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Enumerate the paths and send line segments to
|
||
// vDrawLine
|
||
//
|
||
//
|
||
// start enumeration of lines
|
||
//
|
||
|
||
pd.flags = 0;
|
||
|
||
((EPATHOBJ*) ppo)->vEnumStart();
|
||
|
||
//
|
||
// enumerate each set
|
||
//
|
||
|
||
do
|
||
{
|
||
bMore = ((EPATHOBJ*) ppo)->bEnum(&pd);
|
||
|
||
cptfx = pd.count;
|
||
|
||
//
|
||
// Should not get to here with empty path
|
||
//
|
||
|
||
if (cptfx == 0)
|
||
{
|
||
ASSERTGDI(!bMore, "Empty path record in non-empty path");
|
||
break;
|
||
}
|
||
|
||
//
|
||
// if BEGINSUBPATH, save the starting point for the
|
||
// figure
|
||
//
|
||
|
||
if (pd.flags & PD_BEGINSUBPATH)
|
||
{
|
||
ptfxStartFigure = *pd.pptfx;
|
||
pptfxFirst = pd.pptfx;
|
||
pptfxBuf = pd.pptfx + 1;
|
||
cptfx--;
|
||
|
||
} else {
|
||
|
||
pptfxFirst = &ptfxLast;
|
||
pptfxBuf = pd.pptfx;
|
||
|
||
}
|
||
|
||
|
||
//
|
||
// draw line segments
|
||
//
|
||
|
||
if (cptfx > 0)
|
||
{
|
||
//
|
||
// draw line segment
|
||
//
|
||
|
||
while (cptfx --) {
|
||
|
||
vDrawLine(pptfxFirst,pptfxBuf,pjDst,lDelta,iSolidColor,prclClip,ulFormat);
|
||
|
||
pptfxFirst = pptfxBuf;
|
||
pptfxBuf++;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
ptfxLast = pd.pptfx[pd.count - 1];
|
||
|
||
if (pd.flags & PD_CLOSEFIGURE)
|
||
{
|
||
|
||
//
|
||
// draw closure line segment
|
||
//
|
||
|
||
vDrawLine(&ptfxLast,&ptfxStartFigure,pjDst,lDelta,iSolidColor,prclClip,ulFormat);
|
||
|
||
}
|
||
|
||
} while (bMore);
|
||
}
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* vDrawLine
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* This routine is passed end points of a line segment, either integer or
|
||
* GIQ. The DDA equation for the line is determined then specific routines
|
||
* are called to run the line DDA and draw the pixels for each bitmap format
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pptfx0 - end point 0
|
||
* pptfx1 - end point 1
|
||
* pjDst - pointer to dst
|
||
* lDelta - byte scan line increment for dst
|
||
* iSolidColor - draw color expnaded to 32 bits
|
||
* prclClip - clip rectangles
|
||
* FormatIndex - look up for dst bitmap format
|
||
*
|
||
* Return Value:
|
||
*
|
||
* none
|
||
*
|
||
\**************************************************************************/
|
||
VOID
|
||
vDrawLine (
|
||
POINTFIX *pptfx0,
|
||
POINTFIX *pptfx1,
|
||
PUCHAR pjDst,
|
||
LONG lDelta,
|
||
ULONG iSolidColor,
|
||
PRECTL prclClip,
|
||
ULONG FormatIndex
|
||
)
|
||
{
|
||
LONG x0;
|
||
LONG y0;
|
||
LONG x1;
|
||
LONG y1;
|
||
LONG dx;
|
||
LONG dy;
|
||
ULONG ulTmp;
|
||
PFN_OCTANT pfnOctant;
|
||
LONG DeltaDst = lDelta;
|
||
DDALINE DDALine;
|
||
LONG Reduce;
|
||
|
||
DDALine.ulFlags = 0;
|
||
|
||
//
|
||
// check for GIQ lines
|
||
//
|
||
|
||
ulTmp = ( (ULONG)pptfx0->x |
|
||
(ULONG)pptfx0->y |
|
||
(ULONG)pptfx1->x |
|
||
(ULONG)pptfx1->y
|
||
) & 0x0F;
|
||
|
||
|
||
//
|
||
// check for integer lines
|
||
//
|
||
|
||
if (ulTmp == 0)
|
||
{
|
||
|
||
//
|
||
// check for no clipping rectangle or trivial
|
||
// accept/reject of each line with the clipping
|
||
// rectangle
|
||
//
|
||
|
||
x0 = pptfx0->x >> 4;
|
||
y0 = pptfx0->y >> 4;
|
||
x1 = pptfx1->x >> 4;
|
||
y1 = pptfx1->y >> 4;
|
||
DDALine.ptlStart.x = x0;
|
||
DDALine.ptlStart.y = y0;
|
||
|
||
//
|
||
// order x0,x1 and y0,y1 for clip check and slope calculation
|
||
//
|
||
|
||
if (x1 < x0) {
|
||
ULONG Tmp = x1;
|
||
x1 = x0;
|
||
x0 = Tmp;
|
||
DDALine.ulFlags |= FL_SOL_FLIP_H;
|
||
}
|
||
|
||
if (y1 < y0) {
|
||
ULONG Tmp = y1;
|
||
y1 = y0;
|
||
y0 = Tmp;
|
||
DDALine.ulFlags |= FL_SOL_FLIP_V;
|
||
}
|
||
|
||
if (prclClip != (PRECTL) NULL)
|
||
{
|
||
|
||
//
|
||
// check for a line totally outside clip rect
|
||
//
|
||
|
||
if (
|
||
(x1 < prclClip->left) ||
|
||
(x0 >= prclClip->right) ||
|
||
(y1 < prclClip->top) ||
|
||
(y0 >= prclClip->bottom)
|
||
)
|
||
{
|
||
//
|
||
// line is totally clipped out
|
||
//
|
||
|
||
#if DBG_LINE
|
||
if (DbgLine >= 1) {
|
||
DbgPrint("Trivial reject line %li,%li to %li,%li\n",x0,y0,x1,y1);
|
||
DbgPrint("Clipping rect: %li,%li to %li,%li\n",
|
||
prclClip->left,
|
||
prclClip->top,
|
||
prclClip->right,
|
||
prclClip->bottom);
|
||
}
|
||
#endif
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// check for line that is not totally inside clip rect,
|
||
// if not then call GIQ routine which has rectangular
|
||
// clipping.
|
||
//
|
||
|
||
if
|
||
(
|
||
(x0 < prclClip->left) ||
|
||
(x1 >= prclClip->right) ||
|
||
(y0 < prclClip->top) ||
|
||
(y1 >= prclClip->bottom)
|
||
)
|
||
{
|
||
goto calc_GIQ_line;
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// transform line to the first octant and calculate
|
||
// terms and flags
|
||
//
|
||
|
||
//
|
||
// find out if line is x major or y major
|
||
//
|
||
|
||
dx = x1 - x0;
|
||
dy = y1 - y0;
|
||
|
||
//
|
||
// check for x-major or y-major lines
|
||
//
|
||
|
||
if (dx >= dy) {
|
||
|
||
//
|
||
// check for horizontal line
|
||
//
|
||
|
||
if (dy == 0)
|
||
{
|
||
|
||
PFN_HORZ pfnHorz = gapfnHorizontal[FormatIndex];
|
||
pjDst = pjDst + (DDALine.ptlStart.y * lDelta);
|
||
|
||
//
|
||
// must check to see if end points have been
|
||
// swapped due to exclusive line drawing
|
||
//
|
||
|
||
if (DDALine.ulFlags & FL_SOL_FLIP_H)
|
||
{
|
||
x0++;
|
||
x1++;
|
||
}
|
||
|
||
(*pfnHorz)(pjDst,x0,x1,iSolidColor);
|
||
return;
|
||
}
|
||
|
||
//
|
||
// check for zero length
|
||
//
|
||
|
||
if (dx == 0) {
|
||
return;
|
||
}
|
||
|
||
Reduce = -1;
|
||
|
||
//
|
||
// x major line
|
||
//
|
||
|
||
DDALine.dMajor = dx;
|
||
DDALine.dMinor = dy;
|
||
|
||
//
|
||
// see if y has been flipped
|
||
//
|
||
|
||
if (DDALine.ulFlags & FL_SOL_FLIP_V)
|
||
{
|
||
DeltaDst = -DeltaDst;
|
||
Reduce = 0;
|
||
}
|
||
|
||
//
|
||
// Bresenham term except lErrorTerm is normally dy - dx/2 or
|
||
// 2x which is 2*dy - dx. In this case the 2*2y is not added to
|
||
// the error term until the start of the inner loop routine so that
|
||
// the x86 can immediately use the flag register to determine the sign
|
||
// of the error term after the addition of 2*dy.
|
||
//
|
||
|
||
DDALine.cPels = DDALine.dMajor;
|
||
DDALine.lErrorTerm = -DDALine.dMajor;
|
||
DDALine.dMajor = 2 * DDALine.dMajor;
|
||
DDALine.dMinor = 2 * DDALine.dMinor;
|
||
|
||
//
|
||
// if FL_SOL_FLIP_V then lError term must be reduced by one to
|
||
// compensate for the rounding convention
|
||
//
|
||
|
||
DDALine.lErrorTerm += Reduce;
|
||
|
||
} else {
|
||
|
||
//
|
||
// check for 0 length
|
||
//
|
||
|
||
if (dy == 0) {
|
||
return;
|
||
}
|
||
|
||
Reduce = -1;
|
||
|
||
//
|
||
// y major line, swap the meaning of dMajor and dMinor
|
||
//
|
||
|
||
DDALine.dMajor = dy;
|
||
DDALine.dMinor = dx;
|
||
|
||
DDALine.ulFlags |= FL_SOL_FLIP_D;
|
||
|
||
DDALine.xInc = 1;
|
||
|
||
//
|
||
// check for flipped x
|
||
//
|
||
|
||
if (DDALine.ulFlags & FL_SOL_FLIP_H) {
|
||
|
||
//
|
||
// compensate for negative x in y major line
|
||
//
|
||
|
||
Reduce = 0;
|
||
}
|
||
|
||
//
|
||
// + or - y
|
||
//
|
||
|
||
if (DDALine.ulFlags & FL_SOL_FLIP_V) {
|
||
DeltaDst = -DeltaDst;
|
||
}
|
||
|
||
//
|
||
// Bresenham term except lErrorTerm is normally dy - dx/2 or
|
||
// 2x which is 2*dy - dx. In this case the 2*2y is not added to
|
||
// the error term until the start of the inner loop routine so that
|
||
// the x86 can immediately use the flag register to determine the sign
|
||
// of the error term after the addition of 2*dy.
|
||
//
|
||
|
||
DDALine.cPels = DDALine.dMajor;
|
||
DDALine.lErrorTerm = -DDALine.dMajor;
|
||
DDALine.dMajor = 2 * DDALine.dMajor;
|
||
DDALine.dMinor = 2 * DDALine.dMinor;
|
||
|
||
//
|
||
// if FL_SOL_FLIP_H then lError term must be reduced by one to
|
||
// compensate for the rounding convention
|
||
//
|
||
|
||
DDALine.lErrorTerm += Reduce;
|
||
|
||
}
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Integer line:\n");
|
||
DbgPrint("x0 = %li, y0 = %li\n",x0,y0);
|
||
DbgPrint("Error term = %li\n",DDALine.lErrorTerm);
|
||
DbgPrint("dMajor = %li\n",DDALine.dMajor);
|
||
DbgPrint("dMinor = %li\n",DDALine.dMinor);
|
||
DbgPrint("Pixel Count = %li\n",DDALine.cPels);
|
||
DbgPrint("ulFlags = 0x%08lx\n\n",DDALine.ulFlags);
|
||
}
|
||
|
||
#endif
|
||
|
||
} else {
|
||
|
||
calc_GIQ_line:
|
||
|
||
//
|
||
// caclulate GIQ parameters
|
||
//
|
||
|
||
|
||
if (!bGIQtoIntegerLine(pptfx0,pptfx1,prclClip,&DDALine)) {
|
||
return;
|
||
}
|
||
|
||
//
|
||
// check for 0 length
|
||
//
|
||
|
||
if (DDALine.cPels <= 0) {
|
||
return;
|
||
}
|
||
|
||
if (DDALine.ulFlags & FL_SOL_FLIP_V)
|
||
{
|
||
DeltaDst = -DeltaDst;
|
||
}
|
||
|
||
#if DBG_LINE
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("GIQ line:\n");
|
||
DbgPrint("x0 = %li\n",DDALine.ptlStart.x);
|
||
DbgPrint("y0 = %li\n",DDALine.ptlStart.y);
|
||
DbgPrint("Error term = %li\n",DDALine.lErrorTerm);
|
||
DbgPrint("dMajor = %li\n",DDALine.dMajor);
|
||
DbgPrint("dMinor = %li\n",DDALine.dMinor);
|
||
DbgPrint("Pixel Count = %li\n",DDALine.cPels);
|
||
DbgPrint("DeltaDst = %li\n",DeltaDst);
|
||
DbgPrint("xInc = %li\n",DDALine.xInc);
|
||
DbgPrint("ulFlags = 0x%08lx\n\n",DDALine.ulFlags);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//
|
||
// select drawing routine based on format and octant
|
||
//
|
||
|
||
pfnOctant = gapfnOctant[FormatIndex][DDALine.ulFlags & 0x07];
|
||
|
||
pjDst = pjDst + (DDALine.ptlStart.y * lDelta);
|
||
|
||
(*pfnOctant)(&DDALine,pjDst,DeltaDst,iSolidColor);
|
||
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 8bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
#if !defined(_X86_)
|
||
|
||
VOID
|
||
vLine8Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = (UCHAR)iSolidColor;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst++;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
vLine8Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
|
||
//
|
||
// octant 3
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += pDDALine->ptlStart.x;
|
||
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = (UCHAR)iSolidColor;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst--;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine8Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
|
||
//
|
||
// octant 1
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive/negative
|
||
// y - positive
|
||
//
|
||
|
||
pjDst += pDDALine->ptlStart.x;
|
||
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = (UCHAR)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pjDst ++;
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine8Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
|
||
//
|
||
// octant 5,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive/negative
|
||
// y - negative
|
||
//
|
||
|
||
pjDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = (UCHAR)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pjDst --;
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 16 bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
VOID
|
||
vLine16Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
PUSHORT pusDst = (PUSHORT)pjDst;
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pusDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pusDst = (USHORT)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pusDst++;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pusDst = (PUSHORT)((PUCHAR)pusDst + lDeltaDst);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine16Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
PUSHORT pusDst = (PUSHORT)pjDst;
|
||
|
||
//
|
||
// octant 3
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
pusDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pusDst = (USHORT)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pusDst--;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pusDst = (PUSHORT)((PUCHAR)pusDst + lDeltaDst);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine16Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
PUSHORT pusDst = (PUSHORT)pjDst;
|
||
|
||
//
|
||
// octant 1
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pusDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pusDst = (USHORT)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pusDst = (PUSHORT)((PUCHAR)pusDst + lDeltaDst);
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pusDst ++;
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine16Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
PUSHORT pusDst = (PUSHORT)pjDst;
|
||
|
||
//
|
||
// octant 5,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - negative
|
||
// y - positive/ negative
|
||
//
|
||
|
||
pusDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pusDst = (USHORT)iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pusDst = (PUSHORT)((PUCHAR)pusDst + lDeltaDst);
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pusDst --;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 24bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
VOID
|
||
vLine24Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
UCHAR Red = (UCHAR)iSolidColor;
|
||
UCHAR Green = (UCHAR)(iSolidColor >> 8);
|
||
UCHAR Blue = (UCHAR)(iSolidColor >> 16);
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += (3 * pDDALine->ptlStart.x);
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += 3;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine24Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
UCHAR Red = (UCHAR)iSolidColor;
|
||
UCHAR Green = (UCHAR)(iSolidColor >> 8);
|
||
UCHAR Blue = (UCHAR)(iSolidColor >> 16);
|
||
|
||
//
|
||
// octant 3
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += (3 * pDDALine->ptlStart.x);
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst -= 3;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine24Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
UCHAR Red = (UCHAR)iSolidColor;
|
||
UCHAR Green = (UCHAR)(iSolidColor >> 8);
|
||
UCHAR Blue = (UCHAR)(iSolidColor >> 16);
|
||
|
||
//
|
||
// octant 1,2
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += (3*pDDALine->ptlStart.x);
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pjDst+=3;
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine24Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
UCHAR Red = (UCHAR)iSolidColor;
|
||
UCHAR Green = (UCHAR)(iSolidColor >> 8);
|
||
UCHAR Blue = (UCHAR)(iSolidColor >> 16);
|
||
|
||
//
|
||
// octant 5,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
pjDst += (3*pDDALine->ptlStart.x);
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pjDst-=3;
|
||
}
|
||
}
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 32 bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
VOID
|
||
vLine32Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
PULONG pulDst = (PULONG)pjDst;
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
pulDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pulDst = iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pulDst++;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pulDst = (PULONG)((PUCHAR)pulDst + lDeltaDst);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine32Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
PULONG pulDst = (PULONG)pjDst;
|
||
|
||
//
|
||
// octant 3
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
pulDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pulDst = iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pulDst--;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pulDst = (PULONG)((PUCHAR)pulDst + lDeltaDst);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine32Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
PULONG pulDst = (PULONG)pjDst;
|
||
|
||
//
|
||
// octant 1
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive/negative
|
||
// y - positive
|
||
//
|
||
|
||
pulDst += pDDALine->ptlStart.x;
|
||
|
||
|
||
while (TRUE) {
|
||
|
||
*pulDst = iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pulDst = (PULONG)((PUCHAR)pulDst + lDeltaDst);
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pulDst++;
|
||
}
|
||
|
||
*pulDst = iSolidColor;
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine32Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
PULONG pulDst = (PULONG)pjDst;
|
||
|
||
//
|
||
// octant 5,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive/negative
|
||
// y - negative
|
||
//
|
||
|
||
pulDst += pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
*pulDst = iSolidColor;
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pulDst = (PULONG)((PUCHAR)pulDst + lDeltaDst);
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
pulDst--;
|
||
}
|
||
|
||
*pulDst = iSolidColor;
|
||
}
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 1bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
|
||
VOID
|
||
vLine1Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
ULONG Pixel;
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
UCHAR Mask = (UCHAR)(0x80 >> (Pixel & 0x07));
|
||
|
||
pjDst = pjDst + (Pixel >> 3);
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (iSolidColor) {
|
||
|
||
//
|
||
// loop for storing '1' pixels
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst |= Mask;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Mask = (UCHAR)(Mask >> 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x80;
|
||
pjDst++;
|
||
}
|
||
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
|
||
} else {
|
||
|
||
//
|
||
// loop for storing '0' pixels
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst &= (~Mask);
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Mask = (UCHAR)(Mask >> 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x80;
|
||
pjDst++;
|
||
}
|
||
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
vLine1Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
ULONG Pixel;
|
||
|
||
//
|
||
// octant 3,4
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
UCHAR Mask = (UCHAR)(0x80 >> (Pixel & 0x07));
|
||
|
||
pjDst = pjDst + (Pixel >> 3);
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (iSolidColor) {
|
||
|
||
//
|
||
// loop for storing '1' pixels
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst |= Mask;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Mask = (UCHAR)(Mask << 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x01;
|
||
pjDst--;
|
||
}
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
|
||
|
||
} else {
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst &= (~Mask);
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Mask = (UCHAR)(Mask << 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x01;
|
||
pjDst--;
|
||
}
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine1Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
ULONG Pixel;
|
||
|
||
//
|
||
// octant 1,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
UCHAR Mask = (UCHAR)(0x80 >> (Pixel & 0x07));
|
||
|
||
pjDst = pjDst + (Pixel >> 3);
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (iSolidColor) {
|
||
|
||
//
|
||
// loop for storing '1' pixels
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst |= Mask;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
|
||
Mask = (UCHAR)(Mask >> 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x80;
|
||
pjDst++;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
} else {
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst &= (~Mask);
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
|
||
Mask = (UCHAR)(Mask >> 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x80;
|
||
pjDst++;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
vLine1Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
ULONG Pixel;
|
||
|
||
//
|
||
// octant 2,5
|
||
//
|
||
// y major
|
||
//
|
||
// x - negative
|
||
// y - negative/positive
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
UCHAR Mask = (UCHAR)(0x80 >> (Pixel & 0x07));
|
||
|
||
pjDst = pjDst + (Pixel >> 3);
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (iSolidColor) {
|
||
|
||
//
|
||
// loop for storing '1' pixels
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst |= Mask;
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
|
||
Mask = (UCHAR)(Mask << 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x01;
|
||
pjDst--;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
} else {
|
||
|
||
while (TRUE) {
|
||
|
||
*pjDst &= (~Mask);
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
|
||
Mask = (UCHAR)(Mask << 1);
|
||
|
||
if (!(Mask)) {
|
||
Mask = 0x01;
|
||
pjDst--;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* Inner loop DDA line drawing routines for 4bpp
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* 4 dda routines for line drawing in each octant for each resolution
|
||
*
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pDDALine - dda parameters
|
||
* pjDst - Destination line address
|
||
* lDeltaDst - Destination address scan line increment (bytes)
|
||
* iSolidColor - Solid color for line
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
|
||
VOID
|
||
vLine4Octant07(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
ULONG Pixel;
|
||
PUCHAR PixelAddr;
|
||
|
||
|
||
iSolidColor &= 0x0f;
|
||
iSolidColor |= iSolidColor << 4;
|
||
|
||
//
|
||
// octant 0
|
||
//
|
||
// x major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
PixelAddr = pjDst + (Pixel >> 1);
|
||
|
||
*PixelAddr = (UCHAR)((*PixelAddr & PixelLineMask4[Pixel & 1]) |
|
||
(iSolidColor & ~PixelLineMask4[Pixel & 1]));
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Pixel++;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine4Octant34(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
ULONG Pixel;
|
||
PUCHAR PixelAddr;
|
||
|
||
iSolidColor &= 0x0f;
|
||
iSolidColor |= iSolidColor << 4;
|
||
|
||
//
|
||
// octant 3
|
||
//
|
||
// x major
|
||
//
|
||
// x - negative
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
PixelAddr = pjDst + (Pixel >> 1);
|
||
|
||
*PixelAddr = (UCHAR)((*PixelAddr & PixelLineMask4[Pixel & 1]) |
|
||
(iSolidColor & ~PixelLineMask4[Pixel & 1]));
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
Pixel--;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
|
||
ErrorTerm -= dM;
|
||
pjDst += lDeltaDst;
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
VOID
|
||
vLine4Octant16(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
ULONG Pixel;
|
||
PUCHAR PixelAddr;
|
||
|
||
iSolidColor &= 0x0f;
|
||
iSolidColor |= iSolidColor << 4;
|
||
|
||
//
|
||
// octant 1,6
|
||
//
|
||
// y major
|
||
//
|
||
// x - positive
|
||
// y - positive/negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
PixelAddr = pjDst + (Pixel >> 1);
|
||
*PixelAddr = (UCHAR)((*PixelAddr & PixelLineMask4[Pixel & 1]) |
|
||
(iSolidColor & ~PixelLineMask4[Pixel & 1]));
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
Pixel ++;
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vLine4Octant25(
|
||
PDDALINE pDDALine,
|
||
PUCHAR pjDst,
|
||
LONG lDeltaDst,
|
||
ULONG iSolidColor
|
||
)
|
||
{
|
||
|
||
LONG ErrorTerm = pDDALine->lErrorTerm;
|
||
LONG dM = pDDALine->dMajor;
|
||
LONG dN = pDDALine->dMinor;
|
||
LONG PixelCount = pDDALine->cPels;
|
||
LONG xInc = pDDALine->xInc;
|
||
ULONG Pixel;
|
||
PUCHAR PixelAddr;
|
||
|
||
iSolidColor &= 0x0f;
|
||
iSolidColor |= iSolidColor << 4;
|
||
|
||
//
|
||
// octant 2,5
|
||
//
|
||
// y major
|
||
//
|
||
// x - negative
|
||
// y - psoitive\negative
|
||
//
|
||
|
||
Pixel = pDDALine->ptlStart.x;
|
||
|
||
while (TRUE) {
|
||
|
||
PixelAddr = pjDst + (Pixel >> 1);
|
||
*PixelAddr = (UCHAR)((*PixelAddr & PixelLineMask4[Pixel & 1]) |
|
||
(iSolidColor & ~PixelLineMask4[Pixel & 1]));
|
||
|
||
//
|
||
// integer line
|
||
//
|
||
|
||
if (--PixelCount == 0) {
|
||
return;
|
||
}
|
||
|
||
pjDst += lDeltaDst;
|
||
ErrorTerm += dN;
|
||
|
||
if (ErrorTerm >= 0){
|
||
ErrorTerm -= dM;
|
||
Pixel --;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* vHorizontalLineN
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* Accelerator for horizontal lines
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pjDst - Scan line dst address
|
||
* x0 - Starting pixel location
|
||
* x1 - Ending pixel location (exclusive)
|
||
* iSolidColor - Solid Color replicated to 32 bits if needed
|
||
*
|
||
* Return Value:
|
||
*
|
||
* VOID
|
||
*
|
||
\**************************************************************************/
|
||
|
||
|
||
VOID
|
||
vHorizontalLine1(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
ULONG Count;
|
||
ULONG Alignment;
|
||
|
||
//
|
||
// count = number of pixels to write, make sure it is not 0
|
||
//
|
||
|
||
Count = x1 - x0;
|
||
|
||
if (Count) {
|
||
|
||
pjDst += (x0 >> 3);
|
||
|
||
Alignment = x0 & 0x07;
|
||
|
||
//
|
||
// alignment Start bits
|
||
//
|
||
|
||
if ((Alignment) && ((ULONG)Count >= (8 - Alignment)))
|
||
{
|
||
//
|
||
// partial byte
|
||
//
|
||
|
||
*pjDst = (UCHAR)((*pjDst & (~(0xFF >> Alignment))) |
|
||
(iSolidColor & (0xFF >> Alignment)));
|
||
|
||
pjDst ++;
|
||
Count -= ( 8 - Alignment);
|
||
Alignment = 0;
|
||
|
||
}
|
||
|
||
//
|
||
// byte loop
|
||
//
|
||
|
||
if (Alignment == 0) {
|
||
|
||
//
|
||
// full byte stores
|
||
//
|
||
|
||
ULONG NumBytes = Count >> 3;
|
||
|
||
if (NumBytes > 0) {
|
||
RtlFillMemory((PVOID)pjDst,NumBytes,(UCHAR)iSolidColor);
|
||
pjDst += NumBytes;
|
||
Count = (Count & 0x07);
|
||
}
|
||
|
||
//
|
||
// last store
|
||
//
|
||
|
||
if (Count > 0) {
|
||
*pjDst = (UCHAR)((*pjDst & (0xFF >> Count)) |
|
||
(iSolidColor & (~(0xFF >> Count))));
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// do whats left, partial of 1 byte with
|
||
// start bit = alignment, number of bits = Count
|
||
//
|
||
//
|
||
// bit
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||
// <20>7<EFBFBD>6<EFBFBD>5<EFBFBD>4<EFBFBD>3<EFBFBD>2<EFBFBD>1<EFBFBD>0<EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//
|
||
// pixel
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||
// <20>0<EFBFBD>1<EFBFBD>2<EFBFBD>3<EFBFBD>4<EFBFBD>5<EFBFBD>6<EFBFBD>7<EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
{
|
||
UCHAR DstMask = (UCHAR)(0xff >> Alignment);
|
||
UCHAR AndMask = (UCHAR)(0xff << (8 - (Count + Alignment)));
|
||
|
||
DstMask &= AndMask;
|
||
|
||
*pjDst = (UCHAR)((*pjDst & (~DstMask)) | (iSolidColor & DstMask));
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
vHorizontalLine4(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
ULONG Count;
|
||
ULONG Alignment;
|
||
ULONG NumBytes;
|
||
|
||
|
||
Count = x1 - x0;
|
||
|
||
if (Count) {
|
||
|
||
pjDst += (x0 >> 1);
|
||
|
||
//
|
||
// alignment Start nibble
|
||
//
|
||
|
||
Alignment = x0 & 0x01;
|
||
|
||
if (Alignment)
|
||
{
|
||
*pjDst = (UCHAR)((*pjDst & 0xf0) |
|
||
(iSolidColor & 0x0f));
|
||
Count--;
|
||
pjDst++;
|
||
}
|
||
|
||
//
|
||
// aligned to byte boundary
|
||
//
|
||
|
||
NumBytes = Count >> 1;
|
||
|
||
if (NumBytes) {
|
||
|
||
RtlFillMemory((PVOID)pjDst,NumBytes,(BYTE)iSolidColor);
|
||
|
||
pjDst += NumBytes;
|
||
Count = Count & 0x01;
|
||
}
|
||
|
||
//
|
||
// end alignment if needed
|
||
//
|
||
|
||
if (Count) {
|
||
*pjDst = (UCHAR)((*pjDst & 0x0f) |
|
||
(iSolidColor & 0xf0));
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vHorizontalLine8(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
ULONG Count;
|
||
UCHAR Align;
|
||
|
||
//
|
||
// increment pjDst to x0 address
|
||
//
|
||
|
||
pjDst += x0;
|
||
|
||
//
|
||
// if byte count is less then 7, then just quickly do
|
||
// the bytes
|
||
//
|
||
|
||
Count = x1 - x0;
|
||
|
||
if (Count <= 6) {
|
||
|
||
while (Count--) {
|
||
*pjDst++ = (UCHAR)iSolidColor;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// large scan line that at least covers 1 full DWORD,
|
||
// first do partial bytes if needed
|
||
//
|
||
|
||
//
|
||
// do partial bytes, count is gaurenteed to be
|
||
// greater than max of 3 alignment bytes
|
||
//
|
||
|
||
Align = (UCHAR)(x0 & 0x03);
|
||
|
||
switch (Align) {
|
||
case 1:
|
||
*pjDst++ = (UCHAR)iSolidColor;
|
||
Count--;
|
||
case 2:
|
||
*(PUSHORT)pjDst = (USHORT)iSolidColor;
|
||
pjDst += 2;
|
||
Count -= 2;
|
||
break;
|
||
case 3:
|
||
*pjDst++ = (UCHAR)iSolidColor;
|
||
Count--;
|
||
}
|
||
|
||
ULONG NumBytes = Count & (~0x03);
|
||
|
||
//
|
||
// fill Dwords
|
||
//
|
||
|
||
RtlFillMemoryUlong((PVOID)pjDst,NumBytes,iSolidColor);
|
||
pjDst += NumBytes;
|
||
|
||
//
|
||
// fill last partial bytes
|
||
//
|
||
|
||
switch (Count & 0x03) {
|
||
case 1:
|
||
*pjDst = (UCHAR)iSolidColor;
|
||
break;
|
||
case 2:
|
||
*(PUSHORT)pjDst = (USHORT)iSolidColor;
|
||
break;
|
||
case 3:
|
||
*(PUSHORT)pjDst = (USHORT)iSolidColor;
|
||
*(pjDst+2) = (UCHAR)iSolidColor;
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
vHorizontalLine16(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
PUSHORT pusDst = (PUSHORT)pjDst + x0;
|
||
ULONG Count = x1 - x0;
|
||
|
||
if (Count) {
|
||
|
||
//
|
||
// do starting alignment
|
||
//
|
||
|
||
if (x0 & 0x01) {
|
||
*pusDst++ = (USHORT)iSolidColor;
|
||
Count--;
|
||
}
|
||
|
||
//
|
||
// fill dwords
|
||
//
|
||
|
||
ULONG NumDwords = Count >> 1;
|
||
|
||
if (NumDwords) {
|
||
RtlFillMemoryUlong((PVOID)pusDst,NumDwords << 2,iSolidColor);
|
||
}
|
||
|
||
//
|
||
// fill last 16 if needed
|
||
//
|
||
|
||
if (Count & 0x01) {
|
||
|
||
//
|
||
// add Number of USHORTS stored in RtlFillMemoryUlong to pusDst
|
||
// then store final USHORT
|
||
//
|
||
|
||
pusDst += NumDwords << 1;
|
||
|
||
*pusDst = (USHORT)iSolidColor;
|
||
}
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vHorizontalLine24(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
UCHAR Red = (UCHAR)iSolidColor;
|
||
UCHAR Green = (UCHAR)(iSolidColor >> 8);
|
||
UCHAR Blue = (UCHAR)(iSolidColor >> 16);
|
||
PUCHAR pjEnd = pjDst + 3*x1;
|
||
|
||
pjDst += 3*x0;
|
||
|
||
while (pjDst < pjEnd) {
|
||
*pjDst = Red;
|
||
*(pjDst+1) = Green;
|
||
*(pjDst+2) = Blue;
|
||
pjDst += 3;
|
||
}
|
||
}
|
||
|
||
VOID
|
||
vHorizontalLine32(
|
||
PUCHAR pjDst,
|
||
LONG x0,
|
||
LONG x1,
|
||
ULONG iSolidColor)
|
||
{
|
||
|
||
//
|
||
// incremnet pjDst x0 DWORDs
|
||
//
|
||
|
||
pjDst += (x0 << 2);
|
||
|
||
//
|
||
// fill
|
||
//
|
||
|
||
if (x1 != x0) {
|
||
RtlFillMemoryUlong((PVOID)pjDst,(x1 - x0) << 2,iSolidColor);
|
||
}
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* Routine Name
|
||
*
|
||
* bGIQtoIntegerLine
|
||
*
|
||
* Routine Description:
|
||
*
|
||
* This routine takes GIQ endpoints and calculates the correct integer
|
||
* endpoints, error term and flags.
|
||
*
|
||
* Arguments:
|
||
*
|
||
* pptfxStart - GIQ point 0
|
||
* pptfxEnd - GIQ point 1
|
||
* prclClip - clip rectangles
|
||
* pDDALine - Interger line params
|
||
*
|
||
* Return Value:
|
||
*
|
||
* True if this line can be drawn with 32 bit arithmatic and
|
||
* all params are calculated, otherwise false
|
||
*
|
||
\**************************************************************************/
|
||
|
||
#define HW_X_ROUND_DOWN 0x0100L // x = 1/2 rounds down in value
|
||
#define HW_Y_ROUND_DOWN 0x0200L // y = 1/2 rounds down in value
|
||
|
||
FLONG gaflHardwareRound[] = {
|
||
HW_X_ROUND_DOWN | HW_Y_ROUND_DOWN, // | | |
|
||
HW_X_ROUND_DOWN | HW_Y_ROUND_DOWN, // | | | FLIP_D
|
||
HW_X_ROUND_DOWN, // | | FLIP_V |
|
||
HW_Y_ROUND_DOWN, // | | FLIP_V | FLIP_D
|
||
HW_Y_ROUND_DOWN, // | FLIP_H | |
|
||
HW_X_ROUND_DOWN, // | FLIP_H | | FLIP_D
|
||
0, // | FLIP_H | FLIP_V |
|
||
0, // | FLIP_H | FLIP_V | FLIP_D
|
||
HW_Y_ROUND_DOWN, // SLOPE_ONE | | |
|
||
0xffffffff, // SLOPE_ONE | | | FLIP_D
|
||
HW_X_ROUND_DOWN, // SLOPE_ONE | | FLIP_V |
|
||
0xffffffff, // SLOPE_ONE | | FLIP_V | FLIP_D
|
||
HW_Y_ROUND_DOWN, // SLOPE_ONE | FLIP_H | |
|
||
0xffffffff, // SLOPE_ONE | FLIP_H | | FLIP_D
|
||
HW_X_ROUND_DOWN, // SLOPE_ONE | FLIP_H | FLIP_V |
|
||
0xffffffff // SLOPE_ONE | FLIP_H | FLIP_V | FLIP_D
|
||
};
|
||
|
||
BOOL bGIQtoIntegerLine(
|
||
POINTFIX* pptfxStart,
|
||
POINTFIX* pptfxEnd,
|
||
PRECTL prclClip,
|
||
DDALINE* pDDALine)
|
||
|
||
{
|
||
FLONG fl; // Various flags
|
||
ULONG M0; // Normalized fractional unit x start coordinate (0 <= M0 < F)
|
||
ULONG N0; // Normalized fractional unit y start coordinate (0 <= N0 < F)
|
||
ULONG M1; // Normalized fractional unit x end coordinate (0 <= M1 < F)
|
||
ULONG N1; // Normalized fractional unit x end coordinate (0 <= N1 < F)
|
||
ULONG dM; // Normalized fractional unit x-delta (0 <= dM)
|
||
ULONG dN; // Normalized fractional unit y-delta (0 <= dN <= dM)
|
||
LONG x; // Normalized x coordinate of origin
|
||
LONG y; // Normalized y coordinate of origin
|
||
LONG x0; // Normalized x offset from origin to start Pixel (inclusive)
|
||
LONG y0; // Normalized y offset from origin to start Pixel (inclusive)
|
||
LONG x1; // Normalized x offset from origin to end Pixel (inclusive)
|
||
LONG lGamma; // Possibly overflowing Bresenham error term at origin
|
||
LONGLONG eqGamma;// Non-overflowing Bresenham error term at origin
|
||
BOOL bReturn = FALSE;
|
||
|
||
|
||
/***********************************************************************\
|
||
* Normalize line to the first octant.
|
||
\***********************************************************************/
|
||
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("\nCalculate GIQ parameters for line:\n");
|
||
DbgPrint("pptfxStart = %li.%li, %li.%li\n",
|
||
pptfxStart->x >> 4,
|
||
pptfxStart->x & 0x0f,
|
||
pptfxStart->y >> 4,
|
||
pptfxStart->y & 0x0f);
|
||
|
||
DbgPrint("pptxEnd = %li.%li, %li.%li\n\n",
|
||
pptfxEnd->x >> 4,
|
||
pptfxEnd->x & 0x0f,
|
||
pptfxEnd->y >> 4,
|
||
pptfxEnd->y & 0x0f);
|
||
}
|
||
|
||
#endif
|
||
|
||
fl = 0;
|
||
|
||
M0 = pptfxStart->x;
|
||
dM = pptfxEnd->x;
|
||
|
||
if ((LONG) dM < (LONG) M0)
|
||
{
|
||
//
|
||
// Line runs from right to left, so flip across x = 0:
|
||
//
|
||
|
||
M0 = -(LONG) M0;
|
||
dM = -(LONG) dM;
|
||
fl |= FL_SOL_FLIP_H;
|
||
}
|
||
|
||
//
|
||
// Compute the delta dx. The DDI says we can never have a valid delta
|
||
// with a magnitude more than 2^31 - 1, but the engine never actually
|
||
// checks its transforms. Check for that case and simply refuse to draw
|
||
// the line:
|
||
//
|
||
|
||
dM -= M0;
|
||
if ((LONG) dM < 0)
|
||
{
|
||
goto GIQEnd;
|
||
}
|
||
|
||
N0 = pptfxStart->y;
|
||
dN = pptfxEnd->y;
|
||
|
||
if ((LONG) dN < (LONG) N0)
|
||
{
|
||
|
||
//
|
||
// Line runs from bottom to top, so flip across y = 0
|
||
//
|
||
|
||
N0 = -(LONG) N0;
|
||
dN = -(LONG) dN;
|
||
fl |= FL_SOL_FLIP_V;
|
||
}
|
||
|
||
//
|
||
// Compute the delta dy
|
||
//
|
||
|
||
dN -= N0;
|
||
if ((LONG) dN < 0)
|
||
{
|
||
goto GIQEnd;
|
||
}
|
||
|
||
//
|
||
// check for y-major lines and lines with
|
||
// slope = 1
|
||
//
|
||
|
||
if (dN >= dM)
|
||
{
|
||
if (dN == dM)
|
||
{
|
||
|
||
//
|
||
// Have to special case slopes of one:
|
||
//
|
||
|
||
fl |= FL_SOL_FLIP_SLOPE_ONE;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Since line has slope greater than 1, flip across x = y:
|
||
//
|
||
|
||
register ULONG ulTmp;
|
||
ulTmp = dM; dM = dN; dN = ulTmp;
|
||
ulTmp = M0; M0 = N0; N0 = ulTmp;
|
||
fl |= FL_SOL_FLIP_D;
|
||
}
|
||
}
|
||
|
||
//
|
||
// look up rounding for this line from the table
|
||
//
|
||
|
||
fl |= gaflHardwareRound[fl];
|
||
|
||
//
|
||
// Calculate the error term at Pixel 0
|
||
//
|
||
|
||
x = LFLOOR((LONG) M0);
|
||
y = LFLOOR((LONG) N0);
|
||
|
||
|
||
M0 = FXFRAC(M0);
|
||
N0 = FXFRAC(N0);
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Calc x = %li\n",x);
|
||
DbgPrint("Calc y = %li\n",y);
|
||
DbgPrint("Calc M0 = %li\n",M0);
|
||
DbgPrint("Calc N0 = %li\n",N0);
|
||
}
|
||
|
||
#endif
|
||
|
||
//
|
||
// Calculate the remainder term [ dM * (N0 + F/2) - M0 * dN ]. Note
|
||
// that M0 and N0 have at most 4 bits of significance (and if the
|
||
// arguments are properly ordered, on a 486 each multiply would be no
|
||
// more than 13 cycles):
|
||
//
|
||
|
||
//
|
||
// For the sake of speed, we're only going to do 32-bit multiplies
|
||
// in this routine. If the line is long enough though, we may
|
||
// need 38 bits for this calculation. Since at this point
|
||
// dM >= dN >= 0, and 0 <= N0 < 16, we'll just need to have 6 bits
|
||
// unused in 'dM':
|
||
//
|
||
|
||
if (dM <= (LONG_MAX >> 6))
|
||
{
|
||
lGamma = (N0 + F/2) * dM - M0 * dN;
|
||
|
||
if (fl & HW_Y_ROUND_DOWN)
|
||
lGamma--;
|
||
|
||
lGamma >>= FLOG2;
|
||
|
||
eqGamma = lGamma;
|
||
}
|
||
else
|
||
{
|
||
LONGLONG eq;
|
||
|
||
//
|
||
// Ugh, use safe 64-bit multiply code (cut and pasted from
|
||
// 'engline.cxx'):
|
||
//
|
||
|
||
eqGamma = Int32x32To64(N0 + F/2, dM);
|
||
eq = Int32x32To64(M0, dN);
|
||
|
||
eqGamma -= eq;
|
||
|
||
if (fl & FL_V_ROUND_DOWN)
|
||
eqGamma -= 1; // Adjust so y = 1/2 rounds down
|
||
|
||
eqGamma >>= FLOG2;
|
||
}
|
||
|
||
//
|
||
// Figure out which Pixels are at the ends of the line.
|
||
//
|
||
|
||
//
|
||
// The toughest part of GIQ is determining the start and end pels.
|
||
//
|
||
// Our approach here is to calculate x0 and x1 (the inclusive start
|
||
// and end columns of the line respectively, relative to our normalized
|
||
// origin). Then x1 - x0 + 1 is the number of pels in the line. The
|
||
// start point is easily calculated by plugging x0 into our line equation
|
||
// (which takes care of whether y = 1/2 rounds up or down in value)
|
||
// getting y0, and then undoing the normalizing flips to get back
|
||
// into device space.
|
||
//
|
||
// We look at the fractional parts of the coordinates of the start and
|
||
// end points, and call them (M0, N0) and (M1, N1) respectively, where
|
||
// 0 <= M0, N0, M1, N1 < 16. We plot (M0, N0) on the following grid
|
||
// to determine x0:
|
||
//
|
||
// +-----------------------> +x
|
||
// |
|
||
// | 0 1
|
||
// | 0123456789abcdef
|
||
// |
|
||
// | 0 ........?xxxxxxx
|
||
// | 1 ..........xxxxxx
|
||
// | 2 ...........xxxxx
|
||
// | 3 ............xxxx
|
||
// | 4 .............xxx
|
||
// | 5 ..............xx
|
||
// | 6 ...............x
|
||
// | 7 ................
|
||
// | 8 ................
|
||
// | 9 ......**........
|
||
// | a ........****...x
|
||
// | b ............****
|
||
// | c .............xxx****
|
||
// | d ............xxxx ****
|
||
// | e ...........xxxxx ****
|
||
// | f ..........xxxxxx
|
||
// |
|
||
// | 2 3
|
||
// v
|
||
//
|
||
// +y
|
||
//
|
||
// This grid accounts for the appropriate rounding of GIQ and last-pel
|
||
// exclusion. If (M0, N0) lands on an 'x', x0 = 2. If (M0, N0) lands
|
||
// on a '.', x0 = 1. If (M0, N0) lands on a '?', x0 rounds up or down,
|
||
// depending on what flips have been done to normalize the line.
|
||
//
|
||
// For the end point, if (M1, N1) lands on an 'x', x1 =
|
||
// floor((M0 + dM) / 16) + 1. If (M1, N1) lands on a '.', x1 =
|
||
// floor((M0 + dM)). If (M1, N1) lands on a '?', x1 rounds up or down,
|
||
// depending on what flips have been done to normalize the line.
|
||
//
|
||
// Lines of exactly slope one require a special case for both the start
|
||
// and end. For example, if the line ends such that (M1, N1) is (9, 1),
|
||
// the line has gone exactly through (8, 0) -- which may be considered
|
||
// to be part of 'x' because of rounding! So slopes of exactly slope
|
||
// one going through (8, 0) must also be considered as belonging in 'x'
|
||
// when an x value of 1/2 is supposed to round up in value.
|
||
//
|
||
//
|
||
// Calculate x0, x1:
|
||
//
|
||
|
||
N1 = FXFRAC(N0 + dN);
|
||
M1 = FXFRAC(M0 + dM);
|
||
|
||
x1 = LFLOOR(M0 + dM);
|
||
|
||
//
|
||
// Line runs left-to-right
|
||
//
|
||
//
|
||
// Compute x1
|
||
//
|
||
|
||
x1--;
|
||
if (M1 > 0)
|
||
{
|
||
if (N1 == 0)
|
||
{
|
||
if (LROUND(M1, fl & HW_X_ROUND_DOWN))
|
||
x1++;
|
||
}
|
||
else if (ABS((LONG) (N1 - F/2)) <= (LONG) M1)
|
||
{
|
||
x1++;
|
||
}
|
||
}
|
||
|
||
if ((fl & (FL_SOL_FLIP_SLOPE_ONE | HW_X_ROUND_DOWN))
|
||
== (FL_SOL_FLIP_SLOPE_ONE | HW_X_ROUND_DOWN))
|
||
{
|
||
|
||
//
|
||
// Have to special-case diagonal lines going through our
|
||
// the point exactly equidistant between two horizontal
|
||
// Pixels, if we're supposed to round x=1/2 down:
|
||
//
|
||
|
||
if ((M1 > 0) && (N1 == M1 + 8))
|
||
x1--;
|
||
|
||
if ((M0 > 0) && (N0 == M0 + 8))
|
||
{
|
||
x0 = 0;
|
||
goto left_to_right_compute_y0;
|
||
}
|
||
}
|
||
|
||
//
|
||
// Compute x0:
|
||
//
|
||
|
||
x0 = 0;
|
||
if (M0 > 0)
|
||
{
|
||
if (N0 == 0)
|
||
{
|
||
if (LROUND(M0, fl & HW_X_ROUND_DOWN))
|
||
x0 = 1;
|
||
}
|
||
else if (ABS((LONG) (N0 - F/2)) <= (LONG) M0)
|
||
{
|
||
x0 = 1;
|
||
}
|
||
}
|
||
|
||
left_to_right_compute_y0:
|
||
|
||
|
||
//**********************************************************************
|
||
// Calculate the start Pixel.
|
||
//***********************************************************************
|
||
|
||
//
|
||
// We now compute y0 and adjust the error term. We know x0, and we know
|
||
// the current formula for the Pixels to be lit on the line:
|
||
//
|
||
// dN * x + eqGamma
|
||
// y(x) = floor( ---------------- )
|
||
// dM
|
||
//
|
||
// The remainder of this expression is the new error term at (x0, y0).
|
||
// Since x0 is going to be either 0 or 1, we don't actually have to do a
|
||
// multiply or divide to compute y0. Finally, we subtract dM from the
|
||
// new error term so that it is in the range [-dM, 0).
|
||
//
|
||
|
||
y0 = 0;
|
||
|
||
if ((eqGamma >= 0) &&
|
||
(eqGamma >= (dM - (dN & (-(LONG) x0)))))
|
||
{
|
||
y0 = 1;
|
||
}
|
||
|
||
//
|
||
// check to see if the line is NULL, this should only happen
|
||
// with a line of slope = 1.
|
||
//
|
||
|
||
if (x1 < x0) {
|
||
pDDALine->cPels = 0;
|
||
bReturn = TRUE;
|
||
goto GIQEnd;
|
||
}
|
||
|
||
|
||
//*******************************************************************
|
||
//
|
||
// Must perform rectangular clipping
|
||
//
|
||
//*******************************************************************
|
||
|
||
if (prclClip != (PRECTL) NULL)
|
||
{
|
||
ULONG y1;
|
||
LONG xRight;
|
||
LONG xLeft;
|
||
LONG yBottom;
|
||
LONG yTop;
|
||
LONGLONG euq;
|
||
LONGLONG eq;
|
||
LONGLONG eqBeta;
|
||
RECTL rclClip;
|
||
|
||
//
|
||
// Note that y0 and y1 are actually the lower and upper bounds,
|
||
// respectively, of the y coordinates of the line (the line may
|
||
// have actually shrunk due to first/last pel clipping).
|
||
//
|
||
// Also note that x0, y0 are not necessarily zero.
|
||
//
|
||
|
||
RECTL* prcl = &prclClip[(fl & FL_SOL_RECTLCLIP_MASK)];
|
||
|
||
//
|
||
// take flip_h into account
|
||
//
|
||
|
||
if (fl & FL_SOL_FLIP_H) {
|
||
|
||
if (fl & FL_SOL_FLIP_D) {
|
||
|
||
rclClip.top = -prcl->bottom + 1;
|
||
rclClip.bottom = -prcl->top + 1;
|
||
rclClip.left = prcl->left;
|
||
rclClip.right = prcl->right;
|
||
|
||
} else {
|
||
|
||
rclClip.left = -prcl->right + 1;
|
||
rclClip.right = -prcl->left + 1;
|
||
rclClip.top = prcl->top;
|
||
rclClip.bottom = prcl->bottom;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
rclClip.left = prcl->left;
|
||
rclClip.right = prcl->right;
|
||
rclClip.top = prcl->top;
|
||
rclClip.bottom = prcl->bottom;
|
||
|
||
}
|
||
|
||
//
|
||
// Normalize to the same point we've normalized for the DDA
|
||
// calculations:
|
||
//
|
||
|
||
xRight = rclClip.right - x;
|
||
xLeft = rclClip.left - x;
|
||
yBottom = rclClip.bottom - y;
|
||
yTop = rclClip.top - y;
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
|
||
DbgPrint("Clipping line to rect %li,%li to %li,%li\n",
|
||
rclClip.left,
|
||
rclClip.top,
|
||
rclClip.right,
|
||
rclClip.bottom);
|
||
|
||
DbgPrint("Clipping Parameters: xLeft %li xRight %li yBottom %li yTop %li\n",
|
||
xLeft,
|
||
xRight,
|
||
yBottom,
|
||
yTop);
|
||
|
||
|
||
DbgPrint("normalized line before clip, x = %li, y = %li, x0 = %li, x1 = %li, y0 = %li\n",
|
||
x,y,x0,x1,y0);
|
||
|
||
DbgPrint("Line Params: dM = %li, dN = %li, eqGamma = %lx\n",dM,dN,(ULONG)eqGamma);
|
||
}
|
||
|
||
#endif
|
||
|
||
if (yBottom <= (LONG) y0 ||
|
||
xRight <= (LONG) x0 ||
|
||
xLeft > (LONG) x1)
|
||
{
|
||
Totally_Clipped:
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Line is totally clipped\n");
|
||
}
|
||
|
||
#endif
|
||
|
||
pDDALine->cPels = 0;
|
||
bReturn = TRUE;
|
||
goto GIQEnd;
|
||
}
|
||
|
||
if ((LONG) x1 >= xRight)
|
||
{
|
||
x1 = xRight - 1;
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Line clip x1 to %li\n",x1);
|
||
}
|
||
|
||
#endif
|
||
}
|
||
|
||
//
|
||
// We have to know the correct y1, which we haven't bothered to
|
||
// calculate up until now. This multiply and divide is quite
|
||
// expensive; we could replace it with code similar to that which
|
||
// we used for computing y0.
|
||
//
|
||
// The reason why we need the actual value, and not an upper
|
||
// bounds guess like y1 = LFLOOR(dM) + 2 is that we have to be
|
||
// careful when calculating x(y) that y0 <= y <= y1, otherwise
|
||
// we can overflow on the divide (which, needless to say, is very
|
||
// bad).
|
||
//
|
||
|
||
eqBeta = ~eqGamma;
|
||
euq = Int32x32To64(x1, dN);
|
||
euq += eqGamma;
|
||
|
||
y1 = DIV(euq, dM);
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
|
||
DbgPrint("Clipping: calculated y1 = %li eqBeta = 0x%lx 0x%lx\n",y1,(LONG)(eqBeta>>32),(ULONG)eqBeta);
|
||
|
||
}
|
||
|
||
#endif
|
||
|
||
//
|
||
// check for y1 less than the top of the clip rect
|
||
//
|
||
|
||
if (yTop > (LONG) y1)
|
||
goto Totally_Clipped;
|
||
|
||
//
|
||
// check for y1 > the bottom of the clip rect, clip if true
|
||
//
|
||
|
||
if (yBottom <= (LONG) y1)
|
||
{
|
||
y1 = yBottom;
|
||
|
||
euq = Int32x32To64(y1, dM);
|
||
euq += eqBeta;
|
||
x1 = DIV(euq,dN);
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
|
||
DbgPrint("Clipped y1 to %li, x1 = %li\n",y1,x1);
|
||
|
||
}
|
||
|
||
#endif
|
||
}
|
||
|
||
//
|
||
// At this point, we've taken care of calculating the intercepts
|
||
// with the right and bottom edges. Now we work on the left and
|
||
// top edges:
|
||
//
|
||
|
||
if (xLeft > (LONG) x0)
|
||
{
|
||
x0 = xLeft;
|
||
|
||
euq = Int32x32To64(x0, dN);
|
||
euq += eqGamma;
|
||
y0 = DIV(euq, dM);
|
||
|
||
if (yBottom <= (LONG) y0)
|
||
goto Totally_Clipped;
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
|
||
DbgPrint("Clipped x0 to %li, y0 = %li\n",x0,y0);
|
||
|
||
}
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
//
|
||
// check for y0 less than the top of the clip rect, clip if true
|
||
//
|
||
|
||
if (yTop > (LONG) y0)
|
||
{
|
||
y0 = yTop;
|
||
|
||
euq = Int32x32To64(y0, dM);
|
||
euq += eqBeta;
|
||
x0 = DIV(euq, dN) + 1;
|
||
|
||
if (xRight <= (LONG) x0)
|
||
goto Totally_Clipped;
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
|
||
DbgPrint("Clipped y0 to %li, x0 = %li\n",y0,x0);
|
||
|
||
}
|
||
|
||
#endif
|
||
}
|
||
|
||
euq = Int32x32To64(x0,dN);
|
||
eq = Int32x32To64(y0,dM);
|
||
|
||
euq -= eq;
|
||
|
||
eqGamma += euq;
|
||
|
||
eqGamma -= dM;
|
||
|
||
#if DBG_LINE
|
||
|
||
if (DbgLine >= 2) {
|
||
DbgPrint("Clipped line: x0 = %li, x1 = %li, y0 = %li, y1 = %li\n",
|
||
x0,
|
||
x1,
|
||
y0,
|
||
y1);
|
||
|
||
DbgPrint("eqGamma = %lx\n",eqGamma);
|
||
}
|
||
|
||
if (x0 > x1) {
|
||
DbgPrint("Clip Error: x0 > x1\n");
|
||
|
||
DbgPrint(" pptxStart = %li.%li, %li.%li\n",
|
||
pptfxStart->x >> 4,
|
||
pptfxStart->x & 0x0f,
|
||
pptfxStart->y >> 4,
|
||
pptfxStart->y & 0x0f);
|
||
|
||
DbgPrint(" pptxEnd = %li.%li, %li.%li\n",
|
||
pptfxEnd->x >> 4,
|
||
pptfxEnd->x & 0x0f,
|
||
pptfxEnd->y >> 4,
|
||
pptfxEnd->y & 0x0f);
|
||
|
||
|
||
DbgPrint(" prclClip = 0x%lx\n",prclClip);
|
||
|
||
DbgPrint(" x0 = %li\n",x0);
|
||
DbgPrint(" y0 = %li\n",y0);
|
||
DbgPrint(" x1 = %li\n",x1);
|
||
DbgPrint(" y1 = %li\n",y1);
|
||
|
||
DbgPrint(" dM = %li\n",dM);
|
||
DbgPrint(" dN = %li\n",dN);
|
||
|
||
DbgPrint(" lGamma = %li\n",lGamma);
|
||
|
||
DbgPrint(" Clipping line to rect %li,%li to %li,%li\n",
|
||
rclClip.left,
|
||
rclClip.top,
|
||
rclClip.right,
|
||
rclClip.bottom);
|
||
|
||
}
|
||
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
ASSERTGDI(x0 <= x1, "Improper rectangle clip");
|
||
|
||
} else {
|
||
|
||
//
|
||
// adjust lGamma
|
||
//
|
||
|
||
eqGamma += (dN & (-x0));
|
||
eqGamma -= dM;
|
||
|
||
if (eqGamma >= 0)
|
||
{
|
||
eqGamma -= dM;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// END of simple clipping
|
||
//
|
||
|
||
//
|
||
// Undo our flips to get the start coordinate:
|
||
//
|
||
|
||
x += x0;
|
||
y += y0;
|
||
|
||
if (fl & FL_SOL_FLIP_D)
|
||
{
|
||
register LONG lTmp;
|
||
lTmp = x; x = y; y = lTmp;
|
||
}
|
||
|
||
if (fl & FL_SOL_FLIP_V)
|
||
{
|
||
y = -y;
|
||
}
|
||
|
||
if (fl & FL_SOL_FLIP_H)
|
||
{
|
||
x = -x;
|
||
}
|
||
|
||
/***********************************************************************\
|
||
* Return the Bresenham terms:
|
||
\***********************************************************************/
|
||
|
||
//
|
||
// check values
|
||
//
|
||
|
||
pDDALine->ulFlags = fl;
|
||
pDDALine->ptlStart.x = x;
|
||
pDDALine->ptlStart.y = y;
|
||
pDDALine->cPels = x1 - x0 + 1; // NOTE: You'll have to check if cPels <= 0!
|
||
pDDALine->dMajor = dM;
|
||
pDDALine->dMinor = dN;
|
||
pDDALine->lErrorTerm = (LONG) eqGamma;
|
||
pDDALine->xInc = 1;
|
||
bReturn = TRUE;
|
||
|
||
//
|
||
// end routine
|
||
//
|
||
|
||
GIQEnd:
|
||
|
||
return(bReturn);
|
||
}
|