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
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]);
|
|
|
|
}
|