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.
 
 
 
 
 
 

270 lines
8.0 KiB

//--------------------------------------------------------------------------
//
// Module Name: BRUSH.C
//
// Brief Description: This module contains the PSCRIPT driver's brush
// realization routines.
//
// Author: Kent Settle (kentse)
// Created: 13-Dec-1990
//
// Copyright (c) 1990 - 1992 Microsoft Corporation
//
//--------------------------------------------------------------------------
#include "pscript.h"
//--------------------------------------------------------------------------
//
// BOOL DrvRealizeBrush(pbo, psoTarget, psoPattern, psoMask, pxlo)
// BRUSHOBJ *pbo;
// SURFOBJ *psoTarget;
// SURFOBJ *psoPattern;
// SURFOBJ *psoMask;
// XLATEOBJ *pxlo;
//
// Requests the driver to realize a pattern defined by psoPattern for
// the surface defined by psoTarget. A realized brush contains the
// information and accelerators the driver needs to fill an area with
// a pattern. This information is defined by the driver and used only
// by the driver. The driver's realization of the brush should be
// written into the buffer allocated by calling BRUSHOBJ_pvAllocRBrush.
//
// This function is required for a driver that does any drawing to any
// surface.
//
// Parameters:
// pbo:
// Points to the BRUSHOBJ which is being realized. All the other
// parameters, except for psoTarget, can actually be queried from
// this object. We provide them as an optimization. pbo is best used
// only as a parameter for BRUSHOBJ_pvAllocRBrush, which allocates
// the memory for the realized brush.
//
// psoTarget:
// The object for the surface the brush is to be realized for. This
// surface will either be the physical surface for the device, or a
// device format bitmap.
//
// psoPattern:
// The surface describing the pattern for the brush. For a raster
// device this will always represent a bitmap. For a vector device
// this will always be one of the pattern surfaces returned by
// DrvEnablePDEV.
//
// psoMask:
// If this argument is not NULL, it provides a transparency mask for
// the brush. This is a one bit per pel bitmap having the same
// extent as the pattern. A mask bit of zero means that the pel is
// considered a background pel for the brush (In transparent
// background mode, the background pels would be left unaffected in a
// fill.)
//
// Plotters can ignore this argument as they are never expected to draw
// background information.
//
// pxlo:
// An XLATEOBJ which tells how to interpret the colors in the pattern.
// An XLATEOBJ service routine can be called to translate the colors to
// device color indices. Vector devices should translate color 0
// through the XLATEOBJ to get the foreground color for the brush.
//
// Returns:
// TRUE if the brush was successfully realized. Otherwise, FALSE
// and an error code is logged.
//
// History:
// 13-Dec-1990 -by- Kent Settle (kentse)
// Wrote it.
//
// 16-Feb-1993 Tue 12:28:06 updated -by- Daniel Chou (danielc)
// Re-write so it takc iHatch rather go through the suface handle to
// check what type of pattern.
//
// 14-Mar-1995 -davidx-
// Don't copy color table entries from XLATEOBJ if XO_TABLE bit
// of flXlate is not set. This prevents us from causing memory
// access violation.
//
//--------------------------------------------------------------------------
BOOL DrvRealizeBrush(pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch)
BRUSHOBJ *pbo;
SURFOBJ *psoTarget;
SURFOBJ *psoPattern;
SURFOBJ *psoMask;
XLATEOBJ *pxlo;
ULONG iHatch;
{
ULONG cbTotal, cbBits, cColorTable;
DEVBRUSH *pBrush;
PDEVDATA pdev;
//
// Declare function name for debugging purposes
//
UNREFERENCED_PARAMETER(psoMask);
// get the pointer to our DEVDATA structure and make sure it is ours.
pdev = (PDEVDATA) psoTarget->dhpdev;
if (bValidatePDEV(pdev) == FALSE) {
DBGERRMSG("bValidatePDEV");
SETLASTERROR(ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (iHatch >= HS_DDI_MAX) {
// we have a bitmap for the pattern.
// determine the size of the bitmap, remembering that the
// bitmaps are DWORD (32 bit) bounded.
// how many pels per scanline?
cbBits = psoPattern->sizlBitmap.cx;
// times how many bits per pel.
switch (psoPattern->iBitmapFormat) {
case BMF_1BPP:
break;
case BMF_4BPP:
cbBits *= 4;
break;
case BMF_8BPP:
cbBits *= 8;
break;
case BMF_16BPP:
case BMF_32BPP:
// Convert 16bpp and 32bpp pattern brushes to their 24bpp equivalent
case BMF_24BPP:
cbBits *= 24;
break;
}
// cbBits now equals the number of bits per scanline.
// convert it to the number of bytes per scanline, taking into
// account that scanlines are padded out to 32 bit boundaries.
cbBits = (((cbBits + 31) / 32) * 4);
// now that we have the number of bytes per scanline, get the
// total number of bytes.
cbBits *= psoPattern->sizlBitmap.cy;
} else {
// we have one of the predefined patterns.
cbBits = 0;
}
// leave room for the color table.
// check to make sure there is indeed a color table.
cColorTable = (pxlo->flXlate & XO_TABLE) ? pxlo->cEntries : 0;
// allocate new brush.
cbTotal = sizeof(DEVBRUSH) + cbBits + cColorTable*sizeof(ULONG);
pBrush = BRUSHOBJ_pvAllocRbrush(pbo, cbTotal);
if (pBrush == NULL) {
DBGERRMSG("BRUSHOBJ_pvAllocRbrush");
return(FALSE);
}
// fill in the DEVBRUSH information.
pBrush->iPatIndex = iHatch;
pBrush->cXlate = cColorTable;
pBrush->offsetXlate = sizeof(DEVBRUSH) + cbBits;
// copy color table entries and if necessary
if (cColorTable > 0) {
memcpy((PBYTE) pBrush + pBrush->offsetXlate,
pxlo->pulXlate,
cColorTable * sizeof(ULONG));
}
if (iHatch >= HS_DDI_MAX) {
// we have a bitmap for the pattern. fill in the appropriate
// information in the DEVBRUSH, including the bitmap itself.
pBrush->sizlBitmap = psoPattern->sizlBitmap;
pBrush->flBitmap = psoPattern->fjBitmap;
//
// Copy the bits from the pattern surface to the brush.
//
// If the brush pattern is 16bpp or 32bpp, convert it to 24bpp
// and the resulting pattern will always be topdown.
//
if (psoPattern->iBitmapFormat == BMF_16BPP ||
psoPattern->iBitmapFormat == BMF_32BPP)
{
BOOL is16bpp;
PBYTE pSrc, pDest;
LONG x, y, destPadding;
is16bpp = (psoPattern->iBitmapFormat == BMF_16BPP);
pBrush->iFormat = BMF_24BPP;
pBrush->flBitmap |= BMF_TOPDOWN;
pSrc = psoPattern->pvScan0;
pDest = pBrush->ajBits;
//
// Destination bitmap scanlines always start at DWORD boundary
//
destPadding = (4 - (psoPattern->sizlBitmap.cx * 3) % 4) % 4;
for (y=0; y < psoPattern->sizlBitmap.cy; y++) {
for (x=0; x < psoPattern->sizlBitmap.cx; x++) {
ULONG index;
index = XLATEOBJ_iXlate(pxlo, is16bpp ? ((PWORD)pSrc)[x] : ((PULONG)pSrc)[x]);
*pDest++ = (BYTE) (index );
*pDest++ = (BYTE) (index >> 8);
*pDest++ = (BYTE) (index >> 16);
}
pSrc += psoPattern->lDelta;
pDest += destPadding;
}
} else {
pBrush->iFormat = psoPattern->iBitmapFormat;
memcpy(pBrush->ajBits, psoPattern->pvBits, cbBits);
}
}
// set the pointer to our brush in the BRUSHOBJ. REMEMBER,
// the engine will take care of discarding this memory, so
// we don't have to.
pbo->pvRbrush = pBrush;
return(TRUE);
}