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.
 
 
 
 
 
 

263 lines
8.4 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: Brush.c
*
* Content: Handles all brush/pattern initialization and realization.
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "glint.h"
/////////////////////////////////////////////////////////////////////////////
//
// bDeviceBrush[SurfaceBpp][PatternBpp]
//
// 0 1 2 3 4 5 6 7 8
// 0 1BPP 4BPP 8BPP 16BPP 24BPP 32BPP 4RLE 8RLE (brush)
//
BOOL bDeviceBrush[BMF_8RLE + 1][BMF_8RLE + 1] =
{
{0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
{0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 1bpp
{0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4bpp
{0, 1, 0, 1, 1, 0, 0, 0, 0 }, // 8bpp
{0, 1, 0, 1, 1, 0, 0, 0, 0 }, // 16bpp
{0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 24bpp (screen)
{0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 32bpp
{0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4RLE
{0, 0, 0, 0, 0, 0, 0, 0, 0 } // 8RLE
};
/******************************Public*Routine******************************\
* BOOL DrvRealizeBrush
*
* This function allows us to convert GDI brushes into an internal form
* we can use. It is called by GDI when we've called BRUSHOBJ_pvGetRbrush
* in some other function like DrvBitBlt, and GDI doesn't happen have a cached
* realization lying around.
*
* Input:
*
* ppdev->bRealizeTransparent -- Hint for whether or not the brush should be
* realized for transparency. If this hint is
* wrong, there will be no error, but the brush
* will have to be unnecessarily re-realized.
*
* Note: You should always set 'ppdev->bRealizeTransparent' before calling
* BRUSHOBJ_pvGetRbrush!
*
\**************************************************************************/
BOOL
DrvRealizeBrush(
BRUSHOBJ* pbo,
SURFOBJ* psoDst,
SURFOBJ* psoPattern,
SURFOBJ* psoMask,
XLATEOBJ* pxlo,
ULONG iHatch)
{
static ULONG iBrushUniq = 0;
PDEV* ppdev = (PDEV*) psoDst->dhpdev;
ULONG iPatternFormat;
BYTE* pjSrc;
BYTE* pjDst;
USHORT* pusDst;
LONG lSrcDelta;
LONG cj;
LONG i;
LONG j;
RBRUSH* prb;
ULONG* pulXlate;
GLINT_DECL;
DISPDBG((DBGLVL, "DrvRealizeBrush called for pbo 0x%08X", pbo));
if( iHatch & RB_DITHERCOLOR )
{
// Let GDI to handle this brush.
goto ReturnFalse;
}
iPatternFormat = psoPattern->iBitmapFormat;
// We only accelerate 8x8 patterns. Since Win3.1 and Chicago don't
// support patterns of any other size, it's a safe bet that 99.9%
// of the patterns we'll ever get will be 8x8:
if ((psoPattern->sizlBitmap.cx != 8) ||
(psoPattern->sizlBitmap.cy != 8))
{
goto ReturnFalse;
}
if (bDeviceBrush[ppdev->iBitmapFormat][iPatternFormat])
{
prb = BRUSHOBJ_pvAllocRbrush(pbo,
sizeof(RBRUSH) +
(TOTAL_BRUSH_SIZE << ppdev->cPelSize));
if( prb == NULL )
{
goto ReturnFalse;
}
// Initialize the fields we need:
prb->ptlBrushOrg.x = LONG_MIN;
prb->iUniq = ++iBrushUniq;
prb->fl = 0;
prb->apbe = NULL;
lSrcDelta = psoPattern->lDelta;
pjSrc = (BYTE*) psoPattern->pvScan0;
pjDst = (BYTE*) &prb->aulPattern[0];
if (ppdev->iBitmapFormat == iPatternFormat)
{
if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
{
DISPDBG((DBGLVL, "Realizing un-translated brush"));
// The pattern is the same colour depth as the screen, and
// there's no translation to be done:
cj = (8 << ppdev->cPelSize); // Every pattern is 8 pels wide
for (i = 8; i != 0; i--)
{
RtlCopyMemory(pjDst, pjSrc, cj);
pjSrc += lSrcDelta;
pjDst += cj;
}
}
else if (ppdev->iBitmapFormat == BMF_8BPP)
{
DISPDBG((DBGLVL, "Realizing 8bpp translated brush"));
// The screen is 8bpp, and there's translation to be done:
pulXlate = pxlo->pulXlate;
for (i = 8; i != 0; i--)
{
for (j = 8; j != 0; j--)
{
*pjDst++ = (BYTE) pulXlate[*pjSrc++];
}
pjSrc += lSrcDelta - 8;
}
}
else
{
goto ReturnFalse;
}
}
else if (iPatternFormat == BMF_1BPP)
{
DWORD Data;
DISPDBG((DBGLVL, "Realizing 1bpp brush"));
// We dword align the monochrome bitmap so that every row starts
// on a new long (so that we can do long writes later to transfer
// the bitmap to the area stipple unit).
for (i = 8; i != 0; i--)
{
// Replicate the brush to 32 bits wide, as the TX cannot
// span fill 8 bit wide brushes
Data = (*pjSrc) & 0xff;
Data |= Data << 8;
Data |= Data << 16;
*(DWORD *)pjDst = Data;
// area stipple is loaded with DWORDS
pjDst += sizeof(DWORD);
pjSrc += lSrcDelta;
}
pulXlate = pxlo->pulXlate;
prb->fl |= RBRUSH_2COLOR;
prb->ulForeColor = pulXlate[1];
prb->ulBackColor = pulXlate[0];
}
else if ((iPatternFormat == BMF_4BPP) &&
(ppdev->iBitmapFormat == BMF_8BPP))
{
DISPDBG((DBGLVL, "Realizing 4bpp brush"));
// The screen is 8bpp and the pattern is 4bpp:
pulXlate = pxlo->pulXlate;
for (i = 8; i != 0; i--)
{
// Inner loop is repeated only 4 times because each iteration
// handles 2 pixels:
for (j = 4; j != 0; j--)
{
*pjDst++ = (BYTE) pulXlate[*pjSrc >> 4];
*pjDst++ = (BYTE) pulXlate[*pjSrc & 15];
pjSrc++;
}
pjSrc += lSrcDelta - 4;
}
}
else if ((iPatternFormat == BMF_8BPP) &&
(ppdev->iBitmapFormat == BMF_16BPP))
{
DISPDBG((DBGLVL, "Realizing 8bpp translated brush"));
// The screen is 16bpp, and there's translation to be done:
pulXlate = pxlo->pulXlate;
for (i = 8; i != 0; i--)
{
for (j = 8; j != 0; j--)
{
*((USHORT *) pjDst) = (USHORT)pulXlate[*pjSrc++];
pjDst += 2;
}
pjSrc += lSrcDelta - 8;
}
}
else
{
goto ReturnFalse;
}
DISPDBG((DBGLVL, "DrvRealizeBrush returning true"));
return TRUE;
}
ReturnFalse:
if (psoPattern != NULL)
{
DISPDBG((WRNLVL, "Failed realization -- "
"Type: %li Format: %li cx: %li cy: %li",
psoPattern->iType,
psoPattern->iBitmapFormat,
psoPattern->sizlBitmap.cx,
psoPattern->sizlBitmap.cy));
}
DISPDBG((DBGLVL, "DrvRealizeBrush returning false"));
return FALSE;
}