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