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.
 
 
 
 
 
 

2653 lines
60 KiB

/******************************Module*Header*******************************\
* Module Name: rotate.cxx
*
* Internal DDAs for EngPlgBlt
*
* Created: 06-Aug-1992 15:35:02
* Author: Donald Sidoroff [donalds]
*
* Copyright (c) 1992-1999 Microsoft Corporation
\**************************************************************************/
#include "precomp.hxx"
#include "rotate.hxx"
#ifdef DBG_PLGBLT
extern BOOL gflPlgBlt;
#endif
int aiPlgConst[][6] = {
{ 1, 0, 0, 0, 1, 0 },
{ 0, 1, 0, 1, 0, 0 },
{ -1, 0, 1, 0, 1, 0 },
{ 0, 1, 0, -1, 0, 1 },
{ 0, -1, 1, 1, 0, 0 },
{ 1, 0, 0, 0, -1, 1 },
{ 0, -1, 1, -1, 0, 1 },
{ -1, 0, 1, 0, -1, 1 }
};
int aiPlgSort[][4] = {
{ 0, 1, 2, 3 },
{ 0, 2, 1, 3 },
{ 1, 0, 3, 2 },
{ 1, 3, 0, 2 },
{ 2, 0, 3, 1 },
{ 2, 3, 0, 1 },
{ 3, 1, 2, 0 },
{ 3, 2, 1, 0 }
};
static VOID ROT_DIV(
DIV_T *pdt,
LONG lNum,
LONG lDen)
{
pdt->lQuo = lNum / lDen;
pdt->lRem = lNum % lDen;
if (pdt->lRem < 0)
{
pdt->lQuo -= 1;
pdt->lRem += lDen;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("%ld / %ld = %ld R %ld\n", lNum, lDen, pdt->lQuo, pdt->lRem);
#endif
}
static VOID QDIV(
DIV_T *pdt,
LONGLONG *peqNum,
LONG lDen)
{
ULONGLONG liQuo;
ULONG ul;
BOOL bSigned;
bSigned = *peqNum < 0;
if (bSigned)
{
liQuo = (ULONGLONG) (- (LONGLONG) *peqNum);
}
else
liQuo = *peqNum;
pdt->lQuo = DIVREM(liQuo, lDen, &ul);
if (bSigned)
{
pdt->lQuo = - pdt->lQuo;
if (ul == 0)
pdt->lRem = 0;
else
{
pdt->lQuo -= 1;
pdt->lRem = lDen - ((LONG) ul);
}
}
else
{
pdt->lRem = (LONG) ul;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("%ld,%ld / %ld = %ld R %ld\n", peqNum->HighPart, peqNum->LowPart, lDen, pdt->lQuo, pdt->lRem);
#endif
}
/******************************Public*Routine******************************\
* VOID vInitPlgDDA(pdda, pptl)
*
* Initialize the DDA
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
BOOL bInitPlgDDA(
PLGDDA *pdda,
RECTL *prclScan,
RECTL *prcl,
POINTFIX *pptfx)
{
POINTFIX aptfx[4];
RECTL rclScan;
RECTL rcl;
aptfx[0] = pptfx[0];
aptfx[1] = pptfx[1];
aptfx[2] = pptfx[2];
aptfx[3].x = aptfx[1].x + aptfx[2].x - aptfx[0].x;
aptfx[3].y = aptfx[1].y + aptfx[2].y - aptfx[0].y;
// If the source surface does not have a 0,0 origin, deal with it here.
if ((prcl->left != 0) || (prcl->top != 0))
{
rclScan.left = prclScan->left - prcl->left;
rclScan.top = prclScan->top - prcl->top;
rclScan.right = prclScan->right - prcl->left;
rclScan.bottom = prclScan->bottom - prcl->top;
prclScan = &rclScan;
rcl.left = 0;
rcl.top = 0;
rcl.right = prcl->right - prcl->left;
rcl.bottom = prcl->bottom - prcl->top;
prcl = &rcl;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
{
DbgPrint("prclScan = [(%ld,%ld) (%ld,%ld)]\n",
prclScan->left, prclScan->top, prclScan->right, prclScan->bottom);
DbgPrint("prcl = [(%ld,%ld) (%ld,%ld)]\n",
prcl->left, prcl->top, prcl->right, prcl->bottom);
DbgPrint("aptfx[0] = (%ld,%ld)\n", aptfx[0].x, aptfx[0].y);
DbgPrint("aptfx[1] = (%ld,%ld)\n", aptfx[1].x, aptfx[1].y);
DbgPrint("aptfx[2] = (%ld,%ld)\n", aptfx[2].x, aptfx[2].y);
DbgPrint("aptfx[3] = (%ld,%ld)\n", aptfx[3].x, aptfx[3].y);
}
#endif
int iTop = (aptfx[1].y > aptfx[0].y) == (aptfx[1].y > aptfx[3].y);
int iCase;
if (aptfx[iTop].y > aptfx[iTop ^ 3].y)
iTop ^= 3;
switch (iTop) {
case 0:
if (aptfx[1].y < aptfx[2].y)
iCase = 0;
else
if (aptfx[1].y > aptfx[2].y)
iCase = 1;
else
if (aptfx[1].x < aptfx[2].x)
iCase = 0;
else
iCase = 1;
break;
case 1:
if (aptfx[0].y < aptfx[3].y)
iCase = 2;
else
if (aptfx[0].y > aptfx[3].y)
iCase = 3;
else
if (aptfx[0].x < aptfx[3].x)
iCase = 2;
else
iCase = 3;
break;
case 2:
if (aptfx[0].y < aptfx[3].y)
iCase = 4;
else
if (aptfx[0].y > aptfx[3].y)
iCase = 5;
else
if (aptfx[0].x < aptfx[3].x)
iCase = 4;
else
iCase = 5;
break;
case 3:
if (aptfx[1].y < aptfx[2].y)
iCase = 6;
else
if (aptfx[1].y > aptfx[2].y)
iCase = 7;
else
if (aptfx[1].x < aptfx[2].x)
iCase = 6;
else
iCase = 7;
break;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("iTop = %ld, iCase = %ld\n", iTop, iCase);
#endif
LONG DELTA_1;
LONG DELTA_2;
switch (iCase) {
case 0:
case 2:
case 5:
case 7:
DELTA_1 = prcl->right - prcl->left;
DELTA_2 = prcl->bottom - prcl->top;
break;
case 1:
case 3:
case 4:
case 6:
DELTA_1 = prcl->bottom - prcl->top;
DELTA_2 = prcl->right - prcl->left;
break;
}
LONG ci1 = aiPlgConst[iCase][0];
LONG cj1 = aiPlgConst[iCase][1];
LONG c1 = aiPlgConst[iCase][2];
LONG ci2 = aiPlgConst[iCase][3];
LONG cj2 = aiPlgConst[iCase][4];
LONG c2 = aiPlgConst[iCase][5];
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("Global constants: %ld %ld %ld %ld %ld %ld %ld %ld\n",
DELTA_1, DELTA_2, ci1, cj1, c1, ci2, cj2, c2);
#endif
LONG V1 = ci1 * prclScan->left + cj1 * prclScan->top + c1 * (DELTA_1 - 1);
LONG V2 = ci2 * prclScan->left + cj2 * prclScan->top + c2 * (DELTA_2 - 1);
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("V1 = %ld, V2 = %ld\n", V1, V2);
#endif
LONG I0 = aptfx[aiPlgSort[iCase][0]].x;
LONG J0 = aptfx[aiPlgSort[iCase][0]].y;
LONG I1 = aptfx[aiPlgSort[iCase][1]].x;
LONG J1 = aptfx[aiPlgSort[iCase][1]].y;
LONG I2 = aptfx[aiPlgSort[iCase][2]].x;
LONG J2 = aptfx[aiPlgSort[iCase][2]].y;
LONG I3 = aptfx[aiPlgSort[iCase][3]].x;
LONG J3 = aptfx[aiPlgSort[iCase][3]].y;
I1 -= I0;
I2 -= I0;
I3 -= I0;
J1 -= J0;
J2 -= J0;
J3 -= J0;
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
{
DbgPrint("I0, I1, I2, I3 = %8ld %8ld %8ld %8ld\n", I0, I1, I2, I3);
DbgPrint("J0, J1, J2, J3 = %8ld %8ld %8ld %8ld\n", J0, J1, J2, J3);
}
#endif
LONG X1 = DELTA_2 * I1;
LONG Y1 = DELTA_2 * J1;
LONG X2 = DELTA_1 * I2;
LONG Y2 = DELTA_1 * J2;
// avoid divide by 0's. In some way shape or form, all divides are based on
// these two values. Note that by checking Y2, DELTA_1 is also validated. We
// can't just validate Y1 as well because it is special cased below to be 0.
// Also beware of overflows given large numbers where multipications can
// potentially shift off all set bits leaving you with a zero value. In the case
// where we just lose bits but don't end up with all zeros we will have
// undefined but non-exception (divide by zero) behavior
if ((Y2 == 0) || (DELTA_2 == 0))
return(FALSE);
LONG T = DELTA_1 * DELTA_2;
LONGLONG N = Int32x32To64(T, (J0 + 16));
LONGLONG eqTmp = Int32x32To64(V1, Y1);
N += eqTmp;
eqTmp = Int32x32To64(V2, Y2);
N += eqTmp;
N -= 1;
// LONG N = T * (J0 + 16) + V1 * Y1 + V2 * Y2 - 1;
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
{
DbgPrint("X1 = %ld, Y1 = %ld, X2 = %ld, Y2 = %ld\n", X1, Y1, X2, Y2);
DbgPrint("T = %ld, N = %ld,%ld\n", T, N.HighPart, N.LowPart);
}
#endif
T *= 16;
// overflow check: avoid divide by 0's
if ( T == 0 )
return(FALSE);
DDA_STEP dp1;
DDA_STEP dp2;
ROT_DIV(&dp1.dt, Y1, T);
dp1.lDen = T;
ROT_DIV(&dp2.dt, Y2, T);
dp2.lDen = T;
QDIV(&pdda->ds.dt0, &N, T);
pdda->ds.dt1 = pdda->ds.dt0;
DDA(&pdda->ds.dt1, &dp1)
pdda->ds.dt2 = pdda->ds.dt0;
DDA(&pdda->ds.dt2, &dp2)
pdda->ds.dt3 = pdda->ds.dt2;
DDA(&pdda->ds.dt3, &dp1)
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
{
DbgPrint("N0, N1, N2, N3 = %8ld %8ld %8ld %8ld\n",
pdda->ds.dt0.lQuo, pdda->ds.dt1.lQuo, pdda->ds.dt2.lQuo, pdda->ds.dt3.lQuo);
DbgPrint("R0, R1, R2, R3 = %8ld %8ld %8ld %8ld\n",
pdda->ds.dt0.lRem, pdda->ds.dt1.lRem, pdda->ds.dt2.lRem, pdda->ds.dt3.lRem);
}
#endif
ROT_DIV(&pdda->dp0_i.dt, ci1 * Y1 + ci2 * Y2, T);
pdda->dp0_i.lDen = T;
pdda->dp1_i = pdda->dp0_i;
pdda->dp2_i = pdda->dp0_i;
pdda->dp3_i = pdda->dp0_i;
ROT_DIV(&pdda->dp0_j.dt, cj1 * Y1 + cj2 * Y2, T);
pdda->dp0_j.lDen = T;
pdda->dp1_j = pdda->dp0_j;
pdda->dp2_j = pdda->dp0_j;
pdda->dp3_j = pdda->dp0_j;
LONGLONG Q = Int32x32To64(I1, J2);
eqTmp = Int32x32To64(J1, I2);
Q -= eqTmp;
// LONG Q = I1 * J2 - J1 * I2;
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_INIT)
DbgPrint("Q = %ld,%ld\n", Q.HighPart, Q.LowPart);
#endif
DIV_T dt1;
DIV_T dt2;
//overflow check: avoid divide by 0's
if ((16 * DELTA_1) == 0 || (16 * DELTA_2) == 0)
return(FALSE);
ROT_DIV(&dt1, ci1 * J1, 16 * DELTA_1);
ROT_DIV(&dt2, ci2 * J2, 16 * DELTA_2);
LONG dn_i = dt1.lQuo + dt2.lQuo;
ROT_DIV(&dt1, cj1 * J1, 16 * DELTA_1);
ROT_DIV(&dt2, cj2 * J2, 16 * DELTA_2);
LONG dn_j = dt1.lQuo + dt2.lQuo;
if (Y1 == 0)
{
pdda->dp01.dt.lQuo = 0;
pdda->dp01.dt.lRem = 0;
pdda->dp01.lDen = 0;
pdda->dp01_i.dt.lQuo = 0;
pdda->dp01_i.dt.lRem = 0;
pdda->dp01_i.lDen = 0;
pdda->dp01_j.dt.lQuo = 0;
pdda->dp01_j.dt.lRem = 0;
pdda->dp01_j.lDen = 0;
pdda->ds.dt01.lQuo = 0;
pdda->ds.dt01.lRem = 0;
pdda->ds.dt23.lQuo = 0;
pdda->ds.dt23.lRem = 0;
pdda->dpP01.dt.lQuo = 0;
pdda->dpP01.dt.lRem = 0;
pdda->dpP01.lDen = 0;
}
else
{
N= Int32x32To64(X1, 16 * pdda->ds.dt0.lQuo - J0);
eqTmp= Int32x32To64(Y1, (I0 + 16));
N += eqTmp;
eqTmp= Int32x32To64(V2, I1 * J2);
N -= eqTmp;
eqTmp= Int32x32To64(V2, I2 * J1);
N += eqTmp;
N -= 1;
// N = X1 * (16 * pdda->ds.dt0.lQuo - J0) + Y1 * (I0 + 16) - V2 * Q - 1;
pdda->dp01.lDen = 16 * Y1;
pdda->dp01_i.lDen = pdda->dp01.lDen;
pdda->dp01_j.lDen = pdda->dp01.lDen;
// overflow check: avoid divide by 0's.
if (pdda->dp01.lDen == 0)
return(FALSE);
QDIV(&pdda->ds.dt01, &N, pdda->dp01.lDen);
eqTmp= Int32x32To64(16 * X1, pdda->ds.dt2.lQuo - pdda->ds.dt0.lQuo);
eqTmp -= Q;
N += eqTmp;
// N += 16 * X1 * (pdda->ds.dt2.lQuo - pdda->ds.dt0.lQuo) - Q;
QDIV(&pdda->ds.dt23, &N, pdda->dp01.lDen);
ROT_DIV(&pdda->dp01.dt, 16 * X1, pdda->dp01.lDen);
N= Int32x32To64(ci2 * I1,J2);
eqTmp= Int32x32To64(ci2 * I2, J1);
N -= eqTmp; // Q * ci2
eqTmp= Int32x32To64(16 * dn_i, X1);
eqTmp -= N;
QDIV(&pdda->dp01_i.dt, &eqTmp, pdda->dp01_i.lDen);
N= Int32x32To64(cj2 * I1,J2);
eqTmp= Int32x32To64(cj2 * I2, J1);
N -= eqTmp; // Q * cj2
eqTmp= Int32x32To64(16 * dn_j, X1);
eqTmp -= N;
QDIV(&pdda->dp01_j.dt, &eqTmp, pdda->dp01_j.lDen);
// ROT_DIV(&pdda->dp01_i.dt, 16 * X1 * dn_i - ci2 * Q, pdda->dp01_i.lDen);
// ROT_DIV(&pdda->dp01_j.dt, 16 * X1 * dn_j - cj2 * Q, pdda->dp01_j.lDen);
// overflow check: avoid divide by 0's
// 16*Y1 was already checked above computing pdda->dp01.lDen
ROT_DIV(&pdda->dpP01.dt, 16 * X1, 16 * Y1);
pdda->dpP01.lDen = 16 * Y1;
}
N= Int32x32To64(X2, 16 * pdda->ds.dt0.lQuo - J0);
eqTmp= Int32x32To64(Y2, I0 + 16);
N += eqTmp;
eqTmp= Int32x32To64(V1, I1 * J2);
N += eqTmp;
eqTmp= Int32x32To64(V1, I2 * J1);
N -= eqTmp;
N -= 1;
// N = Y1 * (16 * pdda->ds.dt0.lQuo - J0) + Y2 * (I0 + 16) + V1 * Q - 1;
pdda->dp02.lDen = 16 * Y2;
pdda->dp02_i.lDen = pdda->dp02.lDen;
pdda->dp02_j.lDen = pdda->dp02.lDen;
// overflow check: avoid divide by 0's.
if (pdda->dp02.lDen == 0)
return(FALSE);
QDIV(&pdda->ds.dt02, &N, pdda->dp02.lDen);
eqTmp= Int32x32To64(16 * X2, pdda->ds.dt1.lQuo - pdda->ds.dt0.lQuo);
eqTmp += Q;
N += eqTmp;
// N += 16 * Y1 * (pdda->ds.dt1.lQuo - pdda->ds.dt0.lQuo) + Q;
QDIV(&pdda->ds.dt13, &N, pdda->dp02.lDen);
ROT_DIV(&pdda->dp02.dt, 16 * X2, pdda->dp02.lDen);
N= Int32x32To64(ci1 * I1,J2);
eqTmp= Int32x32To64(ci1 * I2, J1);
N -= eqTmp; // Q * ci1
eqTmp= Int32x32To64(16 * dn_i, X2);
eqTmp += N;
QDIV(&pdda->dp02_i.dt, &eqTmp, pdda->dp02_i.lDen);
N= Int32x32To64(cj1 * I1,J2);
eqTmp= Int32x32To64(cj1 * I2, J1);
N -= eqTmp; // Q * cj1
eqTmp= Int32x32To64(16 * dn_j, X2);
eqTmp += N;
QDIV(&pdda->dp02_j.dt, &eqTmp, pdda->dp02_j.lDen);
// DIV(&pdda->dp02_i.dt, 16 * X2 * dn_i + ci1 * Q, pdda->dp02_i.lDen);
// DIV(&pdda->dp02_j.dt, 16 * X2 * dn_j + cj1 * Q, pdda->dp02_j.lDen);
pdda->dp13 = pdda->dp02;
pdda->dp13_i = pdda->dp02_i;
pdda->dp13_j = pdda->dp02_j;
pdda->dp23 = pdda->dp01;
pdda->dp23_i = pdda->dp01_i;
pdda->dp23_j = pdda->dp01_j;
// overflow check: avoid divide by 0's
// 16*Y2 was already checked above computing pdda->dp02.lDen
ROT_DIV(&pdda->dpP02.dt, 16 * X2, 16 * Y2);
pdda->dpP02.lDen = 16 * Y2;
return(TRUE);
}
/******************************Public*Routine******************************\
* LONG lSizeDDA(pdda)
*
* Return the space needed to run the DDA for a scan
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
LONG lSizeDDA(PLGDDA *pdda)
{
LONG dt[4];
LONG max, min, i;
// Bug #336058:
// Prior to this fix, this function assumed that dt0 contains the
// top-most vertex and dt3 contains the bottom-most vertex in the
// parallelogram. However, under some calls to EngPlgBlt this appears
// to not be true (the bug includes a test program that can
// demonstrate this). That caused the allocated buffer to not be large
// enough which resulted in an AV (i.e. when doing the run from dt1
// to dt2). The fix is to find the smallest and largest vertices (with
// respect to y-values) and allocate enough space for a run from the
// smallest to the largest.
dt[0] = pdda->ds.dt0.lQuo;
dt[1] = pdda->ds.dt1.lQuo;
dt[2] = pdda->ds.dt2.lQuo;
dt[3] = pdda->ds.dt3.lQuo;
max = min = dt[0];
for (i=1; i<4; i++)
{
if (min > dt[i])
{
min = dt[i];
}
if (max < dt[i])
{
max = dt[i];
}
}
//LONG lTmp = pdda->ds.dt3.lQuo - pdda->ds.dt0.lQuo;
LONG lTmp = max-min;
if (lTmp == 0)
lTmp = 1;
return((lTmp + 4) * sizeof(CNTPOS) + sizeof(ULONG));
}
/******************************Public*Routine******************************\
* VOID vAdvXDDA(pdda)
*
* Advance the DDA in X.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vAdvXDDA(PLGDDA *pdda)
{
pdda->dsX.dt0.lQuo += pdda->dp0_i.dt.lQuo;
pdda->dsX.dt0.lRem += pdda->dp0_i.dt.lRem;
if (pdda->dsX.dt0.lRem >= pdda->dp0_i.lDen)
{
pdda->dsX.dt0.lRem -= pdda->dp0_i.lDen;
pdda->dsX.dt0.lQuo++;
DDA(&pdda->dsX.dt01, &pdda->dpP01);
DDA(&pdda->dsX.dt02, &pdda->dpP02);
}
pdda->dsX.dt1.lQuo += pdda->dp1_i.dt.lQuo;
pdda->dsX.dt1.lRem += pdda->dp1_i.dt.lRem;
if (pdda->dsX.dt1.lRem >= pdda->dp1_i.lDen)
{
pdda->dsX.dt1.lRem -= pdda->dp1_i.lDen;
pdda->dsX.dt1.lQuo++;
DDA(&pdda->dsX.dt13, &pdda->dpP02);
}
pdda->dsX.dt2.lQuo += pdda->dp2_i.dt.lQuo;
pdda->dsX.dt2.lRem += pdda->dp2_i.dt.lRem;
if (pdda->dsX.dt2.lRem >= pdda->dp2_i.lDen)
{
pdda->dsX.dt2.lRem -= pdda->dp2_i.lDen;
pdda->dsX.dt2.lQuo++;
DDA(&pdda->dsX.dt23, &pdda->dpP01);
}
DDA(&pdda->dsX.dt3, &pdda->dp3_i);
DDA(&pdda->dsX.dt01, &pdda->dp01_i);
DDA(&pdda->dsX.dt02, &pdda->dp02_i);
DDA(&pdda->dsX.dt13, &pdda->dp13_i);
DDA(&pdda->dsX.dt23, &pdda->dp23_i);
}
/******************************Public*Routine******************************\
* VOID vAdvYDDA(pdda)
*
* Advance the DDA in Y.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vAdvYDDA(PLGDDA *pdda)
{
pdda->ds.dt0.lQuo += pdda->dp0_j.dt.lQuo;
pdda->ds.dt0.lRem += pdda->dp0_j.dt.lRem;
if (pdda->ds.dt0.lRem >= pdda->dp0_j.lDen)
{
pdda->ds.dt0.lRem -= pdda->dp0_j.lDen;
pdda->ds.dt0.lQuo++;
DDA(&pdda->ds.dt01, &pdda->dpP01);
DDA(&pdda->ds.dt02, &pdda->dpP02);
}
pdda->ds.dt1.lQuo += pdda->dp1_j.dt.lQuo;
pdda->ds.dt1.lRem += pdda->dp1_j.dt.lRem;
if (pdda->ds.dt1.lRem >= pdda->dp1_j.lDen)
{
pdda->ds.dt1.lRem -= pdda->dp1_j.lDen;
pdda->ds.dt1.lQuo++;
DDA(&pdda->ds.dt13, &pdda->dpP02);
}
pdda->ds.dt2.lQuo += pdda->dp2_j.dt.lQuo;
pdda->ds.dt2.lRem += pdda->dp2_j.dt.lRem;
if (pdda->ds.dt2.lRem >= pdda->dp2_j.lDen)
{
pdda->ds.dt2.lRem -= pdda->dp2_j.lDen;
pdda->ds.dt2.lQuo++;
DDA(&pdda->ds.dt23, &pdda->dpP01);
}
DDA(&pdda->ds.dt3, &pdda->dp3_j);
DDA(&pdda->ds.dt01, &pdda->dp01_j);
DDA(&pdda->ds.dt02, &pdda->dp02_j);
DDA(&pdda->ds.dt13, &pdda->dp13_j);
DDA(&pdda->ds.dt23, &pdda->dp23_j);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPumpDDA(pdda, prun)
*
* 'Pump' out the target point run for the source point.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPumpDDA(
PLGDDA *pdda,
PLGRUN *prun)
{
DIV_T dt01 = pdda->dsX.dt01;
DIV_T dt02 = pdda->dsX.dt02;
DIV_T dt13 = pdda->dsX.dt13;
DIV_T dt23 = pdda->dsX.dt23;
CNTPOS *pcp;
LONG n = pdda->dsX.dt0.lQuo;
prun->cpY.iPos = n;
pcp = &prun->cpX[0];
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
{
DbgPrint("Pumping pel\n");
DbgPrint("N0 = %ld\n", n);
DbgPrint("N1 = %ld\n", pdda->dsX.dt1.lQuo);
DbgPrint("N2 = %ld\n", pdda->dsX.dt2.lQuo);
DbgPrint("N3 = %ld\n", pdda->dsX.dt3.lQuo);
DbgPrint("DDA 01 = %ld, %ld\n", dt01.lQuo, dt01.lRem);
DbgPrint("DDA 02 = %ld, %ld\n", dt02.lQuo, dt02.lRem);
DbgPrint("DDA 13 = %ld, %ld\n", dt13.lQuo, dt13.lRem);
DbgPrint("DDA 23 = %ld, %ld\n", dt23.lQuo, dt23.lRem);
DbgPrint("Step 01 = %ld, %ld, %ld\n",
pdda->dp01.dt.lQuo, pdda->dp01.dt.lRem, pdda->dp01.lDen);
DbgPrint("Step 02 = %ld, %ld, %ld\n",
pdda->dp02.dt.lQuo, pdda->dp02.dt.lRem, pdda->dp02.lDen);
DbgPrint("Step 13 = %ld, %ld, %ld\n",
pdda->dp13.dt.lQuo, pdda->dp13.dt.lRem, pdda->dp13.lDen);
DbgPrint("Step 23 = %ld, %ld, %ld\n",
pdda->dp23.dt.lQuo, pdda->dp23.dt.lRem, pdda->dp23.lDen);
}
#endif
while(n < pdda->dsX.dt1.lQuo)
{
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt01.lQuo, dt02.lQuo);
#endif
if (dt01.lQuo < dt02.lQuo)
{
pcp->iPos = dt01.lQuo;
pcp->cCnt = dt02.lQuo - dt01.lQuo;
}
else
{
pcp->iPos = dt02.lQuo;
pcp->cCnt = dt01.lQuo - dt02.lQuo;
}
prun->cpY.cCnt++;
DDA(&dt01, &pdda->dp01);
DDA(&dt02, &pdda->dp02);
pcp++;
n++;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("Switching LHS to 13\n");
#endif
while(n < pdda->dsX.dt2.lQuo)
{
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt13.lQuo, dt02.lQuo);
#endif
if (dt13.lQuo < dt02.lQuo)
{
pcp->iPos = dt13.lQuo;
pcp->cCnt = dt02.lQuo - dt13.lQuo;
}
else
{
pcp->iPos = dt02.lQuo;
pcp->cCnt = dt13.lQuo - dt02.lQuo;
}
prun->cpY.cCnt++;
DDA(&dt13, &pdda->dp13);
DDA(&dt02, &pdda->dp02);
pcp++;
n++;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("Switching RHS to 23\n");
#endif
while(n < pdda->dsX.dt3.lQuo)
{
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("@ Y = %ld, X0 = %ld, X1 = %ld\n", n, dt13.lQuo, dt23.lQuo);
#endif
if (dt13.lQuo < dt23.lQuo)
{
pcp->iPos = dt13.lQuo;
pcp->cCnt = dt23.lQuo - dt13.lQuo;
}
else
{
pcp->iPos = dt23.lQuo;
pcp->cCnt = dt13.lQuo - dt23.lQuo;
}
prun->cpY.cCnt++;
DDA(&dt13, &pdda->dp13);
DDA(&dt23, &pdda->dp23);
pcp++;
n++;
}
#ifdef DBG_PLGBLT
if (gflPlgBlt & PLGBLT_SHOW_PUMP)
DbgPrint("Done.\n");
#endif
prun->cpY.cCnt = n - prun->cpY.iPos;
// Always put at least one X pair in the list. This handles the BLACKONWHITE
// and WHITEONBLACK compression. Notice that the size of the X run is zero.
if ((pdda->bOverwrite) && (prun->cpY.cCnt == 0))
{
if (dt13.lQuo < dt02.lQuo)
{
pcp->iPos = dt13.lQuo;
pcp->cCnt = dt02.lQuo - dt13.lQuo;
}
else
{
pcp->iPos = dt02.lQuo;
pcp->cCnt = dt13.lQuo - dt02.lQuo;
}
prun->cpY.cCnt = 1;
pcp++;
}
return((PLGRUN *) pcp);
}
static ULONG gaulMaskMono[] =
{
0x00000080, 0x00000040, 0x00000020, 0x00000010,
0x00000008, 0x00000004, 0x00000002, 0x00000001,
0x00008000, 0x00004000, 0x00002000, 0x00001000,
0x00000800, 0x00000400, 0x00000200, 0x00000100,
0x00800000, 0x00400000, 0x00200000, 0x00100000,
0x00080000, 0x00040000, 0x00020000, 0x00010000,
0x80000000, 0x40000000, 0x20000000, 0x10000000,
0x08000000, 0x04000000, 0x02000000, 0x01000000
};
static ULONG gaulMaskQuad[] =
{
0x000000F0, 0x0000000F, 0x0000F000, 0x00000F00,
0x00F00000, 0x000F0000, 0xF0000000, 0x0F000000
};
static ULONG gaulShftQuad[] =
{
0x00000004, 0x00000000, 0x0000000C, 0x00000008,
0x00000014, 0x00000010, 0x0000001C, 0x00000018
};
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead1(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 1BPP surface.
*
* History:
* 12-Feb-1993 -by- Donald Sidoroff [donalds]
* Fixed a LOT of bugs in monochrome sources
*
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead1(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
ULONG *pulMsk;
ULONG *pulSrc;
ULONG ulMsk;
ULONG ulSrc;
ULONG iBlack;
ULONG iWhite;
LONG cLeft;
LONG iLeft;
LONG iMask;
cLeft = xLeft >> 5; // Index of leftmost DWORD
iLeft = xLeft & 31; // Bits used in leftmost DWORD
pulSrc = ((DWORD *) pjSrc) + cLeft; // Adjust base address
ulSrc = *pulSrc;
// To prevent derefences of the XLATE, do it upfront. We can easily do
// this on monochrome bitmaps.
if (pxlo == NULL)
{
iBlack = 0;
iWhite = 1;
}
else
{
iBlack = pxlo->pulXlate[0];
iWhite = pxlo->pulXlate[1];
}
if (pjMask == (BYTE *) NULL)
{
if (xLeft < xRght)
{
while (TRUE)
{
if (ulSrc & gaulMaskMono[iLeft])
prun->iColor = iWhite;
else
prun->iColor = iBlack;
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
xLeft++;
iLeft++;
if (xLeft >= xRght)
break;
if (iLeft & 32)
{
pulSrc++;
ulSrc = *pulSrc;
iLeft = 0;
}
}
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
if (xLeft < xRght)
{
while (TRUE)
{
if (ulMsk & gaulMaskMono[iMask])
{
if (ulSrc & gaulMaskMono[iLeft])
prun->iColor = iWhite;
else
prun->iColor = iBlack;
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
xLeft++;
iLeft++;
iMask++;
if (xLeft >= xRght)
break;
if (iLeft & 32)
{
pulSrc++;
ulSrc = *pulSrc;
iLeft = 0;
}
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
}
return(prun);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead4(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 4BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead4(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
ULONG *pulMsk;
ULONG *pulSrc;
ULONG ulMsk;
ULONG ulSrc;
ULONG iColor;
LONG cLeft;
LONG iLeft;
LONG iMask;
cLeft = xLeft >> 3; // Index of leftmost DWORD
iLeft = xLeft & 7; // Bits used in leftmost DWORD
pulSrc = ((DWORD *) pjSrc) + cLeft; // Adjust base address
ulSrc = *pulSrc;
if (pjMask == (BYTE *) NULL)
{
if (xLeft < xRght)
{
while (TRUE)
{
iColor = (ulSrc & gaulMaskQuad[iLeft]) >> gaulShftQuad[iLeft];
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = pxlo->pulXlate[iColor];
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
xLeft++;
iLeft++;
if (xLeft >= xRght)
break;
if (iLeft & 8)
{
pulSrc++;
ulSrc = *pulSrc;
iLeft = 0;
}
}
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
if (xLeft < xRght)
{
while (TRUE)
{
if (ulMsk & gaulMaskMono[iMask])
{
iColor = (ulSrc & gaulMaskQuad[iLeft]) >> gaulShftQuad[iLeft];
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = pxlo->pulXlate[iColor];
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
xLeft++;
iLeft++;
iMask++;
if (xLeft >= xRght)
break;
if (iLeft & 8)
{
pulSrc++;
ulSrc = *pulSrc;
iLeft = 0;
}
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
}
return(prun);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead8(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 8BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead8(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
ULONG *pulMsk;
ULONG ulMsk;
ULONG iColor;
LONG iMask;
pjSrc += xLeft;
if (pjMask == (BYTE *) NULL)
{
if (pxlo == NULL)
while (xLeft != xRght)
{
prun->iColor = *pjSrc;
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pjSrc++;
xLeft++;
}
else
while (xLeft != xRght)
{
prun->iColor = pxlo->pulXlate[*pjSrc];
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pjSrc++;
xLeft++;
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
while (xLeft != xRght)
{
if (ulMsk & gaulMaskMono[iMask])
{
iColor = *pjSrc;
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = pxlo->pulXlate[iColor];
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
pjSrc++;
xLeft++;
iMask++;
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
return(prun);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead16(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 16BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead16(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
WORD *pwSrc = (WORD *) pjSrc;
ULONG *pulMsk;
ULONG ulMsk;
ULONG iColor;
LONG iMask;
pwSrc += xLeft;
if (pjMask == (BYTE *) NULL)
{
if (pxlo == NULL)
while (xLeft != xRght)
{
prun->iColor = *pwSrc;
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pwSrc++;
xLeft++;
}
else
while (xLeft != xRght)
{
prun->iColor = ((XLATE *) pxlo)->ulTranslate((ULONG) *pwSrc);
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pwSrc++;
xLeft++;
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
while (xLeft != xRght)
{
if (ulMsk & gaulMaskMono[iMask])
{
iColor = *pwSrc;
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
pwSrc++;
xLeft++;
iMask++;
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
return(prun);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead24(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 24BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead24(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
RGBTRIPLE *prgbSrc = (RGBTRIPLE *) pjSrc;
ULONG *pulMsk;
ULONG ulMsk;
ULONG iColor = 0;
LONG iMask;
prgbSrc += xLeft;
if (pjMask == (BYTE *) NULL)
{
if (pxlo == NULL)
while (xLeft != xRght)
{
*((RGBTRIPLE *) &iColor) = *prgbSrc;
prun->iColor = iColor;
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
prgbSrc++;
xLeft++;
}
else
while (xLeft != xRght)
{
*((RGBTRIPLE *) &iColor) = *prgbSrc;
prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
prgbSrc++;
xLeft++;
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
while (xLeft != xRght)
{
if (ulMsk & gaulMaskMono[iMask])
{
*((RGBTRIPLE *) &iColor) = *prgbSrc;
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
prgbSrc++;
xLeft++;
iMask++;
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
return(prun);
}
/******************************Public*Routine******************************\
* PLGRUN *prunPlgRead32(prun, pjSrc, pjMask, pxlo, xLeft, xRght, xMask)
*
* Read the source, mask it, xlate colors and produce a run list
* for a row of a 32BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
PLGRUN *prunPlgRead32(
PLGDDA *pdda,
PLGRUN *prun,
BYTE *pjSrc,
BYTE *pjMask,
XLATEOBJ *pxlo,
LONG xLeft,
LONG xRght,
LONG xMask)
{
DWORD *pdwSrc = (DWORD *) pjSrc;
ULONG *pulMsk;
ULONG ulMsk;
ULONG iColor;
LONG iMask;
pdwSrc += xLeft;
if (pjMask == (BYTE *) NULL)
{
if (pxlo == NULL)
while (xLeft != xRght)
{
prun->iColor = *pdwSrc;
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pdwSrc++;
xLeft++;
}
else
while (xLeft != xRght)
{
prun->iColor = ((XLATE *) pxlo)->ulTranslate(*pdwSrc);
prun = prunPumpDDA(pdda, prun);
vAdvXDDA(pdda);
pdwSrc++;
xLeft++;
}
return(prun);
}
// Compute initial state of mask
pulMsk = ((DWORD *) pjMask) + (xMask >> 5);
iMask = xMask & 31;
ulMsk = *pulMsk;
while (xLeft != xRght)
{
if (ulMsk & gaulMaskMono[iMask])
{
iColor = *pdwSrc;
if (pxlo == NULL)
prun->iColor = iColor;
else
prun->iColor = ((XLATE *) pxlo)->ulTranslate(iColor);
prun = prunPumpDDA(pdda, prun);
}
vAdvXDDA(pdda);
pdwSrc++;
xLeft++;
iMask++;
if (iMask & 32)
{
pulMsk++;
ulMsk = *pulMsk;
iMask = 0;
}
}
return(prun);
}
static BYTE gajMask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
/******************************Public*Routine******************************\
* VOID vPlgWrite1(prun, prunEnd, pSurf, pco)
*
* Write the clipped run list of pels to the target 1BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite1(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
BYTE *pjOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
BYTE jMask;
BYTE jTemp;
BOOL bValid;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor ? (ULONG) -1L : 0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
jTemp = *pjOff;
while (xDist != 0)
{
jTemp = (BYTE) ((jTemp & ~jMask) | (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
*pjOff = jTemp;
pjOff++;
jTemp = *pjOff;
jMask = gajMask[xCurr & 7];
}
}
*pjOff = jTemp;
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
iColor = prun->iColor ? (ULONG) -1L : 0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
jTemp = (BYTE) ((jTemp & ~jMask) | (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
if (bValid)
*pjOff = jTemp;
jMask = gajMask[xCurr & 7];
pjOff++;
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
}
}
if (bValid)
*pjOff = jTemp;
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWrite4(prun, prunEnd, pSurf, pco)
*
* Write the clipped run list of pels to the target 4BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite4(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
BYTE *pjOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
BYTE jMask;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor | (prun->iColor << 4);
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 1);
jMask = (xCurr & 1) ? 0x0F : 0xF0;
while (xDist != 0)
{
*pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
jMask ^= 0xFF;
if (jMask == 0xF0)
pjOff++;
xDist--;
}
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There maybe a single rectangle to clip against.
RECTL rclClip;
if (pco->iDComplexity == DC_RECT)
{
rclClip = pco->rclBounds;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor | (prun->iColor << 4);
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 1);
jMask = (xCurr & 1) ? 0x0F : 0xF0;
while (xDist != 0)
{
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
xDist--;
xCurr++;
jMask ^= 0xFF;
if (jMask == 0xF0)
pjOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is complex clipping. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor | (prun->iColor << 4);
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 1);
jMask = (xCurr & 1) ? 0x0F : 0xF0;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pjOff = (BYTE) ((*pjOff & ~jMask) | (iColor & jMask));
xDist--;
xCurr++;
jMask ^= 0xFF;
if (jMask == 0xF0)
pjOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWrite8(prun, prunEnd, pso, pco)
*
* Write the clipped run list of pels to the target 8BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite8(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
BYTE *pjOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
pjOff = pjBase + pcp->iPos;
xDist = pcp->cCnt;
while (xDist != 0)
{
*pjOff = (BYTE) iColor;
pjOff++;
xDist--;
}
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There maybe a single rectangle to clip against.
RECTL rclClip;
if (pco->iDComplexity == DC_RECT)
{
rclClip = pco->rclBounds;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + xCurr;
while (xDist != 0)
{
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pjOff = (BYTE) iColor;
xDist--;
xCurr++;
pjOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is complex clipping. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + xCurr;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pjOff = (BYTE) iColor;
xDist--;
xCurr++;
pjOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWrite16(prun, prunEnd, pSurf, pco)
*
* Write the clipped run list of pels to the target 16BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite16(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
WORD *pwOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
pwOff = ((WORD *) pjBase) + pcp->iPos;
xDist = pcp->cCnt;
while (xDist != 0)
{
*pwOff = (WORD) iColor;
xDist--;
pwOff++;
}
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pwOff = ((WORD *) pjBase) + xCurr;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pwOff = (WORD) iColor;
xDist--;
xCurr++;
pwOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWrite24(prun, prunEnd, pSurf, pco)
*
* Write the clipped run list of pels to the target 24BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite24(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
RGBTRIPLE *prgbOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
prgbOff = ((RGBTRIPLE *) pjBase) + pcp->iPos;
xDist = pcp->cCnt;
while (xDist != 0)
{
*prgbOff = *((RGBTRIPLE *) &iColor);
prgbOff++;
xDist--;
}
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
prgbOff = ((RGBTRIPLE *) pjBase) + xCurr;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*prgbOff = *((RGBTRIPLE *) &iColor);
xDist--;
xCurr++;
prgbOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWrite32(prun, prunEnd, pSurf, pco)
*
* Write the clipped run list of pels to the target 32BPP surface.
*
* History:
* 08-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWrite32(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
DWORD *pdwOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
pdwOff = ((DWORD *) pjBase) + pcp->iPos;
xDist = pcp->cCnt;
while (xDist != 0)
{
*pdwOff = iColor;
xDist--;
pdwOff++;
}
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
iColor = prun->iColor;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pdwOff = ((DWORD *) pjBase) + xCurr;
while (xDist != 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
*pdwOff = iColor;
xDist--;
xCurr++;
pdwOff++;
}
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWriteAND(prun, prunEnd, pSurf, pco)
*
* AND the clipped run list of pels to the target 1BPP surface. This can
* be made much faster by noting that ANDing with 1's is a NOP.
*
* History:
* 25-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWriteAND(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
BYTE *pjOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
BYTE jMask;
BYTE jTemp;
BOOL bValid;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor == 0 ? ~0L : 0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
jTemp = *pjOff;
while (xDist >= 0)
{
jTemp &= ~((BYTE) (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
*pjOff = jTemp;
pjOff++;
jTemp = *pjOff;
jMask = gajMask[xCurr & 7];
}
}
*pjOff = jTemp;
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
iColor = prun->iColor == 0 ? ~0L : 0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
while (xDist >= 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
jTemp &= ~((BYTE) (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
if (bValid)
*pjOff = jTemp;
pjOff++;
jMask = gajMask[xCurr & 7];
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
}
}
if (bValid)
*pjOff = jTemp;
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}
/******************************Public*Routine******************************\
* VOID vPlgWriteOR(prun, prunEnd, pso, pco)
*
* OR the clipped run list of pels to the target 1BPP surface. This can
* be much faster by noting that ORing with 0's is a NOP.
*
* History:
* 25-Aug-1992 -by- Donald Sidoroff [donalds]
* Wrote it.
\**************************************************************************/
VOID vPlgWriteOR(
PLGRUN *prun,
PLGRUN *prunEnd,
SURFACE *pSurf,
CLIPOBJ *pco)
{
BYTE *pjBase;
BYTE *pjOff;
CNTPOS *pcp;
ULONG iColor;
LONG yCurr;
LONG yDist;
LONG xCurr;
LONG xDist;
BYTE jMask;
BYTE jTemp;
BOOL bValid;
// See if this can be handled without clipping.
if (pco == (CLIPOBJ *) NULL)
{
while (prun != prunEnd)
{
iColor = prun->iColor == 0 ? 0L : ~0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
jTemp = *pjOff;
while (xDist >= 0)
{
jTemp |= ((BYTE) (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
*pjOff = jTemp;
pjOff++;
jTemp = *pjOff;
jMask = gajMask[xCurr & 7];
}
}
*pjOff = jTemp;
pjBase += pSurf->lDelta();
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
return;
}
// There is a clip region. Set up the clipping code.
((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, CD_ANY, 100);
RECTL rclClip;
rclClip.left = POS_INFINITY;
rclClip.top = POS_INFINITY;
rclClip.right = NEG_INFINITY;
rclClip.bottom = NEG_INFINITY;
while (prun != prunEnd)
{
iColor = prun->iColor == 0 ? 0L : ~0L;
yCurr = prun->cpY.iPos;
yDist = prun->cpY.cCnt;
pjBase = (BYTE *) pSurf->pvScan0() + pSurf->lDelta() * yCurr;
pcp = &prun->cpX[0];
while (yDist != 0)
{
if ((yCurr < rclClip.top) || (yCurr >= rclClip.bottom))
((ECLIPOBJ *) pco)->vFindScan(&rclClip, yCurr);
if ((yCurr >= rclClip.top) && (yCurr < rclClip.bottom))
{
xCurr = pcp->iPos;
xDist = pcp->cCnt;
pjOff = pjBase + (xCurr >> 3);
jMask = gajMask[xCurr & 7];
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
while (xDist >= 0)
{
if ((xCurr < rclClip.left) || (xCurr >= rclClip.right))
((ECLIPOBJ *) pco)->vFindSegment(&rclClip, xCurr, yCurr);
if ((xCurr >= rclClip.left) && (xCurr < rclClip.right))
jTemp |= ((BYTE) (iColor & jMask));
xDist--;
xCurr++;
jMask >>= 1;
if (jMask == (BYTE) 0)
{
if (bValid)
*pjOff = jTemp;
pjOff++;
jMask = gajMask[xCurr & 7];
bValid = ((xCurr >= 0) && (xCurr < pSurf->sizl().cx));
jTemp = bValid ? *pjOff : (BYTE) 0;
}
}
if (bValid)
*pjOff = jTemp;
}
pjBase += pSurf->lDelta();
yCurr++;
yDist--;
pcp++;
}
prun = (PLGRUN *) pcp;
}
}