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.
514 lines
15 KiB
514 lines
15 KiB
/******************************Module*Header*******************************\
|
|
*
|
|
* $Workfile: STROKE.C $
|
|
*
|
|
* Handle DrvStrokePath routine.
|
|
*
|
|
* Copyright (c) 1992-1995 Microsoft Corporation
|
|
* Copyright (c) 1997 Cirrus Logic, Inc.
|
|
*
|
|
* $Log: X:/log/laguna/nt35/displays/cl546x/STROKE.C $
|
|
*
|
|
* Rev 1.17 Mar 04 1998 15:35:34 frido
|
|
* Added new shadow macros.
|
|
*
|
|
* Rev 1.16 Nov 03 1997 10:20:44 frido
|
|
* Added REQUIRE macros.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
#include "precomp.h"
|
|
#define STROKE_DBG_LEVEL 1
|
|
|
|
#if LOG_CALLS
|
|
void LogStrokePath(
|
|
ULONG acc,
|
|
PPDEV ppdev,
|
|
CLIPOBJ* pco,
|
|
BRUSHOBJ* pbo,
|
|
MIX mix,
|
|
LINEATTRS* pla,
|
|
PATHOBJ* ppo
|
|
);
|
|
#else
|
|
#define LogStrokePath(acc, ppdev, pco, pbo, mix, pla, ppo)
|
|
#endif
|
|
|
|
VOID (*gapfnStrip[])(PDEV*, STRIP*, LINESTATE*) = {
|
|
vrlSolidHorizontal,
|
|
vrlSolidVertical,
|
|
NULL,
|
|
NULL,
|
|
|
|
// Should be NUM_STRIP_DRAW_DIRECTIONS = 4 strip drawers in every group
|
|
|
|
vrlSolidHorizontal,
|
|
vrlSolidVertical,
|
|
NULL,
|
|
NULL,
|
|
|
|
// Should be NUM_STRIP_DRAW_STYLES = 8 strip drawers in total for doing
|
|
// solid lines, and the same number for non-solid lines:
|
|
|
|
vStripStyledHorizontal,
|
|
vStripStyledVertical,
|
|
NULL, // Diagonal goes here
|
|
NULL, // Diagonal goes here
|
|
|
|
vStripStyledHorizontal,
|
|
vStripStyledVertical,
|
|
NULL, // Diagonal goes here
|
|
NULL, // Diagonal goes here
|
|
};
|
|
|
|
// Style array for alternate style (alternates one pixel on, one pixel off):
|
|
|
|
STYLEPOS gaspAlternateStyle[] = { 1 };
|
|
|
|
extern BYTE Rop2ToRop3[];
|
|
|
|
USHORT mixToBLTDEF[] =
|
|
{
|
|
0x1000, //0 R2_WHITE 1
|
|
0x1000, //1 R2_BLACK 0
|
|
0x1107, //2 DPon
|
|
0x1107, //3 DPna
|
|
0x1007, //4 PN
|
|
0x1107, //5 PDna
|
|
0x1100, //6 Dn
|
|
0x1107, //7 DPx
|
|
0x1107, //8 DPan
|
|
0x1107, //9 DPa
|
|
0x1107, //A DPxn
|
|
0x1100, //B D
|
|
0x1107, //C DPno
|
|
0x1007, //D P
|
|
0x1107, //E PDno
|
|
0x1107, //F DPo
|
|
};
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrush, pla, mix)
|
|
*
|
|
* Strokes the path.
|
|
*
|
|
\**************************************************************************/
|
|
BOOL DrvStrokePath(
|
|
SURFOBJ* pso,
|
|
PATHOBJ* ppo,
|
|
CLIPOBJ* pco,
|
|
XFORMOBJ* pxo,
|
|
BRUSHOBJ* pbo,
|
|
POINTL* pptlBrush,
|
|
LINEATTRS* pla,
|
|
MIX mix)
|
|
{
|
|
STYLEPOS aspLtoR[STYLE_MAX_COUNT];
|
|
STYLEPOS aspRtoL[STYLE_MAX_COUNT];
|
|
LINESTATE ls;
|
|
PFNSTRIP* apfn;
|
|
FLONG fl;
|
|
PDEV* ppdev;
|
|
RECTL arclClip[4]; // For rectangular clipping
|
|
DWORD color;
|
|
|
|
#if NULL_STROKE
|
|
{
|
|
if (pointer_switch) return(TRUE);
|
|
}
|
|
#endif
|
|
|
|
DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Entry %x.\n", mix));
|
|
ppdev = (PDEV*) pso->dhpdev;
|
|
|
|
SYNC_W_3D(ppdev);
|
|
|
|
if (pso->iType == STYPE_DEVBITMAP)
|
|
{
|
|
PDSURF pdsurf = (PDSURF) pso->dhsurf;
|
|
if ( pdsurf->pso && !bCreateScreenFromDib(ppdev, pdsurf) )
|
|
{
|
|
LogStrokePath(4,ppdev, pco, pbo, mix, pla, ppo);
|
|
return(EngStrokePath(pdsurf->pso, ppo, pco, pxo, pbo,
|
|
pptlBrush, pla, mix));
|
|
}
|
|
ppdev->ptlOffset = pdsurf->ptl;
|
|
}
|
|
else
|
|
{
|
|
ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
|
|
}
|
|
// Convert to 3 OP ROP
|
|
ppdev->uRop = Rop2ToRop3[mix & 0xF];
|
|
ppdev->uBLTDEF = mixToBLTDEF[mix & 0x0F];
|
|
|
|
//
|
|
// Get the device ready:
|
|
//
|
|
ASSERTMSG(pbo,"Null brush in SrvStrokePath!\n");
|
|
color = pbo->iSolidColor; // & 0x00000000FF; // Clear upper 24 bits.
|
|
ASSERTMSG((color !=0xFFFFFFFF),"DrvStrokePath got a Pattern!\n");
|
|
|
|
switch (ppdev->ulBitCount)
|
|
{
|
|
case 8: // For 8 bpp duplicate byte 0 into bytes 1,2,3.
|
|
color = (color << 8) | (color & 0xFF);
|
|
|
|
case 16: // For 16 bpp, duplicate the low word into the high word.
|
|
color = ((color << 16) | (color & 0xFFFF));
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Set Color %x.\n", color));
|
|
REQUIRE(2);
|
|
LL_BGCOLOR(color, 2);
|
|
|
|
fl = 0;
|
|
|
|
// Check line style.
|
|
if (pla->fl & LA_ALTERNATE)
|
|
{
|
|
ls.cStyle = 1;
|
|
ls.spTotal = 1;
|
|
ls.spTotal2 = 2;
|
|
ls.spRemaining = 1;
|
|
ls.aspRtoL = &gaspAlternateStyle[0];
|
|
ls.aspLtoR = &gaspAlternateStyle[0];
|
|
ls.spNext = HIWORD(pla->elStyleState.l);
|
|
ls.xyDensity = 1;
|
|
fl |= FL_STYLED;
|
|
ls.ulStartMask = 0L;
|
|
}
|
|
|
|
// Is it styled or solid?
|
|
else if (pla->pstyle != (FLOAT_LONG*) NULL)
|
|
{
|
|
// Styled.
|
|
|
|
PFLOAT_LONG pstyle;
|
|
STYLEPOS* pspDown;
|
|
STYLEPOS* pspUp;
|
|
|
|
pstyle = &pla->pstyle[pla->cstyle];
|
|
|
|
ls.xyDensity = STYLE_DENSITY;
|
|
ls.spTotal = 0;
|
|
while (pstyle-- > pla->pstyle)
|
|
{
|
|
ls.spTotal += pstyle->l;
|
|
}
|
|
ls.spTotal *= STYLE_DENSITY;
|
|
ls.spTotal2 = 2 * ls.spTotal;
|
|
|
|
// Compute starting style position
|
|
// (this is guaranteed not to overflow):
|
|
|
|
ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY +
|
|
LOWORD(pla->elStyleState.l);
|
|
|
|
fl |= FL_STYLED;
|
|
ls.cStyle = pla->cstyle;
|
|
ls.aspRtoL = aspRtoL;
|
|
ls.aspLtoR = aspLtoR;
|
|
|
|
if (pla->fl & LA_STARTGAP)
|
|
ls.ulStartMask = 0xffffffffL;
|
|
else
|
|
ls.ulStartMask = 0L;
|
|
|
|
pstyle = pla->pstyle;
|
|
pspDown = &ls.aspRtoL[ls.cStyle - 1];
|
|
pspUp = &ls.aspLtoR[0];
|
|
|
|
while (pspDown >= &ls.aspRtoL[0])
|
|
{
|
|
*pspDown = pstyle->l * STYLE_DENSITY;
|
|
*pspUp = *pspDown;
|
|
|
|
pspUp++;
|
|
pspDown--;
|
|
pstyle++;
|
|
}
|
|
}
|
|
|
|
apfn = &gapfnStrip[NUM_STRIP_DRAW_STYLES *
|
|
((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT)];
|
|
|
|
// Set up to enumerate the path:
|
|
|
|
if (pco->iDComplexity != DC_COMPLEX)
|
|
{
|
|
PATHDATA pd;
|
|
RECTL* prclClip = (RECTL*) NULL;
|
|
BOOL bMore;
|
|
ULONG cptfx;
|
|
POINTFIX ptfxStartFigure;
|
|
POINTFIX ptfxLast;
|
|
POINTFIX* pptfxFirst;
|
|
POINTFIX* pptfxBuf;
|
|
|
|
if (pco->iDComplexity == DC_RECT)
|
|
{
|
|
fl |= FL_SIMPLE_CLIP;
|
|
|
|
arclClip[0] = pco->rclBounds;
|
|
|
|
// FL_FLIP_D:
|
|
|
|
arclClip[1].top = pco->rclBounds.left;
|
|
arclClip[1].left = pco->rclBounds.top;
|
|
arclClip[1].bottom = pco->rclBounds.right;
|
|
arclClip[1].right = pco->rclBounds.bottom;
|
|
|
|
// FL_FLIP_V:
|
|
|
|
arclClip[2].top = -pco->rclBounds.bottom + 1;
|
|
arclClip[2].left = pco->rclBounds.left;
|
|
arclClip[2].bottom = -pco->rclBounds.top + 1;
|
|
arclClip[2].right = pco->rclBounds.right;
|
|
|
|
// FL_FLIP_V | FL_FLIP_D:
|
|
|
|
arclClip[3].top = pco->rclBounds.left;
|
|
arclClip[3].left = -pco->rclBounds.bottom + 1;
|
|
arclClip[3].bottom = pco->rclBounds.right;
|
|
arclClip[3].right = -pco->rclBounds.top + 1;
|
|
|
|
prclClip = arclClip;
|
|
} // End DC_RECT
|
|
|
|
pd.flags = 0;
|
|
|
|
do {
|
|
bMore = PATHOBJ_bEnum(ppo, &pd);
|
|
|
|
cptfx = pd.count;
|
|
if (cptfx == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (pd.flags & PD_BEGINSUBPATH)
|
|
{
|
|
ptfxStartFigure = *pd.pptfx;
|
|
pptfxFirst = pd.pptfx;
|
|
pptfxBuf = pd.pptfx + 1;
|
|
cptfx--;
|
|
}
|
|
else
|
|
{
|
|
pptfxFirst = &ptfxLast;
|
|
pptfxBuf = pd.pptfx;
|
|
}
|
|
|
|
if (pd.flags & PD_RESETSTYLE)
|
|
ls.spNext = 0;
|
|
|
|
if (cptfx > 0)
|
|
{
|
|
if (!bLines(ppdev,
|
|
pptfxFirst,
|
|
pptfxBuf,
|
|
(RUN*) NULL,
|
|
cptfx,
|
|
&ls,
|
|
prclClip,
|
|
apfn,
|
|
fl))
|
|
{
|
|
LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
ptfxLast = pd.pptfx[pd.count - 1];
|
|
|
|
if (pd.flags & PD_CLOSEFIGURE)
|
|
{
|
|
if (!bLines(ppdev,
|
|
&ptfxLast,
|
|
&ptfxStartFigure,
|
|
(RUN*) NULL,
|
|
1,
|
|
&ls,
|
|
prclClip,
|
|
apfn,
|
|
fl))
|
|
{
|
|
LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
} while (bMore);
|
|
|
|
if (fl & FL_STYLED)
|
|
{
|
|
// Save the style state:
|
|
|
|
ULONG ulHigh;
|
|
ULONG ulLow;
|
|
|
|
// Masked styles don't normalize the style state. It's a good
|
|
// thing to do, so let's do it now:
|
|
|
|
if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2)
|
|
ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2;
|
|
|
|
ulHigh = ls.spNext / ls.xyDensity;
|
|
ulLow = ls.spNext % ls.xyDensity;
|
|
|
|
pla->elStyleState.l = MAKELONG(ulLow, ulHigh);
|
|
}
|
|
} // End non complex clipping.
|
|
|
|
else // clipping is DC_COMPLEX
|
|
{
|
|
// Local state for path enumeration:
|
|
|
|
BOOL bMore;
|
|
union {
|
|
BYTE aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)];
|
|
CLIPLINE cl;
|
|
} cl;
|
|
|
|
fl |= FL_COMPLEX_CLIP;
|
|
|
|
// We use the clip object when non-simple clipping is involved:
|
|
|
|
PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla);
|
|
|
|
do {
|
|
bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl);
|
|
if (cl.cl.c != 0)
|
|
{
|
|
if (fl & FL_STYLED)
|
|
{
|
|
ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity
|
|
+ LOWORD(cl.cl.lStyleState);
|
|
}
|
|
if (!bLines(ppdev,
|
|
&cl.cl.ptfxA,
|
|
&cl.cl.ptfxB,
|
|
&cl.cl.arun[0],
|
|
cl.cl.c,
|
|
&ls,
|
|
(RECTL*) NULL,
|
|
apfn,
|
|
fl))
|
|
{
|
|
LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
} while (bMore);
|
|
}
|
|
|
|
DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Exit.\n"));
|
|
|
|
LogStrokePath(0, ppdev, pco, pbo, mix, pla, ppo);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
#if LOG_CALLS
|
|
|
|
extern long lg_i;
|
|
extern char lg_buf[256];
|
|
|
|
void LogStrokePath(
|
|
ULONG acc,
|
|
PPDEV ppdev,
|
|
CLIPOBJ* pco,
|
|
BRUSHOBJ* pbo,
|
|
MIX mix,
|
|
LINEATTRS* pla,
|
|
PATHOBJ* ppo
|
|
)
|
|
{
|
|
BYTE iDComplexity;
|
|
|
|
#if ENABLE_LOG_SWITCH
|
|
if (pointer_switch == 0) return;
|
|
#endif
|
|
|
|
lg_i = sprintf(lg_buf,"DSP: ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
// Did we realize it? If not, why?
|
|
switch (acc)
|
|
{
|
|
case 0: lg_i = sprintf(lg_buf,"(ACCL) "); break;
|
|
case 2: lg_i = sprintf(lg_buf,"(Punt - bLines failed) "); break;
|
|
case 3: lg_i = sprintf(lg_buf,"(Punt - S3) "); break;
|
|
case 4: lg_i = sprintf(lg_buf,"(Punt - DevBmp on host) "); break;
|
|
default: lg_i = sprintf(lg_buf,"(STATUS UNKNOWN) "); break;
|
|
}
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
//
|
|
// Check the type of clipping.
|
|
//
|
|
iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
|
|
lg_i = sprintf(lg_buf,"C=%s ",
|
|
(iDComplexity==DC_TRIVIAL ? "T":
|
|
(iDComplexity == DC_RECT ? "R" : "C" )));
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
|
|
//
|
|
// Check the brush
|
|
//
|
|
if (pbo)
|
|
if (pbo->iSolidColor == 0xFFFFFFFF )
|
|
lg_i = sprintf(lg_buf,"BR=P ");
|
|
else
|
|
lg_i = sprintf(lg_buf,"BR=0x%X ",(pbo->iSolidColor));
|
|
else
|
|
lg_i = sprintf(lg_buf,"BR=N ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
//
|
|
// Check the MIX
|
|
//
|
|
lg_i = sprintf(lg_buf,"MIX = 0x%04X ", mix);
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
//
|
|
// Check the Line Attrs
|
|
//
|
|
if (pla->fl & LA_GEOMETRIC) lg_i = sprintf(lg_buf,"LA=G ");
|
|
else if (pla->fl & LA_ALTERNATE) lg_i = sprintf(lg_buf,"LA=A ");
|
|
else if (pla->fl & LA_STARTGAP) lg_i = sprintf(lg_buf,"LA=S ");
|
|
else lg_i = sprintf(lg_buf,"LA=U ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
|
|
if (pla->iJoin == JOIN_ROUND) lg_i = sprintf(lg_buf,"J=R ");
|
|
else if (pla->iJoin == JOIN_BEVEL) lg_i = sprintf(lg_buf,"J=B ");
|
|
else if (pla->iJoin == JOIN_MITER) lg_i = sprintf(lg_buf,"J=M ");
|
|
else lg_i = sprintf(lg_buf,"J=U ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
|
|
if (pla->iEndCap == ENDCAP_ROUND) lg_i = sprintf(lg_buf,"E=R ");
|
|
else if (pla->iEndCap == ENDCAP_SQUARE) lg_i = sprintf(lg_buf,"E=S ");
|
|
else if (pla->iEndCap == ENDCAP_BUTT) lg_i = sprintf(lg_buf,"E=B ");
|
|
else lg_i = sprintf(lg_buf,"E=U ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
|
|
if (pla->pstyle == NULL) lg_i = sprintf(lg_buf,"SOLID ");
|
|
else lg_i = sprintf(lg_buf,"STYLED ");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
|
|
lg_i = sprintf(lg_buf,"\r\n");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
}
|
|
#endif
|