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