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