Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

498 lines
15 KiB

/******************************Module*Header*******************************\
* Module Name: Brush.c
*
* Handles all brush/pattern initialization and realization.
*
* Copyright (c) 1992-1994 Microsoft Corporation
*
\**************************************************************************/
/*
* Copyright (c) 1995 FirePower Systems, Inc.
* DO NOT DISTRIBUTE without permission
*
* $RCSfile: brush.c $
* $Revision: 1.1 $
* $Date: 1996/03/08 01:18:52 $
* $Locker: $
*/
#include "driver.h"
/******************************Public*Routine******************************\
* VOID vRealizeDitherPattern
*
* Generates an 8x8 dither pattern, in our internal realization format, for
* the colour ulRGBToDither. Note that the high byte of ulRGBToDither does
* not need to be set to zero, because vComputeSubspaces ignores it.
\**************************************************************************/
VOID vRealizeDitherPattern(
RBRUSH* prb,
ULONG ulRGBToDither)
{
ULONG ulNumVertices;
VERTEX_DATA vVertexData[4];
VERTEX_DATA* pvVertexData;
BYTE rgjTemp[8*8];
BYTE *pjSrc;
BYTE *pjDst;
BYTE uj;
LONG i;
LONG j;
// Calculate what colour subspaces are involved in the dither:
pvVertexData = vComputeSubspaces(ulRGBToDither, vVertexData);
// Now that we have found the bounding vertices and the number of
// pixels to dither for each vertex, we can create the dither pattern
ulNumVertices = pvVertexData - vVertexData;
// # of vertices with more than zero pixels in the dither
// Do the actual dithering:
vDitherColor((ULONG *)rgjTemp, vVertexData, pvVertexData, ulNumVertices);
pjDst = (BYTE*) &prb->adPattern[0];
pjSrc = rgjTemp;
// Create 8 possible rotated versions of pattern
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j++) {
uj = *pjSrc++;
pjDst[8*0+j] = uj;
pjDst[8*1+((j+1) & 7)] = uj;
pjDst[8*2+((j+2) & 7)] = uj;
pjDst[8*3+((j+3) & 7)] = uj;
pjDst[8*4+((j+4) & 7)] = uj;
pjDst[8*5+((j+5) & 7)] = uj;
pjDst[8*6+((j+6) & 7)] = uj;
pjDst[8*7+((j+7) & 7)] = uj;
}
pjDst += 8*8;
}
}
/******************************Public*Routine******************************\
* BOOL DrvRealizeBrush
*
* This function allows us to convert GDI brushes into an internal form
* we can use. It may be called directly by GDI at SelectObject time, or
* it may be called by GDI as a result of us calling BRUSHOBJ_pvGetRbrush
* to create a realized brush in a function like DrvBitBlt.
*
* Note that we have no way of determining what the current Rop or brush
* alignment are at this point.
*
\**************************************************************************/
BOOL DrvRealizeBrush(
BRUSHOBJ* pbo,
SURFOBJ* psoDst,
SURFOBJ* psoPattern,
SURFOBJ* psoMask,
XLATEOBJ* pxlo,
ULONG iHatch)
{
PDEV* ppdev;
ULONG iPatternFormat;
BYTE* pjSrc;
BYTE* pjDst;
LONG lSrcDelta;
LONG i;
LONG j;
RBRUSH* prb;
ULONG* pulXlate;
ULONG ul;
USHORT us;
BYTE uj;
ULONG colorModeShift;
#if INVESTIGATE
if(traseentry & dbgflg & FL_DRV_REALIZE_BRUSH)
DISPDBG((0,"+++ Entering DrvRealizeBrush +++\n"));
if(breakentry & FL_DRV_REALIZE_BRUSH)
CountBreak();
#endif
CLOCKSTART((DRV_REALIZE_BRUSH));
ppdev = (PDEV*) psoDst->dhpdev;
// We have a fast path for dithers when we set GCAPS_DITHERONREALIZE:
// (only in 8BPP)
if (iHatch & RB_DITHERCOLOR) {
prb = BRUSHOBJ_pvAllocRbrush(pbo, cpixelRbrush);
if (prb == NULL)
goto ReturnFalse;
vRealizeDitherPattern(prb, iHatch);
CLOCKEND((DRV_REALIZE_BRUSH));
#if INVESTIGATE
if(traseexit & dbgflg & FL_DRV_REALIZE_BRUSH)
DISPDBG((0,"--- Exiting DrvRealizeBrush ---\n"));
if(breakexit & FL_DRV_REALIZE_BRUSH)
CountBreak();
#endif
return(TRUE);
}
// 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;
iPatternFormat = psoPattern->iBitmapFormat;
switch (ppdev->iBitmapFormat) {
case BMF_8BPP:
if ((iPatternFormat != BMF_1BPP) &&
(iPatternFormat != BMF_8BPP) &&
(iPatternFormat != BMF_4BPP))
goto ReturnFalse;
colorModeShift = 0;
break;
case BMF_16BPP:
if (((iPatternFormat != BMF_1BPP) &&
(iPatternFormat != BMF_8BPP) &&
(iPatternFormat != BMF_4BPP) &&
(iPatternFormat != BMF_16BPP)) ||
(iPatternFormat == BMF_16BPP && pxlo && !(pxlo->flXlate & XO_TRIVIAL)))
goto ReturnFalse;
colorModeShift = 1;
break;
case BMF_32BPP:
if (((iPatternFormat != BMF_1BPP) &&
(iPatternFormat != BMF_8BPP) &&
(iPatternFormat != BMF_4BPP) &&
(iPatternFormat != BMF_32BPP)) ||
(iPatternFormat == BMF_32BPP && pxlo && !(pxlo->flXlate & XO_TRIVIAL)))
goto ReturnFalse;
colorModeShift = 2;
break;
default:
goto ReturnFalse;
}
prb = BRUSHOBJ_pvAllocRbrush(pbo, cpixelRbrush << colorModeShift);
if (prb == NULL)
goto ReturnFalse;
lSrcDelta = psoPattern->lDelta;
pjSrc = (BYTE*) psoPattern->pvScan0;
pjDst = (BYTE*) &prb->adPattern[0];
if (pxlo)
pulXlate = pxlo->pulXlate;
else
pulXlate = NULL; // To remove warning message 3/20/95
switch (iPatternFormat) {
case BMF_8BPP: // Pattern is 8 BPP
if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) {
DISPDBG((2, "Realizing un-translated brush\n"));
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j++) {
uj = *pjSrc++;
pjDst[8*0+j] = uj;
pjDst[8*1+((j+1) & 7)] = uj;
pjDst[8*2+((j+2) & 7)] = uj;
pjDst[8*3+((j+3) & 7)] = uj;
pjDst[8*4+((j+4) & 7)] = uj;
pjDst[8*5+((j+5) & 7)] = uj;
pjDst[8*6+((j+6) & 7)] = uj;
pjDst[8*7+((j+7) & 7)] = uj;
}
pjDst += 8*8;
pjSrc += lSrcDelta - 8;
}
break;
} else {
DISPDBG((2, "Realizing 8bpp translated brush\n"));
// The screen is 8bpp, and there's translation to be done:
switch (ppdev->iBitmapFormat) {
case BMF_8BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j++) {
uj = (BYTE)pulXlate[ *pjSrc++];
pjDst[8*0+j] = uj;
pjDst[8*1+((j+1) & 7)] = uj;
pjDst[8*2+((j+2) & 7)] = uj;
pjDst[8*3+((j+3) & 7)] = uj;
pjDst[8*4+((j+4) & 7)] = uj;
pjDst[8*5+((j+5) & 7)] = uj;
pjDst[8*6+((j+6) & 7)] = uj;
pjDst[8*7+((j+7) & 7)] = uj;
}
pjDst += 8*8;
pjSrc += lSrcDelta - 8;
}
break;
case BMF_16BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j++) {
us = (USHORT)pulXlate[ *pjSrc++];
((USHORT *)pjDst)[8*0+j] = us;
((USHORT *)pjDst)[8*1+((j+1) & 7)] = us;
((USHORT *)pjDst)[8*2+((j+2) & 7)] = us;
((USHORT *)pjDst)[8*3+((j+3) & 7)] = us;
((USHORT *)pjDst)[8*4+((j+4) & 7)] = us;
((USHORT *)pjDst)[8*5+((j+5) & 7)] = us;
((USHORT *)pjDst)[8*6+((j+6) & 7)] = us;
((USHORT *)pjDst)[8*7+((j+7) & 7)] = us;
}
pjDst += 8*8*sizeof(USHORT);
pjSrc += lSrcDelta - 8;
}
break;
case BMF_32BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j++) {
ul = pulXlate[ *pjSrc++];
((ULONG *)pjDst)[8*0+j] = ul;
((ULONG *)pjDst)[8*1+((j+1) & 7)] = ul;
((ULONG *)pjDst)[8*2+((j+2) & 7)] = ul;
((ULONG *)pjDst)[8*3+((j+3) & 7)] = ul;
((ULONG *)pjDst)[8*4+((j+4) & 7)] = ul;
((ULONG *)pjDst)[8*5+((j+5) & 7)] = ul;
((ULONG *)pjDst)[8*6+((j+6) & 7)] = ul;
((ULONG *)pjDst)[8*7+((j+7) & 7)] = ul;
}
pjDst += 8*8*sizeof(ULONG);
pjSrc += lSrcDelta - 8;
}
break;
}
}
break;
case BMF_1BPP: // Pattern is 1 BPP
DISPDBG((2, "Realizing 1bpp brush\n"));
if (! pxlo)
goto ReturnFalse; // Just for safety reason
switch (ppdev->iBitmapFormat) {
case BMF_8BPP:
for (i = 8; i != 0; i--) {
ul = (ULONG)(*pjSrc);
for (j = 0; j< 8; j++) {
uj = (BYTE)pulXlate[(ul >> (7-j)) & 1];
pjDst[8*0+j] = uj;
pjDst[8*1+((j+1) & 7)] = uj;
pjDst[8*2+((j+2) & 7)] = uj;
pjDst[8*3+((j+3) & 7)] = uj;
pjDst[8*4+((j+4) & 7)] = uj;
pjDst[8*5+((j+5) & 7)] = uj;
pjDst[8*6+((j+6) & 7)] = uj;
pjDst[8*7+((j+7) & 7)] = uj;
}
pjDst += 8*8;
pjSrc += lSrcDelta;
}
break;
case BMF_16BPP:
for (i = 8; i != 0; i--) {
ul = (ULONG)(*pjSrc);
for (j = 0; j< 8; j++) {
us = (USHORT)pulXlate[(ul >> (7-j)) & 1];
((USHORT *)pjDst)[8*0+j] = us;
((USHORT *)pjDst)[8*1+((j+1) & 7)] = us;
((USHORT *)pjDst)[8*2+((j+2) & 7)] = us;
((USHORT *)pjDst)[8*3+((j+3) & 7)] = us;
((USHORT *)pjDst)[8*4+((j+4) & 7)] = us;
((USHORT *)pjDst)[8*5+((j+5) & 7)] = us;
((USHORT *)pjDst)[8*6+((j+6) & 7)] = us;
((USHORT *)pjDst)[8*7+((j+7) & 7)] = us;
}
pjDst += 8*8*sizeof(USHORT);
pjSrc += lSrcDelta;
}
break;
case BMF_32BPP:
for (i = 8; i != 0; i--) {
uj = (BYTE)(*pjSrc);
for (j = 0; j< 8; j++) {
ul = (ULONG)pulXlate[(uj >> (7-j)) & 1];
((ULONG *)pjDst)[8*0+j] = ul;
((ULONG *)pjDst)[8*1+((j+1) & 7)] = ul;
((ULONG *)pjDst)[8*2+((j+2) & 7)] = ul;
((ULONG *)pjDst)[8*3+((j+3) & 7)] = ul;
((ULONG *)pjDst)[8*4+((j+4) & 7)] = ul;
((ULONG *)pjDst)[8*5+((j+5) & 7)] = ul;
((ULONG *)pjDst)[8*6+((j+6) & 7)] = ul;
((ULONG *)pjDst)[8*7+((j+7) & 7)] = ul;
}
pjDst += 8*8*sizeof(ULONG);
pjSrc += lSrcDelta;
}
break;
}
break;
case BMF_4BPP: // Pattern is 4 BPP
DISPDBG((2, "Realizing 4bpp brush\n"));
if (! pxlo)
goto ReturnFalse; // Just for safety reason
switch (ppdev->iBitmapFormat) {
case BMF_8BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j += 2) {
ul = (ULONG)(*pjSrc++);
uj = (BYTE)pulXlate[ul >> 4];
pjDst[8*0+j] = uj;
pjDst[8*1+((j+1) & 7)] = uj;
pjDst[8*2+((j+2) & 7)] = uj;
pjDst[8*3+((j+3) & 7)] = uj;
pjDst[8*4+((j+4) & 7)] = uj;
pjDst[8*5+((j+5) & 7)] = uj;
pjDst[8*6+((j+6) & 7)] = uj;
pjDst[8*7+((j+7) & 7)] = uj;
uj = (BYTE)pulXlate[ul & 0xF];
pjDst[8*0+((j+1) & 7)] = uj;
pjDst[8*1+((j+2) & 7)] = uj;
pjDst[8*2+((j+3) & 7)] = uj;
pjDst[8*3+((j+4) & 7)] = uj;
pjDst[8*4+((j+5) & 7)] = uj;
pjDst[8*5+((j+6) & 7)] = uj;
pjDst[8*6+((j+7) & 7)] = uj;
pjDst[8*7+(j)] = uj;
}
pjDst += 8*8;
pjSrc += lSrcDelta-4;
}
break;
case BMF_16BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j += 2) {
ul = (ULONG)(*pjSrc++);
us = (USHORT)pulXlate[ul >> 4];
((USHORT *)pjDst)[8*0+j] = us;
((USHORT *)pjDst)[8*1+((j+1) & 7)] = us;
((USHORT *)pjDst)[8*2+((j+2) & 7)] = us;
((USHORT *)pjDst)[8*3+((j+3) & 7)] = us;
((USHORT *)pjDst)[8*4+((j+4) & 7)] = us;
((USHORT *)pjDst)[8*5+((j+5) & 7)] = us;
((USHORT *)pjDst)[8*6+((j+6) & 7)] = us;
((USHORT *)pjDst)[8*7+((j+7) & 7)] = us;
us = (USHORT)pulXlate[ul & 0xF];
((USHORT *)pjDst)[8*0+((j+1) & 7)] = us;
((USHORT *)pjDst)[8*1+((j+2) & 7)] = us;
((USHORT *)pjDst)[8*2+((j+3) & 7)] = us;
((USHORT *)pjDst)[8*3+((j+4) & 7)] = us;
((USHORT *)pjDst)[8*4+((j+5) & 7)] = us;
((USHORT *)pjDst)[8*5+((j+6) & 7)] = us;
((USHORT *)pjDst)[8*6+((j+7) & 7)] = us;
((USHORT *)pjDst)[8*7+j] = us;
}
pjDst += 8*8*sizeof(USHORT);
pjSrc += lSrcDelta-4;
}
break;
case BMF_32BPP:
for (i = 8; i != 0; i--) {
for (j = 0; j< 8; j += 2) {
uj = (BYTE)(*pjSrc++);
ul = (ULONG)pulXlate[uj >> 4];
((ULONG *)pjDst)[8*0+j] = ul;
((ULONG *)pjDst)[8*1+((j+1) & 7)] = ul;
((ULONG *)pjDst)[8*2+((j+2) & 7)] = ul;
((ULONG *)pjDst)[8*3+((j+3) & 7)] = ul;
((ULONG *)pjDst)[8*4+((j+4) & 7)] = ul;
((ULONG *)pjDst)[8*5+((j+5) & 7)] = ul;
((ULONG *)pjDst)[8*6+((j+6) & 7)] = ul;
((ULONG *)pjDst)[8*7+((j+7) & 7)] = ul;
ul = (ULONG)pulXlate[uj & 0xF];
((ULONG *)pjDst)[8*0+((j+1) & 7)] = ul;
((ULONG *)pjDst)[8*1+((j+2) & 7)] = ul;
((ULONG *)pjDst)[8*2+((j+3) & 7)] = ul;
((ULONG *)pjDst)[8*3+((j+4) & 7)] = ul;
((ULONG *)pjDst)[8*4+((j+5) & 7)] = ul;
((ULONG *)pjDst)[8*5+((j+6) & 7)] = ul;
((ULONG *)pjDst)[8*6+((j+7) & 7)] = ul;
((ULONG *)pjDst)[8*7+j] = ul;
}
pjDst += 8*8*sizeof(ULONG);
pjSrc += lSrcDelta-4;
}
break;
}
break;
case BMF_16BPP: // Pattern is 16 BPP
// The pattern is the same colour depth as the screen, and
// there's no translation to be done:
for (i = 8; i != 0; i--) {
for (j = 0; j < 8; j++) {
us = *((USHORT *)pjSrc)++;
((USHORT *)pjDst)[8*0+j] = us;
((USHORT *)pjDst)[8*1+((j+1) & 7)] = us;
((USHORT *)pjDst)[8*2+((j+2) & 7)] = us;
((USHORT *)pjDst)[8*3+((j+3) & 7)] = us;
((USHORT *)pjDst)[8*4+((j+4) & 7)] = us;
((USHORT *)pjDst)[8*5+((j+5) & 7)] = us;
((USHORT *)pjDst)[8*6+((j+6) & 7)] = us;
((USHORT *)pjDst)[8*7+((j+7) & 7)] = us;
}
pjDst += 8*8*sizeof(USHORT);
pjSrc += lSrcDelta - 8*sizeof(USHORT);
}
break;
case BMF_32BPP: // Pattern is 32 BPP
// The pattern is the same colour depth as the screen, and
// there's no translation to be done:
for (i = 8; i != 0; i--) {
for (j = 0; j < 8; j++) {
ul = *((ULONG *)pjSrc)++;
((ULONG *)pjDst)[8*0+j] = ul;
((ULONG *)pjDst)[8*1+((j+1) & 7)] = ul;
((ULONG *)pjDst)[8*2+((j+2) & 7)] = ul;
((ULONG *)pjDst)[8*3+((j+3) & 7)] = ul;
((ULONG *)pjDst)[8*4+((j+4) & 7)] = ul;
((ULONG *)pjDst)[8*5+((j+5) & 7)] = ul;
((ULONG *)pjDst)[8*6+((j+6) & 7)] = ul;
((ULONG *)pjDst)[8*7+((j+7) & 7)] = ul;
}
pjDst += 8*8*sizeof(ULONG);
pjSrc += lSrcDelta - 8*sizeof(ULONG);
}
break;
default:
goto ReturnFalse;
}
CLOCKEND((DRV_REALIZE_BRUSH));
#if INVESTIGATE
if(traseexit & dbgflg & FL_DRV_REALIZE_BRUSH)
DISPDBG((0,"--- Exiting DrvRealizeBrush ---\n"));
if(breakexit & FL_DRV_REALIZE_BRUSH)
CountBreak();
#endif
return(TRUE);
ReturnFalse:
if (psoPattern != NULL) {
DISPDBG((2, "Failed realization -- Type: %li Format: %li cx: %li cy: %li\n",
psoPattern->iType, psoPattern->iBitmapFormat,
psoPattern->sizlBitmap.cx, psoPattern->sizlBitmap.cy));
}
CLOCKEND((DRV_REALIZE_BRUSH));
COUNTUP ((TRAP_REALIZE_BRUSH));
#if INVESTIGATE
if(traseexit & dbgflg & FL_DRV_REALIZE_BRUSH)
DISPDBG((0,"--- Exiting DrvRealizeBrush ### returning FALSE to let GDI realize the brush ---\n"));
if(breakexit & FL_DRV_REALIZE_BRUSH)
CountBreak();
#endif
return(FALSE);
}