mirror of https://github.com/lianthony/NT4.0
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.
440 lines
12 KiB
440 lines
12 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: paintddi.cxx
|
|
*
|
|
* DDA callbacks
|
|
*
|
|
* Created: 05-Mar-1992 18:30:39
|
|
* Author: Donald Sidoroff [donalds]
|
|
*
|
|
* Copyright (c) 1992 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
extern ULONG aulShiftFormat[];
|
|
extern ULONG aulMulFormat[];
|
|
|
|
PFN_PATBLT apfnPatRect[][3] =
|
|
{
|
|
{ NULL, NULL, NULL },
|
|
{ NULL, NULL, NULL },
|
|
{ NULL, NULL, NULL },
|
|
{ vPatCpyRect8, vPatNotRect8, vPatXorRect8 },
|
|
{ vPatCpyRect8, vPatNotRect8, vPatXorRect8 },
|
|
{ vPatCpyRect8, vPatNotRect8, vPatXorRect8 },
|
|
{ vPatCpyRect8, vPatNotRect8, vPatXorRect8 }
|
|
};
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vPaintRgn
|
|
*
|
|
* Paint the clipping region with the specified color and mode
|
|
*
|
|
* History:
|
|
* 05-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vPaintRgn(
|
|
SURFACE *pSurf,
|
|
CLIPOBJ *pco,
|
|
ULONG iColor,
|
|
BOOL bXor)
|
|
{
|
|
PFN_SOLIDBLT pfnRect;
|
|
CLIPENUMRECT clenr;
|
|
BYTE *pjBits = (BYTE *) pSurf->pvScan0();
|
|
LONG lDelta = pSurf->lDelta();
|
|
ULONG cShift;
|
|
ULONG iRT;
|
|
BOOL bMore;
|
|
BOOL bBanked = pco->fjOptions & OC_BANK_CLIP;
|
|
|
|
// Get the shift for the format
|
|
|
|
cShift = aulShiftFormat[pSurf->iFormat()];
|
|
|
|
// Promote the color to 32 bits
|
|
|
|
switch(pSurf->iFormat())
|
|
{
|
|
case BMF_1BPP:
|
|
|
|
if (iColor)
|
|
iColor = 0xFFFFFFFF;
|
|
break;
|
|
|
|
case BMF_4BPP:
|
|
|
|
iColor = iColor | (iColor << 4);
|
|
|
|
case BMF_8BPP:
|
|
|
|
iColor = iColor | (iColor << 8);
|
|
|
|
case BMF_16BPP:
|
|
|
|
iColor = iColor | (iColor << 16);
|
|
}
|
|
|
|
if (bXor)
|
|
if (pSurf->iFormat() == BMF_24BPP)
|
|
pfnRect = vSolidXorRect24;
|
|
else
|
|
pfnRect = vSolidXorRect1;
|
|
else
|
|
if (pSurf->iFormat() == BMF_24BPP)
|
|
pfnRect = vSolidFillRect24;
|
|
else
|
|
pfnRect = vSolidFillRect1;
|
|
|
|
// Enumerate all the rectangles and draw them
|
|
|
|
((ECLIPOBJ *) pco)->cEnumStart(FALSE,CT_RECTANGLES,CD_ANY,CLIPOBJ_ENUM_LIMIT);
|
|
|
|
do {
|
|
bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr), (PVOID) &clenr);
|
|
|
|
if (bBanked)
|
|
{
|
|
for (iRT = 0; iRT < clenr.c; iRT++)
|
|
{
|
|
if (clenr.arcl[iRT].left < pco->rclBounds.left)
|
|
clenr.arcl[iRT].left = pco->rclBounds.left;
|
|
|
|
if (clenr.arcl[iRT].top < pco->rclBounds.top)
|
|
clenr.arcl[iRT].top = pco->rclBounds.top;
|
|
|
|
if (clenr.arcl[iRT].right > pco->rclBounds.right)
|
|
clenr.arcl[iRT].right = pco->rclBounds.right;
|
|
|
|
if (clenr.arcl[iRT].bottom > pco->rclBounds.bottom)
|
|
clenr.arcl[iRT].bottom = pco->rclBounds.bottom;
|
|
|
|
if ((clenr.arcl[iRT].left >= clenr.arcl[iRT].right) ||
|
|
(clenr.arcl[iRT].top >= clenr.arcl[iRT].bottom))
|
|
continue;
|
|
|
|
(*pfnRect)(
|
|
&clenr.arcl[iRT],
|
|
1,
|
|
pjBits,
|
|
lDelta,
|
|
iColor,
|
|
cShift);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
(*pfnRect)(
|
|
clenr.arcl,
|
|
clenr.c,
|
|
pjBits,
|
|
lDelta,
|
|
iColor,
|
|
cShift);
|
|
|
|
|
|
}
|
|
} while (bMore);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vBrushRgn
|
|
*
|
|
* Paint the clipping region with the specified brush and mode
|
|
*
|
|
* History:
|
|
* 05-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vBrushRgn(
|
|
SURFACE *pSurf,
|
|
CLIPOBJ *pco,
|
|
BRUSHOBJ *pbo,
|
|
POINTL *pptl,
|
|
ULONG iMode)
|
|
{
|
|
PFN_PATBLT pfnPat;
|
|
PATBLTFRAME pbf;
|
|
CLIPENUMRECT clenr;
|
|
ULONG iRT;
|
|
BOOL bMore;
|
|
|
|
// Get the multiplier for the format
|
|
|
|
pbf.cMul = aulMulFormat[pSurf->iFormat()];
|
|
pbf.pvTrg = pSurf->pvScan0();
|
|
pbf.lDeltaTrg = pSurf->lDelta();
|
|
pbf.pvPat = (PVOID) ((EBRUSHOBJ *) pbo)->pengbrush()->pjPat;
|
|
pbf.lDeltaPat = ((EBRUSHOBJ *) pbo)->pengbrush()->lDeltaPat;
|
|
pbf.cxPat = ((EBRUSHOBJ *) pbo)->pengbrush()->cxPat * pbf.cMul;
|
|
pbf.cyPat = ((EBRUSHOBJ *) pbo)->pengbrush()->cyPat;
|
|
pbf.xPat = pptl->x * pbf.cMul;
|
|
pbf.yPat = pptl->y;
|
|
|
|
if (pbf.xPat < 0)
|
|
pbf.xPat = pbf.cxPat - (-pbf.xPat % pbf.cxPat);
|
|
|
|
if (pbf.yPat < 0)
|
|
pbf.yPat = pbf.cyPat - (-pbf.yPat % pbf.cyPat);
|
|
|
|
pfnPat = apfnPatRect[pSurf->iFormat()][iMode];
|
|
|
|
// Handle the single rectangle case
|
|
|
|
if (pco->iDComplexity == DC_RECT)
|
|
{
|
|
pbf.pvObj = (PVOID) &pco->rclBounds;
|
|
(*pfnPat)(&pbf);
|
|
return;
|
|
}
|
|
|
|
// Enumerate all the rectangles and draw them
|
|
|
|
((ECLIPOBJ *) pco)->cEnumStart(FALSE,CT_RECTANGLES,CD_ANY,CLIPOBJ_ENUM_LIMIT);
|
|
|
|
do {
|
|
bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr), (PVOID) &clenr);
|
|
|
|
for (iRT = 0; iRT < clenr.c; iRT++)
|
|
{
|
|
pbf.pvObj = (PVOID) &clenr.arcl[iRT];
|
|
(*pfnPat)(&pbf);
|
|
}
|
|
} while (bMore);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vBrushRgnN_8x8
|
|
*
|
|
* Paint the clipping region with the specified brush and mode for 8x8
|
|
* patterns.
|
|
*
|
|
* History:
|
|
* 19-Nov-1992 Michael Abrash [mikeab]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vBrushRgnN_8x8(
|
|
SURFACE *pSurf,
|
|
CLIPOBJ *pco,
|
|
BRUSHOBJ *pbo,
|
|
POINTL *pptlBrush,
|
|
PFN_PATBLT2 pfnPat)
|
|
{
|
|
PATBLTFRAME pbf;
|
|
CLIPENUMRECT clenr;
|
|
BOOL bMore;
|
|
|
|
pbf.pvTrg = pSurf->pvScan0();
|
|
pbf.lDeltaTrg = pSurf->lDelta();
|
|
pbf.pvPat = (PVOID) ((EBRUSHOBJ *) pbo)->pengbrush()->pjPat;
|
|
|
|
// Force the X and Y pattern origin coordinates into the ranges 0-7 and 0-7,
|
|
// so we don't have to do modulo arithmetic all over again at a lower level
|
|
|
|
pbf.xPat = pptlBrush->x & 0x07;
|
|
pbf.yPat = pptlBrush->y & 0x07;
|
|
|
|
if (pco->iDComplexity == DC_RECT)
|
|
{
|
|
pbf.pvObj = (PVOID) &pco->rclBounds;
|
|
(*pfnPat)(&pbf, 1);
|
|
|
|
return;
|
|
}
|
|
|
|
((ECLIPOBJ *) pco)->cEnumStart(FALSE,
|
|
CT_RECTANGLES,
|
|
CD_ANY,
|
|
CLIPOBJ_ENUM_LIMIT);
|
|
|
|
do
|
|
{
|
|
|
|
// Get the next batch of rectangles in the clip region
|
|
|
|
bMore =
|
|
((ECLIPOBJ *) pco)->bEnum(sizeof(clenr), (PVOID) &clenr);
|
|
|
|
// If there are any rectangles in this enumeration, clip the
|
|
// destination rectangle to each clip region rectangle, then
|
|
// fill all the rectangles at once
|
|
|
|
if (clenr.c > 0)
|
|
{
|
|
|
|
// Draw the rectangles
|
|
|
|
pbf.pvObj = (PVOID) clenr.arcl;
|
|
(*pfnPat)(&pbf, (INT) clenr.c);
|
|
}
|
|
|
|
} while (bMore);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngPaint
|
|
*
|
|
* Paint the clipping region with the specified brush
|
|
*
|
|
* History:
|
|
* 05-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* add accelerators for common mix modes.
|
|
*
|
|
* Sat 07-Sep-1991 -by- Patrick Haluptzok [patrickh]
|
|
* add translate of mix to rop
|
|
*
|
|
* 01-Apr-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL EngPaint(
|
|
SURFOBJ *pso,
|
|
CLIPOBJ *pco,
|
|
BRUSHOBJ *pdbrush,
|
|
POINTL *pptlBrush,
|
|
MIX mix)
|
|
{
|
|
PSURFACE pSurf = SURFOBJ_TO_SURFACE(pso);
|
|
|
|
ASSERTGDI(pco != (CLIPOBJ *) NULL, "EngPaint - NULL CLIPOBJ\n");
|
|
ASSERTGDI(pco->iMode == TC_RECTANGLES,"EngPaint - iMode not rects\n");
|
|
ASSERTGDI(mix & 0xff00, "Background mix uninitialized");
|
|
|
|
ROP4 rop4 = gaMix[(mix >> 8) & 0x0F];
|
|
rop4 = rop4 << 8;
|
|
rop4 = rop4 | ((ULONG) gaMix[mix & 0x0F]);
|
|
|
|
if (pso->iType == STYPE_BITMAP)
|
|
{
|
|
// Synchronize with the device driver before drawing on the device surface.
|
|
|
|
if (pSurf->flags() & HOOK_SYNCHRONIZE)
|
|
{
|
|
PDEVOBJ po(pSurf->hdev());
|
|
|
|
(po.pfnSync())(pso->dhpdev,&pco->rclBounds);
|
|
}
|
|
|
|
switch (rop4)
|
|
{
|
|
case 0x0000: // Black
|
|
vPaintRgn(pSurf, pco, 0, FALSE);
|
|
return(TRUE);
|
|
|
|
case 0x0F0F: // Pn
|
|
if (pdbrush->iSolidColor != 0xFFFFFFFF)
|
|
{
|
|
vPaintRgn(pSurf, pco, ~pdbrush->iSolidColor, FALSE);
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pSurf->iFormat() >= BMF_8BPP)
|
|
{
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
|
|
{
|
|
vBrushRgn(pSurf, pco, pdbrush, pptlBrush, DPA_PATNOT);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x5555: // Dn
|
|
vPaintRgn(pSurf, pco, (ULONG)~0, TRUE);
|
|
return(TRUE);
|
|
|
|
case 0x5A5A: // DPx
|
|
if (pdbrush->iSolidColor != 0xFFFFFFFF)
|
|
{
|
|
vPaintRgn(pSurf, pco, pdbrush->iSolidColor, TRUE);
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pSurf->iFormat() >= BMF_8BPP)
|
|
{
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
|
|
{
|
|
vBrushRgn(pSurf, pco, pdbrush, pptlBrush, DPA_PATXOR);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xAAAA: // D
|
|
return(TRUE);
|
|
|
|
case 0xF0F0: // P
|
|
if (pdbrush->iSolidColor != 0xFFFFFFFF)
|
|
{
|
|
vPaintRgn(pSurf, pco, pdbrush->iSolidColor, FALSE);
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pSurf->iFormat() == BMF_4BPP)
|
|
{
|
|
|
|
// We only support 8x8 DIB4 patterns with SRCCOPY right now
|
|
|
|
if (pvGetEngRbrush(pdbrush) != NULL)
|
|
{
|
|
if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
|
|
(((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8))
|
|
{
|
|
vBrushRgnN_8x8(pSurf, pco, pdbrush, pptlBrush,
|
|
(PFN_PATBLT2)vPatCpyRect4_8x8);
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pSurf->iFormat() >= BMF_8BPP)
|
|
{
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
|
|
{
|
|
vBrushRgn(pSurf, pco, pdbrush, pptlBrush, DPA_PATCOPY);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 0xFFFF: // White
|
|
vPaintRgn(pSurf, pco, (ULONG)~0, FALSE);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
// Inc the target surface uniqueness
|
|
|
|
INC_SURF_UNIQ(pSurf);
|
|
|
|
return(pSurf->pfnBitBlt())
|
|
(
|
|
(SURFOBJ *) pso,
|
|
(SURFOBJ *) NULL,
|
|
(SURFOBJ *) NULL,
|
|
pco,
|
|
NULL,
|
|
(RECTL *) &(((ECLIPOBJ *) pco)->erclExclude()),
|
|
(POINTL *) NULL,
|
|
(POINTL *) NULL,
|
|
pdbrush,
|
|
pptlBrush,
|
|
rop4
|
|
);
|
|
}
|