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.
 
 
 
 
 
 

550 lines
11 KiB

/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
brush.c
Abstract:
DrvRealizeBrush
Environment:
Windows NT Unidrv driver
Revision History:
05/14/97 -amandan-
Created
--*/
#include "unidrv.h"
BRGBColorSpace(PDEV *);
LONG
FindCachedHTPattern(
PDEV *pPDev,
WORD wChecksum
)
/*++
Routine Description:
This function find the cached text brush pattern color, if not there then
it will add it to the cached.
Arguments:
pPDev - Pointer to our PDEV
wCheckSum - Checksum of pattern brush
Return Value:
LONG >0 - Found the cached, return value is the pattern ID
=0 - Out of memory, not cached
<0 - not in the cached, add to the cached, return value is
the negated pattern ID
Author:
08-Apr-1997 Tue 19:42:21 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
LPWORD pDBCache;
WORD cMaxDB;
WORD cUsedDB;
WORD Index;
//
// The first is the cMaxDB, the 2nd is the cUsedDB
//
if (pDBCache = pPDev->GState.pCachedPatterns)
{
cMaxDB = *(pDBCache + 0);
cUsedDB = *(pDBCache + 1);
pDBCache += 2;
for (Index = 1; Index <= cUsedDB; Index++, pDBCache++)
{
if (*pDBCache == wChecksum)
{
VERBOSE(("\n\tRaddd:FindCachedHTPat(%04lx): FOUND=%ld ",
wChecksum, Index));
return((LONG)Index);
}
}
//
// If we can't find a cached one, add the new one to the list
//
if (cUsedDB < cMaxDB)
{
*pDBCache = wChecksum;
*(pPDev->GState.pCachedPatterns + 1) += 1;
VERBOSE(("\n\tRaddd:FindCachedHTPat(%04lx): NOT FOUND=%ld ",
wChecksum, -(LONG)Index));
return(-(LONG)Index);
}
}
else
{
cUsedDB =
cMaxDB = 0;
}
//
// We need to expand the checksum cached buffer
//
VERBOSE(("\n\tUnidrv:FindCachedHTPat(%04lx): pDBCache=%08lx, cUsedDB=%ld, cMaxDB=%ld",
wChecksum, pDBCache, cUsedDB, cMaxDB));
if (((cMaxDB + DBCACHE_INC) < DBCACHE_MAX) &&
(pDBCache = (LPWORD)MemAllocZ((cMaxDB + DBCACHE_INC + 2) *
sizeof(WORD))))
{
if ((cMaxDB) && (pPDev->GState.pCachedPatterns))
{
CopyMemory(pDBCache + 2,
pPDev->GState.pCachedPatterns + 2,
cMaxDB * sizeof(WORD));
MemFree(pPDev->GState.pCachedPatterns);
}
*(pDBCache + 0) = cMaxDB + DBCACHE_INC;
*(pDBCache + 1) = cUsedDB + 1;
*(pDBCache + 2 + cUsedDB) = wChecksum;
pPDev->GState.pCachedPatterns = pDBCache;
VERBOSE (("\n\tUnidrv:FindCachedHTPat(%04lx): pDBCache=%08lx, cUsedDB=%ld, cMaxDB=%ld, EMPTY=%ld ",
wChecksum, pDBCache, *(pDBCache + 1), *(pDBCache + 0), -(LONG)(cUsedDB + 1)));
return(-(LONG)(cUsedDB + 1));
}
//
// Out of memory
//
WARNING(("\n\tUnidrv:FindCachedHTPat: OUT OF MEMORY"));
return(0);
}
BOOL
Download1BPPHTPattern(
PDEV *pPDev,
SURFOBJ *pso,
DWORD dwPatID
)
/*++
Routine Description:
This function donload a user define pattern
Arguments:
pPDev - Pointer to the PDEV
pDevBrush - Pointer to the cached device brush
Return Value:
INT to indicate a pattern number downloaed/defined
Author:
08-Apr-1997 Tue 19:41:00 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
SURFOBJ so;
LPBYTE pb;
LPBYTE pbEnd;
LPBYTE pSrc;
DWORD cbCX;
DWORD cb;
WORD cxcyRes;
INT Len;
BYTE Buf[64];
BYTE XorMask;
BYTE EndMask;
so = *pso;
pb = Buf;
pbEnd = pb + sizeof(Buf) - 4;
cbCX = (DWORD)(((DWORD)so.sizlBitmap.cx + 7) >> 3);
//
// Update standard variable and send command
//
pPDev->dwPatternBrushType = BRUSH_USERPATTERN;
pPDev->dwPatternBrushSize = (DWORD)(cbCX * so.sizlBitmap.cy) + 12;
pPDev->dwPatternBrushID = dwPatID;
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_DOWNLOAD_PATTERN));
//
// Send header and pattern data
//
*pb++ = 20;
*pb++ = 0;
*pb++ = (so.iBitmapFormat == BMF_1BPP) ? 1 : 8;
*pb++ = 0;
*pb++ = HIBYTE((WORD)so.sizlBitmap.cx);
*pb++ = LOBYTE((WORD)so.sizlBitmap.cx);
*pb++ = HIBYTE((WORD)so.sizlBitmap.cy);
*pb++ = LOBYTE((WORD)so.sizlBitmap.cy);
*pb++ = HIBYTE((WORD)pPDev->ptGrxRes.x);
*pb++ = LOBYTE((WORD)pPDev->ptGrxRes.x);
*pb++ = HIBYTE((WORD)pPDev->ptGrxRes.y);
*pb++ = LOBYTE((WORD)pPDev->ptGrxRes.y);
//
// The XorMask is used to flip the BLACK/WHITE bit depends on the output
// and EndMask is to mask off any unwanted bit in the last byte to 0
// this is to fix LJ5si, LJ4si firmware bugs, REMEMBER our palette always
// in RGB additive mode so the passed in 1BPP format has 0=Black, 1=White
//
XorMask = (BRGBColorSpace(pPDev)) ? 0x00 : 0xff;
if (!(EndMask = (BYTE)(0xff << (8 - (so.sizlBitmap.cx & 0x07)))))
{
EndMask = 0xff;
}
VERBOSE(("\n\tRaddd:DownLoaHTPattern: PatID=%ld, Format=%ld, %ld x %ld, XorMask=%02lx, EndMaks=%02lx\t\t",
dwPatID, pso->iBitmapFormat, so.sizlBitmap.cx, so.sizlBitmap.cy,
XorMask, EndMask));
while (so.sizlBitmap.cy--)
{
cb = cbCX;
pSrc = so.pvScan0;
(LPBYTE)so.pvScan0 += so.lDelta;
while (cb--)
{
*pb++ = (BYTE)(*pSrc++ ^ XorMask);
if (!cb) {
*(pb - 1) &= EndMask;
}
if (pb >= pbEnd) {
WriteSpoolBuf(pPDev, Buf, (DWORD)(pb - Buf));
pb = Buf;
}
}
}
//
// Send remaining data
//
if (Len = (INT)(pb - Buf))
{
WriteSpoolBuf(pPDev, Buf, Len);
}
return(TRUE);
}
WORD
GetBMPChecksum(
SURFOBJ *pso,
PRECTW prcw
)
/*++
Routine Description:
Arguments:
Return Value:
Author:
22-Apr-1997 Tue 11:32:37 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
LPBYTE pb;
RECTW rcw;
LONG cy;
LONG cPixels;
LONG lDelta;
WORD wChecksum;
UINT c1stPixels;
UINT Format;
BYTE BegMask;
BYTE EndMask;
BYTE XorMask;
rcw = *prcw;
Format = (UINT)pso->iBitmapFormat;
wChecksum = 0;
VERBOSE(("\nComputeChecksum(%ld): (%4ld, %4ld)-(%4ld, %4ld)=%3ldx%3ld\t\t",
Format, rcw.l, rcw.t, rcw.r, rcw.b,
rcw.r - rcw.l, rcw.b - rcw.t));
if (rcw.l > (WORD)pso->sizlBitmap.cx) {
rcw.l = (WORD)pso->sizlBitmap.cx;
}
if (rcw.t > (WORD)pso->sizlBitmap.cy) {
rcw.t = (WORD)pso->sizlBitmap.cy;
}
if (rcw.r > (WORD)pso->sizlBitmap.cx) {
rcw.r = (WORD)pso->sizlBitmap.cx;
}
if (rcw.b > (WORD)pso->sizlBitmap.cy) {
rcw.b = (WORD)pso->sizlBitmap.cy;
}
if ((rcw.r <= rcw.l) || (rcw.b <= rcw.t)) {
return(wChecksum);
}
cPixels = (LONG)(rcw.r - rcw.l);
cy = (LONG)(rcw.b - rcw.t);
lDelta = pso->lDelta;
pb = (LPBYTE)pso->pvScan0 + ((LONG)rcw.t * lDelta);
XorMask = 0xFF;
//
// rcw.r and rcw.b are exclusive
//
--rcw.r;
--rcw.b;
switch (Format) {
case BMF_1BPP:
pb += (rcw.l >> 3);
c1stPixels = (UINT)(8 - (rcw.l & 0x07));
BegMask = (BYTE)(0xff >> (rcw.l & 0x07));
EndMask = (BYTE)(0xff << (8 - (rcw.r & 0x07)));
break;
case BMF_4BPP:
if (rcw.l & 0x01) {
BegMask = 0x07;
c1stPixels = 4;
} else {
BegMask = 0x77;
c1stPixels = 0;
}
pb += (rcw.l >> 1);
cPixels <<= 2;
EndMask = (BYTE)((rcw.r & 0x01) ? 0x70 : 0x77);
XorMask = 0x77;
break;
case BMF_8BPP:
case BMF_16BPP:
case BMF_24BPP:
BegMask =
EndMask = 0xFF;
c1stPixels = (UINT)(Format - BMF_8BPP + 1);
pb += (rcw.l * c1stPixels);
cPixels *= (c1stPixels << 3);
c1stPixels = 0;
break;
}
while (cy--) {
LPBYTE pbCur;
LONG Count;
WORD w;
pbCur = pb;
pb += lDelta;
Count = cPixels;
w = (WORD)((c1stPixels) ? ((*pbCur++ ^ XorMask) & BegMask) : 0);
if ((Count -= c1stPixels) >= 8) {
do {
w <<= 8;
w |= (*pbCur++ ^ XorMask);
wChecksum += w;
} while ((Count -= 8) >= 8);
}
if (Count > 0) {
w <<= 8;
w |= (WORD)((*pbCur ^ XorMask) & EndMask);
} else {
w &= EndMask;
}
wChecksum += w;
}
VERBOSE(("\nComputeChecksum(%ld:%04lx): (%4ld, %4ld)-(%4ld, %4ld)=%3ldx%3ld [%3ld], pb=%08lx [%02lx:%02lx], %1ld\t",
Format, wChecksum,
rcw.l, rcw.t, rcw.r + 1, rcw.b + 1,
rcw.r - rcw.l + 1, rcw.b - rcw.t + 1, cPixels,
pb, BegMask, EndMask, c1stPixels));
return(wChecksum);
}
BOOL
BRGBColorSpace(
PDEV *pPDev
)
{
LISTNODE *pListNode = NULL;
if (pPDev->pDriverInfo && pPDev->pColorModeEx)
pListNode = LISTNODEPTR(pPDev->pDriverInfo,pPDev->pColorModeEx->liColorPlaneOrder);
while (pListNode)
{
switch (pListNode->dwData)
{
case COLOR_RED:
case COLOR_GREEN:
case COLOR_BLUE:
return TRUE;
default:
break;
}
if (pListNode->dwNextItem == END_OF_LIST)
break;
else
pListNode = LOCALLISTNODEPTR(pPDev->pDriverInfo, pListNode->dwNextItem);
}
return FALSE;
}
BOOL
BFoundCachedBrush(
PDEV *pPDev,
PDEVBRUSH pDevBrush
)
{
//
// search the cache only if we want to use the last color. If
// MODE_BRUSH_RESET_COLOR is set then we want to explicitly reset the brush
// color by sending the command to the printer.
//
if ( (!(pPDev->ctl.dwMode & MODE_BRUSH_RESET_COLOR)) )
{
if ( (pDevBrush->dwBrushType == pPDev->GState.CurrentBrush.dwBrushType) &&
(pDevBrush->iColor == pPDev->GState.CurrentBrush.iColor) )
{
return TRUE;
}
}
else
{
//
// Reset the MODE_BRUSH_RESET_COLOR flag as we want to search the cache
// next time.
//
pPDev->ctl.dwMode &= ~MODE_BRUSH_RESET_COLOR;
}
return FALSE;
}