224 lines
6.1 KiB
C
224 lines
6.1 KiB
C
/******************************Module*Header*******************************\
|
||
* Module Name: paint.c
|
||
*
|
||
* Copyright (c) 1992 Microsoft Corporation
|
||
\**************************************************************************/
|
||
|
||
#include "driver.h"
|
||
|
||
/******************************Public*Data*********************************\
|
||
* MIX translation table
|
||
*
|
||
* Translates a mix 1-16, into an old style Rop 0-255.
|
||
*
|
||
\**************************************************************************/
|
||
|
||
BYTE gaMix[] =
|
||
{
|
||
0xFF, // R2_WHITE - Allow rop = gaMix[mix & 0x0F]
|
||
0x00, // R2_BLACK
|
||
0x05, // R2_NOTMERGEPEN
|
||
0x0A, // R2_MASKNOTPEN
|
||
0x0F, // R2_NOTCOPYPEN
|
||
0x50, // R2_MASKPENNOT
|
||
0x55, // R2_NOT
|
||
0x5A, // R2_XORPEN
|
||
0x5F, // R2_NOTMASKPEN
|
||
0xA0, // R2_MASKPEN
|
||
0xA5, // R2_NOTXORPEN
|
||
0xAA, // R2_NOP
|
||
0xAF, // R2_MERGENOTPEN
|
||
0xF0, // R2_COPYPEN
|
||
0xF5, // R2_MERGEPENNOT
|
||
0xFA, // R2_MERGEPEN
|
||
0xFF // R2_WHITE
|
||
};
|
||
|
||
/******************************Public*Routine******************************\
|
||
* bPaintRgn
|
||
*
|
||
* Paint the clipping region with the specified color and mode
|
||
*
|
||
\**************************************************************************/
|
||
|
||
BOOL bPaintRgn
|
||
(
|
||
SURFOBJ *pso,
|
||
CLIPOBJ *pco,
|
||
MIX mix,
|
||
RBRUSH_COLOR rbc,
|
||
POINTL *pptlBrush,
|
||
PFNFILL pfnFill
|
||
)
|
||
{
|
||
BBENUM bben;
|
||
PPDEV ppdev;
|
||
ULONG iRT;
|
||
BOOL bMore;
|
||
|
||
// Get the target surface information.
|
||
|
||
ppdev = (PPDEV) pso->dhsurf;
|
||
|
||
switch(pco->iMode) {
|
||
|
||
case TC_RECTANGLES:
|
||
|
||
// Rectangular clipping can be handled without enumeration.
|
||
// Note that trivial clipping is not possible, since the clipping
|
||
// region defines the area to fill
|
||
|
||
if (pco->iDComplexity == DC_RECT)
|
||
{
|
||
(*pfnFill)(ppdev, 1, &pco->rclBounds, mix, rbc, pptlBrush);
|
||
|
||
} else {
|
||
|
||
// Enumerate all the rectangles and draw them
|
||
|
||
CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,CD_ANY,BB_RECT_LIMIT);
|
||
|
||
do {
|
||
bMore = CLIPOBJ_bEnum(pco, sizeof(bben), (PVOID) &bben);
|
||
|
||
(*pfnFill)(ppdev, bben.c, &bben.arcl[0], mix, rbc, pptlBrush);
|
||
|
||
} while (bMore);
|
||
}
|
||
|
||
return(TRUE);
|
||
|
||
default:
|
||
RIP("bPaintRgn: unhandled TC_xxx\n");
|
||
return(FALSE);
|
||
}
|
||
}
|
||
|
||
|
||
/**************************************************************************\
|
||
* DrvPaint
|
||
*
|
||
* Paint the clipping region with the specified brush
|
||
*
|
||
\**************************************************************************/
|
||
|
||
BOOL DrvPaint
|
||
(
|
||
SURFOBJ *pso,
|
||
CLIPOBJ *pco,
|
||
BRUSHOBJ *pbo,
|
||
POINTL *pptlBrush,
|
||
MIX mix
|
||
)
|
||
{
|
||
ROP4 rop4;
|
||
RBRUSH_COLOR rbc;
|
||
PFNFILL pfnFill;
|
||
|
||
// If this adapter supports planar mode and the foreground and background
|
||
// mixes are the same,
|
||
// LATER or if there's no brush mask
|
||
// then see if we can use the brush accelerators
|
||
// LATER handle non-planar also
|
||
|
||
if ((((PPDEV) pso->dhsurf)->fl & DRIVER_PLANAR_CAPABLE) &&
|
||
((mix & 0xFF) == ((mix >> 8) & 0xFF))) {
|
||
|
||
switch (mix & 0xFF) {
|
||
case 0:
|
||
break;
|
||
|
||
// vTrgBlt can only handle solid color fills where if the
|
||
// destination is inverted, no other action is also required
|
||
|
||
case R2_MASKNOTPEN:
|
||
case R2_NOTCOPYPEN:
|
||
case R2_XORPEN:
|
||
case R2_MASKPEN:
|
||
case R2_NOTXORPEN:
|
||
case R2_MERGENOTPEN:
|
||
case R2_COPYPEN:
|
||
case R2_MERGEPEN:
|
||
case R2_NOTMERGEPEN:
|
||
case R2_MASKPENNOT:
|
||
case R2_NOTMASKPEN:
|
||
case R2_MERGEPENNOT:
|
||
|
||
// vTrgBlt can only handle solid color fills
|
||
|
||
if (pbo->iSolidColor != 0xffffffff)
|
||
{
|
||
rbc.iSolidColor = pbo->iSolidColor;
|
||
pfnFill = vTrgBlt;
|
||
}
|
||
else
|
||
{
|
||
rbc.prb = (RBRUSH*) pbo->pvRbrush;
|
||
if (rbc.prb == NULL)
|
||
{
|
||
rbc.prb = (RBRUSH*) BRUSHOBJ_pvGetRbrush(pbo);
|
||
if (rbc.prb == NULL)
|
||
{
|
||
// If we haven't realized the brush, punt the call:
|
||
|
||
break;
|
||
}
|
||
}
|
||
if (!(rbc.prb->fl & RBRUSH_BLACKWHITE) &&
|
||
((mix & 0xff) != R2_COPYPEN))
|
||
{
|
||
// Only black/white brushes can handle ROPs other
|
||
// than COPYPEN:
|
||
|
||
break;
|
||
}
|
||
|
||
if (rbc.prb->fl & RBRUSH_NCOLOR)
|
||
pfnFill = vColorPat;
|
||
else
|
||
pfnFill = vMonoPat;
|
||
}
|
||
|
||
return(bPaintRgn(pso, pco, mix, rbc, pptlBrush, pfnFill));
|
||
|
||
// Rops that are implicit solid colors
|
||
|
||
case R2_NOT:
|
||
case R2_WHITE:
|
||
case R2_BLACK:
|
||
|
||
// Brush color parameter doesn't matter for these rops
|
||
|
||
// compiler error local variable 'rbc' used without having been initialized
|
||
rbc.prb = NULL;
|
||
rbc.iSolidColor = 0;
|
||
|
||
return(bPaintRgn(pso, pco, mix, rbc, NULL, vTrgBlt));
|
||
|
||
case R2_NOP:
|
||
return(TRUE);
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
rop4 = (gaMix[(mix >> 8) & 0x0F]) << 8;
|
||
rop4 |= ((ULONG) gaMix[mix & 0x0F]);
|
||
|
||
return(DrvBitBlt(
|
||
pso,
|
||
(SURFOBJ *) NULL,
|
||
(SURFOBJ *) NULL,
|
||
pco,
|
||
(XLATEOBJ *) NULL,
|
||
&pco->rclBounds,
|
||
(POINTL *) NULL,
|
||
(POINTL *) NULL,
|
||
pbo,
|
||
pptlBrush,
|
||
rop4));
|
||
}
|
||
|
||
|