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.
 
 
 
 
 
 

626 lines
14 KiB

/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
state.c
Abstract:
Printer graphics state tracking.
Implemenation of
GSRealizeBrush
GSUnRealizeBrush
GSSelectBrush
GSResetBrush
Environment:
Windows NT Unidrv driver
Revision History:
04/29/97 -amandan-
Created
--*/
#include "unidrv.h"
#ifdef WINNT_40 // NT 4.0
extern HSEMAPHORE hSemBrushColor;
LPDWORD pBrushSolidColor = NULL;
DWORD
GetBRUSHOBJRealColor(
PDEV *pPDev,
BRUSHOBJ *pbo
)
/*++
Routine Description:
Given a BRUSHOBJ Gets the original color ofthe brush using DrvDitherColor.
Arguments:
pPDev - Pointer to PDEV
pbo - Pointer to BRUSHOBJ
Return Value:
Original RGB color
Note:
--*/
{
DWORD SolidColor;
if ((SolidColor = pbo->iSolidColor) == 0xFFFFFFFF)
{
SolidColor = 0;
EngAcquireSemaphore(hSemBrushColor);
pBrushSolidColor = &SolidColor;
BRUSHOBJ_pvGetRbrush(pbo);
EngReleaseSemaphore(hSemBrushColor);
}
else
{
ERR(( "GetBRUSHOBJRealColor: Should not be Called for mapped color\n" ));
SolidColor = 0;
}
return(SolidColor);
}
#endif //WINNT_40
ULONG GetRGBColor(PDEV *, ULONG);
PDEVBRUSH
GSRealizeBrush(
IN OUT PDEV *pPDev,
IN SURFOBJ *pso,
IN BRUSHOBJ *pbo
)
/*++
Routine Description:
Given a BRUSHOBJ perform one of the following:
Color Printer:
1. Programmable Palette
2. Non-Programmable Palette
Monochrome Printer:
1. User defined pattern, only if brush is pattern brush
2. Shading Patterns , only if brush is pattern brush
3. Maps to black/white brush
4. Maps to black
Arguments:
pPDev - Pointer to PDEV
pso - Pointer to SURFOBJ
pbo - Pointer to BRUSHOBJ
Return Value:
PDEVBRUSH if successful, otherwise NULL
Note:
It's up to the caller to call GSUnRealizeBrush to free brushes
--*/
{
ULONG ulColor = pbo->iSolidColor;
PDEVBRUSH pDevBrush;
BOOL bPatternBrush = FALSE;
//
// Allocate memory for Brush, deallocation is done in GSUnRealizeBrush
//
if ((pDevBrush = MemAllocZ(sizeof(DEVBRUSH))) == NULL)
return NULL;
if (pso->iBitmapFormat != BMF_24BPP &&
pbo->iSolidColor != DITHERED_COLOR)
{
//
// Index case
// pbo->iSolidColor holds the Index, Map index to RGB color
//
ulColor = GetRGBColor(pPDev, pbo->iSolidColor);
}
//
// TBD: BUG_BUG NT4 - needs to be fixed
// no NT4 bugs will be fixed unless necessary.
//
if (pbo->iSolidColor == DITHERED_COLOR)
{
//
// Pattern Brush, get the color
//
#ifndef WINNT_40 //NT 5.0
ulColor = BRUSHOBJ_ulGetBrushColor(pbo);
// BUG_BUG: Unidrv currently doesn't handle the case where the brush is
// a non-solid brush (return -1). The HPGL / PCL-XL implementations will require
// this so we will merge that implementation when it is complete.
if (ulColor != -1)
ulColor &= 0x00FFFFFF;
#else // NT 4.0
ulColor = GetBRUSHOBJRealColor(pPDev, pbo);
#endif //!WINNT_40
bPatternBrush = TRUE;
}
//
// ulColor should always be RGB color by the time we get here
//
if ((pso->iBitmapFormat == BMF_1BPP) )
{
//
// Monochrome case
// Download user define pattern or select intensity for
// non-solid brush ONLY. Otherwise, map it to black or white.
//
//
if ((pPDev->fMode & PF_DOWNLOAD_PATTERN) && bPatternBrush)
{
PDEVBRUSH pDB;
// Support user defined pattern, iColor will hold the pattern ID
if ((pDB = (PDEVBRUSH)BRUSHOBJ_pvGetRbrush(pbo)) == NULL)
{
WARNING(("BRUSHOBJ_pvGetRBrush failed"));
MemFree(pDevBrush);
return NULL;
}
pDevBrush->dwBrushType = BRUSH_USERPATTERN;
pDevBrush->iColor = pDB->iColor;
}
else if ((pPDev->fMode & PF_SHADING_PATTERN) && bPatternBrush)
{
// Support shading pattern, iColor holds %of gray
pDevBrush->dwBrushType = BRUSH_SHADING;
pDevBrush->iColor = GET_SHADING_PERCENT(ulColor);
}
else if (pPDev->fMode & PF_WHITEBLACK_BRUSH)
{
// Support black/white brush commands, iColor will hold RBG color
// We are here means solid color brush, and for monochrome
// it can be either black or white. If it's indexed, we
// have taken care of mapping index to RGB color already
//
pDevBrush->dwBrushType = BRUSH_BLKWHITE;
pDevBrush->iColor = ulColor;
}
else
{
//
// Map to black
//
pDevBrush->dwBrushType = BRUSH_BLKWHITE;
pDevBrush->iColor = RGB_BLACK_COLOR;
}
}
else if (pPDev->fMode & PF_ANYCOLOR_BRUSH )
{
//
// Programmable
//
pDevBrush->dwBrushType = BRUSH_PROGCOLOR;
pDevBrush->iColor = ulColor;
}
else
{
//
// Non-Programmable
//
pDevBrush->dwBrushType = BRUSH_NONPROGCOLOR;
//
// Since ulColor is RGB color, need to map it to the nearest
// color in the fixed palette.
// iColor will hold the index of the color
//
if (pbo->iSolidColor == DITHERED_COLOR)
pDevBrush->iColor = BestMatchDeviceColor(pPDev,(DWORD)ulColor);
else
pDevBrush->iColor = pbo->iSolidColor;
}
//
// Save the brush to the Realized Brush linked list
//
if (pPDev->GState.pRealizedBrush == NULL)
{
pDevBrush->pNext = NULL;
pPDev->GState.pRealizedBrush = pDevBrush;
}
else
{
pDevBrush->pNext = pPDev->GState.pRealizedBrush;
pPDev->GState.pRealizedBrush = pDevBrush;
}
return pDevBrush;
}
VOID
GSUnRealizeBrush(
IN PDEV *pPDev
)
/*++
Routine Description:
Deallocate memory for the realized brush
Arguments:
pPDev Pointer to PDEV
Return Value:
None
--*/
{
PDEVBRUSH pDevBrush = pPDev->GState.pRealizedBrush;
VERBOSE(("GSUnRealizeBrush \n"));
while(pPDev->GState.pRealizedBrush !=NULL)
{
pDevBrush = pPDev->GState.pRealizedBrush;
pPDev->GState.pRealizedBrush = pDevBrush->pNext;
MemFree(pDevBrush);
}
pPDev->GState.pRealizedBrush = NULL;
}
BOOL
GSSelectBrush(
IN PDEV *pPDev,
IN PDEVBRUSH pDevBrush
)
/*++
Routine Description:
Given a pDevBrush, select the brush.
Arguments:
pPDev - Pointer to PDEV
pDevBrush - Pointer to DEVBRUSH
Return Value:
TRUE if sucessful, otherwise FALSE
--*/
{
BOOL bIndexedColor = FALSE;
//
// Find Cached Brush, if the current selected brush matches
// the caller request, do nothing.
//
if (BFoundCachedBrush(pPDev, pDevBrush))
return TRUE;
switch(pDevBrush->dwBrushType){
case BRUSH_PROGCOLOR:
{
VERBOSE(("Using Programmable RGB Color \n"));
if (((PAL_DATA *)pPDev->pPalData)->fFlags & PDF_PALETTE_FOR_8BPP_MONO)
pDevBrush->iColor = ConvertRGBToGrey(pDevBrush->iColor);
if ( !BSelectProgrammableBrushColor(pPDev, pDevBrush->iColor) )
{
WARNING(("\nCan't Select the brush color for RGB = 0x%x\n",pDevBrush->iColor));
pDevBrush->iColor = BestMatchDeviceColor(pPDev, pDevBrush->iColor);
bIndexedColor = TRUE;
}
}
//
// Let it fall thru to catch the indexed case
//
case BRUSH_NONPROGCOLOR:
{
if (bIndexedColor || pDevBrush->dwBrushType == BRUSH_NONPROGCOLOR)
{
INT iCmd;
VERBOSE(("Using Non Programmable Indexed Color"));
//
// If this color is not supported, use the default color: black.
//
pDevBrush->iColor &= (MAX_COLOR_SELECTION - 1); /* 16 entry palette wrap around */
//
// If there is no command to set the color, map to black.
//
if(COMMANDPTR(pPDev->pDriverInfo, CMD_COLORSELECTION_FIRST + pDevBrush->iColor) == NULL)
pDevBrush->iColor = BLACK_COLOR_CMD_INDEX;
iCmd = CMD_COLORSELECTION_FIRST + pDevBrush->iColor;
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, iCmd));
}
}
break;
case BRUSH_USERPATTERN:
{
VERBOSE(("Selecting user defined pattern brush"));
//
// The pattern ID, is stored in pDevBrush->iColor
//
pPDev->dwPatternBrushType = BRUSH_USERPATTERN;
pPDev->dwPatternBrushID = pDevBrush->iColor;
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_PATTERN));
}
break;
case BRUSH_SHADING:
{
VERBOSE(("Selecting shading pattern brush"));
//
// The gray level (expressed as intensity) is stored in
// pDevBrush->iColor
//
//
// Update standard variable for brush selection command
//
pPDev->dwPatternBrushType = BRUSH_SHADING;
pPDev->dwPatternBrushID = pDevBrush->iColor;
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_PATTERN));
}
break;
case BRUSH_BLKWHITE:
{
INT iCmd;
if (pDevBrush->iColor == RGB_WHITE_COLOR)
{
VERBOSE(("Selecting white brush"));
//
// BUG_BUG, need to remove the CMD_WHITETEXTON and CMD_WHITETEXTOFF
// once all GPD changes have been made for BLACKBRUSH, WHITEBRUSH
// doesn't hurt to leave it in.
if (pPDev->arCmdTable[CMD_SELECT_WHITEBRUSH])
iCmd = CMD_SELECT_WHITEBRUSH;
else
iCmd = CMD_WHITETEXTON;
}
else
{
//
// Black - standard text color
//
VERBOSE(("Selecting black brush"));
//
// BUG_BUG, need to remove the CMD_WHITETEXT_ON and CMD_WHITETEXT_OFF
// once all GPD changes have been made for BLACKBRUSH, WHITEBRUSH
// doesn't hurt to leave it in.
//
if (pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH])
iCmd = CMD_SELECT_BLACKBRUSH;
else
iCmd = CMD_WHITETEXTOFF;
}
//
// Set the desired colour !
//
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, iCmd));
}
break;
}
//
// Cached the brush
//
CACHE_CURRENT_BRUSH(pPDev, pDevBrush)
return TRUE;
}
VOID
GSResetBrush(
IN OUT PDEV *pPDev
)
/*++
Routine Description:
Select the default brush
Arguments:
pPDev - Pointer to PDEV
Return Value:
None
--*/
{
DEVBRUSH DeviceBrush;
PDEVBRUSH pDevBrush = &DeviceBrush;
PAL_DATA *pPD;
pPD = pPDev->pPalData;
if (pPD->fFlags & PDF_PALETTE_FOR_1BPP)
{
//
// Monochrome case. Select black brush
//
pDevBrush->dwBrushType = BRUSH_BLKWHITE;
pDevBrush->iColor = RGB_BLACK_COLOR;
if (BFoundCachedBrush(pPDev, pDevBrush))
return;
//
// BUG_BUG, need to remove the CMD_WHITETEXT_ON and CMD_WHITETEXT_OFF
// once all GPD changes have been made
// doesn't hurt to leave it in.
//
if (pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH])
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_BLACKBRUSH));
else
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_WHITETEXTOFF));
}
else if (pPDev->fMode & PF_ANYCOLOR_BRUSH )
{
//
// Programmable
//
pDevBrush->dwBrushType = BRUSH_PROGCOLOR;
pDevBrush->iColor = RGB_BLACK_COLOR;
VResetProgrammableBrushColor(pPDev);
}
else
{
//
// Non-Programmable
//
pDevBrush->dwBrushType = BRUSH_NONPROGCOLOR;
pDevBrush->iColor = ((PAL_DATA*)(pPDev->pPalData))->iBlackIndex;
if (BFoundCachedBrush(pPDev, pDevBrush))
return;
WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo,CMD_SELECTBLACKCOLOR));
}
CACHE_CURRENT_BRUSH(pPDev, pDevBrush)
}
ULONG
GetRGBColor(
IN PDEV *pPDev,
IN ULONG ulIndex
)
/*++
Routine Description:
Given an Indexed color, map to an RGB color
Arguments:
pPDev - Pointer to PDEV
pDevBrush - Pointer to DEVBRUSH
Return Value:
TRUE if sucessful, otherwise FALSE
--*/
{
// If the index is invalid, map to Black.
if (ulIndex > PALETTE_MAX)
{
ERR(( "GSSelectBrush: Bad input Color Index\n" ));
ulIndex = ((PAL_DATA*)(pPDev->pPalData))->iBlackIndex;
}
return( ((PAL_DATA *)(pPDev->pPalData))->ulPalCol[ulIndex]);
}