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.
2153 lines
59 KiB
2153 lines
59 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
Implemenation of the following initialization functions:
|
|
BInitGDIInfo
|
|
BInitDevInfo
|
|
BInitPDEV
|
|
|
|
Environment:
|
|
|
|
Windows NT Unidrv driver
|
|
|
|
Revision History:
|
|
|
|
10/21/96 -amandan-
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include "unidrv.h"
|
|
|
|
INT iHypot( INT, INT);
|
|
INT iGCD(INT, INT);
|
|
VOID VInitFMode(PDEV *);
|
|
VOID VInitFYMove(PDEV *);
|
|
BOOL BInitOptions(PDEV *);
|
|
BOOL BInitCmdTable(PDEV *);
|
|
BOOL BInitStdTable(PDEV *);
|
|
BOOL BInitPaperFormat(PDEV *, RECTL *);
|
|
VOID VInitOutputCTL(PDEV *, PRESOLUTIONEX);
|
|
VOID VGetPaperMargins(PDEV *, PAGESIZE *, PAGESIZEEX *, SIZEL, RECTL *);
|
|
VOID VOptionsToDevmodeFields(PDEV *pPDev) ;
|
|
|
|
|
|
|
|
VOID VSwapL(
|
|
long *pl1,
|
|
long *pl2)
|
|
{
|
|
long ltemp;
|
|
|
|
ltemp = *pl1;
|
|
*pl1 = *pl2;
|
|
*pl2 = ltemp;
|
|
}
|
|
|
|
BOOL
|
|
BInitPDEV (
|
|
PDEV *pPDev,
|
|
RECTL *prcFormImageArea
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the PDEVICE
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
pdm - Points to the input devmode
|
|
prcFormInageArea - pointer image area of form selected
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
{
|
|
pPDev->sCopies = pPDev->pdm->dmCopies;
|
|
pPDev->pGlobals = &(pPDev->pDriverInfo->Globals);
|
|
|
|
//
|
|
// Initializes Options structs
|
|
//
|
|
|
|
if (BInitOptions(pPDev) == FALSE)
|
|
return FALSE;
|
|
|
|
|
|
//
|
|
// Initializes pPDev->ptGrxRes and pPDev->ptTextRes based on the
|
|
// current resolution selection
|
|
//
|
|
|
|
//
|
|
// Initializes the graphics and text resolution of PDEV
|
|
//
|
|
|
|
ASSERT(pPDev->pResolution && pPDev->pResolutionEx);
|
|
|
|
pPDev->ptGrxRes.x = pPDev->pResolutionEx->ptGrxDPI.x;
|
|
pPDev->ptGrxRes.y = pPDev->pResolutionEx->ptGrxDPI.y;
|
|
|
|
pPDev->ptTextRes.x = pPDev->pResolutionEx->ptTextDPI.x;
|
|
pPDev->ptTextRes.y = pPDev->pResolutionEx->ptTextDPI.y;
|
|
|
|
pPDev->ptGrxScale.x = pPDev->pGlobals->ptMasterUnits.x / pPDev->ptGrxRes.x;
|
|
pPDev->ptGrxScale.y = pPDev->pGlobals->ptMasterUnits.y / pPDev->ptGrxRes.y;
|
|
|
|
if (pPDev->pdm->dmOrientation == DMORIENT_LANDSCAPE)
|
|
{
|
|
VSwapL(&pPDev->ptGrxRes.x, &pPDev->ptGrxRes.y);
|
|
VSwapL(&pPDev->ptTextRes.x, &pPDev->ptTextRes.y);
|
|
VSwapL(&pPDev->ptGrxScale.x, &pPDev->ptGrxScale.y);
|
|
}
|
|
if (pPDev->pGlobals->ptDeviceUnits.x)
|
|
pPDev->ptDeviceFac.x = pPDev->pGlobals->ptMasterUnits.x / pPDev->pGlobals->ptDeviceUnits.x;
|
|
if (pPDev->pGlobals->ptDeviceUnits.y)
|
|
pPDev->ptDeviceFac.y = pPDev->pGlobals->ptMasterUnits.y / pPDev->pGlobals->ptDeviceUnits.y;
|
|
|
|
//
|
|
// Init OUTPUTCTL
|
|
//
|
|
|
|
VInitOutputCTL(pPDev, pPDev->pResolutionEx);
|
|
|
|
//
|
|
// Initializes pPDev->sBitsPixel
|
|
//
|
|
|
|
if (pPDev->pColorModeEx != NULL)
|
|
pPDev->sBitsPixel = (short)pPDev->pColorModeEx->dwDrvBPP;
|
|
else
|
|
pPDev->sBitsPixel = 1;
|
|
|
|
//
|
|
// Init PAPERFORMAT struct
|
|
//
|
|
|
|
ASSERT(pPDev->pPageSize != NULL);
|
|
|
|
if (BInitPaperFormat(pPDev, prcFormImageArea) == FALSE)
|
|
return FALSE;
|
|
|
|
//
|
|
// Initialize the amount of free memory in the device
|
|
//
|
|
|
|
if (pPDev->pMemOption)
|
|
{
|
|
pPDev->dwFreeMem = pPDev->pMemOption->dwFreeMem;
|
|
}
|
|
else
|
|
{
|
|
pPDev->dwFreeMem = 0;
|
|
}
|
|
|
|
//
|
|
// Initialize the command table from the Unidrv predefined command index
|
|
// as defined in GPD.H
|
|
//
|
|
|
|
if (BInitCmdTable(pPDev) == FALSE)
|
|
return FALSE;
|
|
|
|
//
|
|
// Initialize the pPDev->fMode flag
|
|
//
|
|
|
|
VInitFMode(pPDev);
|
|
|
|
//
|
|
// Initialize the pPDev->fYMove flag
|
|
//
|
|
|
|
VInitFYMove(pPDev);
|
|
|
|
//
|
|
// Initialize the standard variable table in PDEVICE.
|
|
// This table is used to access state variable controls by the driver
|
|
//
|
|
|
|
if (BInitStdTable(pPDev) == FALSE)
|
|
return FALSE;
|
|
|
|
//
|
|
// Initialize misc. variables that need to be in pdev since
|
|
// we unloads the binary data at DrvEnablePDEV and reloads it at
|
|
// DrvEnableSurface
|
|
//
|
|
|
|
pPDev->dwMaxCopies = pPDev->pGlobals->dwMaxCopies;
|
|
pPDev->dwMaxGrayFill = pPDev->pGlobals->dwMaxGrayFill;
|
|
pPDev->dwMinGrayFill = pPDev->pGlobals->dwMinGrayFill;
|
|
pPDev->cxafterfill = pPDev->pGlobals->cxafterfill;
|
|
pPDev->cyafterfill = pPDev->pGlobals->cyafterfill;
|
|
pPDev->dwCallingFuncID = INVALID_EP;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
BOOL
|
|
BInitGdiInfo(
|
|
PDEV *pPDev,
|
|
ULONG *pGdiInfoBuffer,
|
|
ULONG ulBufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes the GDIINFO struct
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
pGdiInfoBuffer - Points to the output GDIINFO buffer passed in from GDI
|
|
ulBufferSize - Size of the output buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
GDIINFO gdiinfo;
|
|
DEVHTINFO DevHTInfo;
|
|
|
|
// initialize GDIINFO structure
|
|
//
|
|
ZeroMemory(&gdiinfo, sizeof(GDIINFO));
|
|
|
|
//
|
|
// Driver version
|
|
//
|
|
|
|
gdiinfo.ulVersion = UNIDRIVER_VERSION;
|
|
|
|
if ( pPDev->pGlobals->printertype == PT_TTY)
|
|
{
|
|
pPDev->bTTY = TRUE;
|
|
gdiinfo.ulTechnology = DT_CHARSTREAM;
|
|
}
|
|
else
|
|
{
|
|
pPDev->bTTY = FALSE;
|
|
gdiinfo.ulTechnology = DT_RASPRINTER;
|
|
}
|
|
|
|
//
|
|
// Width and Height of physical display in milimeters
|
|
//
|
|
|
|
//
|
|
// Returning a negative number for ulHorzSize and ulVertSize means
|
|
// the values are in micrometers. (25400 micrometer in 1 inch)
|
|
//
|
|
|
|
gdiinfo.ulHorzSize = (ULONG)MulDiv(-pPDev->sf.szImageAreaG.cx,
|
|
25400, pPDev->ptGrxRes.x);
|
|
|
|
gdiinfo.ulVertSize = (ULONG)MulDiv(-pPDev->sf.szImageAreaG.cy,
|
|
25400, pPDev->ptGrxRes.y);
|
|
|
|
//
|
|
// Width and height of physical surface measured in device pixels
|
|
//
|
|
|
|
gdiinfo.ulHorzRes = pPDev->sf.szImageAreaG.cx;
|
|
gdiinfo.ulVertRes = pPDev->sf.szImageAreaG.cy;
|
|
|
|
gdiinfo.cBitsPixel = pPDev->sBitsPixel;
|
|
gdiinfo.cPlanes = 1;
|
|
gdiinfo.ulNumColors = (1 << gdiinfo.cBitsPixel);
|
|
#ifdef WINNT_40
|
|
if (gdiinfo.ulNumColors > 0x7fff)
|
|
gdiinfo.ulNumColors = 0x7fff;
|
|
#endif
|
|
|
|
gdiinfo.flRaster = 0;
|
|
|
|
gdiinfo.ulLogPixelsX = pPDev->ptGrxRes.x;
|
|
gdiinfo.ulLogPixelsY = pPDev->ptGrxRes.y;
|
|
|
|
//
|
|
// BUG_BUG, The FMInit() function fills out gdiinfo.flTextCaps field
|
|
// gdiinfo.flTextCaps = pPDev->flTextCaps;
|
|
//
|
|
|
|
//
|
|
// The following are for Win 3.1 compatability. The X and Y values
|
|
// are reversed.
|
|
//
|
|
|
|
gdiinfo.ulAspectX = pPDev->ptTextRes.y;
|
|
gdiinfo.ulAspectY = pPDev->ptTextRes.x;
|
|
gdiinfo.ulAspectXY = iHypot( gdiinfo.ulAspectX, gdiinfo.ulAspectY);
|
|
|
|
|
|
//
|
|
// Set the styled line information for this printer
|
|
//
|
|
|
|
if(pPDev->ptGrxRes.x == pPDev->ptGrxRes.y)
|
|
{
|
|
//
|
|
// Special case: resolution is the same in both directions. This
|
|
// is typically true for laser and inkjet printers.
|
|
//
|
|
|
|
gdiinfo.xStyleStep = 1;
|
|
gdiinfo.yStyleStep = 1;
|
|
gdiinfo.denStyleStep = pPDev->ptGrxRes.x / 50; // 50 elements per inch
|
|
if ( gdiinfo.denStyleStep == 0 )
|
|
gdiinfo.denStyleStep = 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Resolutions differ, so figure out lowest common multiple
|
|
//
|
|
|
|
INT igcd;
|
|
|
|
igcd = iGCD( pPDev->ptGrxRes.x, pPDev->ptGrxRes.y);
|
|
|
|
gdiinfo.xStyleStep = pPDev->ptGrxRes.y / igcd;
|
|
gdiinfo.yStyleStep = pPDev->ptGrxRes.x / igcd;
|
|
gdiinfo.denStyleStep = gdiinfo.xStyleStep * gdiinfo.yStyleStep / 2;
|
|
|
|
}
|
|
|
|
//
|
|
// Size and margins of physical surface measured in device pixels
|
|
//
|
|
|
|
gdiinfo.ptlPhysOffset.x = pPDev->sf.ptImageOriginG.x;
|
|
gdiinfo.ptlPhysOffset.y = pPDev->sf.ptImageOriginG.y;
|
|
|
|
gdiinfo.szlPhysSize.cx = pPDev->sf.szPhysPaperG.cx;
|
|
gdiinfo.szlPhysSize.cy = pPDev->sf.szPhysPaperG.cy;
|
|
|
|
|
|
//
|
|
// BUG_BUG, RMInit should fill out the following fields in GDIINFO
|
|
// gdiinfo.ciDevice
|
|
// gdiinfo.ulDevicePelsDPI
|
|
// gdiinfo.ulPrimaryOrder
|
|
// gdiinfo.ulHTPatternSize
|
|
// gdiinfo.ulHTOutputFormat
|
|
// gdiinfo.flHTFlags
|
|
//
|
|
|
|
//
|
|
// Copy ulBufferSize bytes of gdiinfo to pGdiInfoBuffer.
|
|
//
|
|
|
|
if (ulBufferSize != sizeof(gdiinfo))
|
|
ERR(("Incorrect GDIINFO buffer size: %d != %d\n", ulBufferSize, sizeof(gdiinfo)));
|
|
|
|
CopyMemory(pGdiInfoBuffer, &gdiinfo, min(ulBufferSize, sizeof(gdiinfo)));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BInitDevInfo(
|
|
PDEV *pPDev,
|
|
DEVINFO *pDevInfoBuffer,
|
|
ULONG ulBufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the output DEVINFO buffer
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
pDevInfoBuffer - Points to the output DEVINFO buffer passed in from GDI
|
|
ulBufferSize - Size of the output buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
DEVINFO devinfo;
|
|
|
|
ZeroMemory(&devinfo, sizeof(devinfo));
|
|
|
|
//
|
|
// Fill in the graphics capabilities flags
|
|
// BUBUG, RMInit() function should fill out devinfo.flGraphicsCaps
|
|
// should fill this out later
|
|
//
|
|
|
|
//
|
|
// Determine whether we should do metafile spooling or not
|
|
//
|
|
|
|
if( pPDev->pdmPrivate->dwFlags & DXF_NOEMFSPOOL )
|
|
devinfo.flGraphicsCaps |= GCAPS_DONTJOURNAL;
|
|
|
|
#ifndef WINNT_40 // NT5
|
|
if (pPDev->pdmPrivate->iLayout != ONE_UP)
|
|
devinfo.flGraphicsCaps |= GCAPS_NUP;
|
|
#endif // !WINNT_40
|
|
|
|
//
|
|
// Get information about the default device font. Default size 10 point.
|
|
//
|
|
|
|
//
|
|
// BUG_BUG, RMInit() should initialize the following DEVINFO fields
|
|
// flGraphicsCaps
|
|
// iDitherFormat
|
|
// cxDither
|
|
// cyDither
|
|
// hpalDefault
|
|
//
|
|
|
|
if (ulBufferSize != sizeof(devinfo))
|
|
ERR(("Invalid DEVINFO buffer size: %d != %d\n", ulBufferSize, sizeof(devinfo)));
|
|
|
|
CopyMemory(pDevInfoBuffer, &devinfo, min(ulBufferSize, sizeof(devinfo)));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BInitCmdTable(
|
|
PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The GPD specification defines a list of predefined command. Each of these
|
|
command has an enumration value as defined in CMDINDEX enumeration.
|
|
This function will look up the indices of the predefined command and
|
|
convert them to COMMAND pointers.
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
INT iCmd;
|
|
|
|
for (iCmd = 0; iCmd < CMD_MAX; iCmd++)
|
|
{
|
|
//
|
|
// CMDPOINTER will return NULL if the predefined command
|
|
// is not supported by the device
|
|
//
|
|
|
|
pPDev->arCmdTable[iCmd] = COMMANDPTR(pPDev->pDriverInfo, iCmd);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
BInitStdTable(
|
|
PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the array of pointers to the standard variables. In the TOKENSTREAM
|
|
struct, the parser will specify the actual parameter value or reference to one
|
|
of the standard variable index defined in STDVARIABLE enumeration. The
|
|
driver use the pPDev->arStdPtrs to reference the actual values of the paramters,
|
|
which are kept in various fields of the PDEVICE.
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// BUG_BUG, need to go back and fill this table out completely once
|
|
// the FONT and RASTER PDEVICE are completely defined.
|
|
// note: I could not find any uninitialized sv_fields.
|
|
// perhaps this is too paranoid.
|
|
//
|
|
|
|
pPDev->arStdPtrs[SV_NUMDATABYTES] = &pPDev->dwNumOfDataBytes;
|
|
pPDev->arStdPtrs[SV_WIDTHINBYTES] = &pPDev->dwWidthInBytes;
|
|
pPDev->arStdPtrs[SV_HEIGHTINPIXELS] = &pPDev->dwHeightInPixels;
|
|
pPDev->arStdPtrs[SV_COPIES] = (PDWORD)&pPDev->sCopies;
|
|
pPDev->arStdPtrs[SV_PRINTDIRECTION] = &pPDev->dwPrintDirection;
|
|
pPDev->arStdPtrs[SV_DESTX] = &pPDev->ctl.ptAbsolutePos.x;
|
|
pPDev->arStdPtrs[SV_DESTY] = &pPDev->ctl.ptAbsolutePos.y;
|
|
pPDev->arStdPtrs[SV_DESTXREL] = &pPDev->ctl.ptRelativePos.x;
|
|
pPDev->arStdPtrs[SV_DESTYREL] = &pPDev->ctl.ptRelativePos.y;
|
|
pPDev->arStdPtrs[SV_LINEFEEDSPACING]= (PDWORD)&pPDev->ctl.lLineSpacing;
|
|
pPDev->arStdPtrs[SV_RECTXSIZE] = &pPDev->dwRectXSize;
|
|
pPDev->arStdPtrs[SV_RECTYSIZE] = &pPDev->dwRectYSize;
|
|
pPDev->arStdPtrs[SV_GRAYPERCENT] = &pPDev->dwGrayPercentage;
|
|
pPDev->arStdPtrs[SV_NEXTFONTID] = &pPDev->dwNextFontID;
|
|
pPDev->arStdPtrs[SV_NEXTGLYPH] = &pPDev->dwNextGlyph;
|
|
pPDev->arStdPtrs[SV_PHYSPAPERLENGTH]= &pPDev->pf.szPhysSizeM.cy;
|
|
pPDev->arStdPtrs[SV_PHYSPAPERWIDTH] = &pPDev->pf.szPhysSizeM.cx;
|
|
pPDev->arStdPtrs[SV_FONTHEIGHT] = &pPDev->dwFontHeight;
|
|
pPDev->arStdPtrs[SV_FONTWIDTH] = &pPDev->dwFontWidth;
|
|
pPDev->arStdPtrs[SV_FONTMAXWIDTH] = &pPDev->dwFontMaxWidth;
|
|
pPDev->arStdPtrs[SV_FONTBOLD] = &pPDev->dwFontBold;
|
|
pPDev->arStdPtrs[SV_FONTITALIC] = &pPDev->dwFontItalic;
|
|
pPDev->arStdPtrs[SV_FONTUNDERLINE] = &pPDev->dwFontUnderline;
|
|
pPDev->arStdPtrs[SV_FONTSTRIKETHRU] = &pPDev->dwFontStrikeThru;
|
|
pPDev->arStdPtrs[SV_CURRENTFONTID] = &pPDev->dwCurrentFontID;
|
|
pPDev->arStdPtrs[SV_TEXTYRES] = &pPDev->ptTextRes.y;
|
|
pPDev->arStdPtrs[SV_TEXTXRES] = &pPDev->ptTextRes.x;
|
|
#ifdef BETA2
|
|
pPDev->arStdPtrs[SV_GRAPHICSYRES] = &pPDev->ptGrxRes.y;
|
|
pPDev->arStdPtrs[SV_GRAPHICSXRES] = &pPDev->ptGrxRes.x;
|
|
#endif
|
|
pPDev->arStdPtrs[SV_ROP3] = &pPDev->dwRop3;
|
|
pPDev->arStdPtrs[SV_REDVALUE] = &pPDev->dwRedValue ;
|
|
pPDev->arStdPtrs[SV_GREENVALUE] = &pPDev->dwGreenValue ;
|
|
pPDev->arStdPtrs[SV_BLUEVALUE] = &pPDev->dwBlueValue ;
|
|
pPDev->arStdPtrs[SV_PALETTEINDEXTOPROGRAM] = &pPDev->dwPaletteIndexToProgram;
|
|
pPDev->arStdPtrs[SV_CURRENTPALETTEINDEX] = &pPDev->dwCurrentPaletteIndex ;
|
|
pPDev->arStdPtrs[SV_PATTERNBRUSH_TYPE] = &pPDev->dwPatternBrushType;
|
|
pPDev->arStdPtrs[SV_PATTERNBRUSH_ID] = &pPDev->dwPatternBrushID;
|
|
pPDev->arStdPtrs[SV_PATTERNBRUSH_SIZE] = &pPDev->dwPatternBrushSize;
|
|
pPDev->arStdPtrs[SV_CURSORORIGINX] = &(pPDev->sf.ptPrintOffsetM.x);
|
|
pPDev->arStdPtrs[SV_CURSORORIGINY] = &(pPDev->sf.ptPrintOffsetM.y);
|
|
pPDev->arStdPtrs[SV_PAGENUMBER] = &pPDev->dwPageNumber;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
BOOL
|
|
BMergeAndValidateDevmode(
|
|
PDEV *pPDev,
|
|
PDEVMODE pdmInput,
|
|
PRECTL prcFormImageArea
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Validate the input devmode and merge it with the defaults
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
pdmInput - Points to the input devmode passed in from GDI
|
|
prcImageArea - Returns the logical imageable area associated with the requested form
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
{
|
|
PPRINTER_INFO_2 pPrinterInfo2;
|
|
|
|
//
|
|
// Start with the driver default devmode
|
|
//
|
|
|
|
pPDev->pdm = PGetDefaultDevmodeWithOemPlugins(
|
|
NULL,
|
|
pPDev->pUIInfo,
|
|
pPDev->pRawData,
|
|
(pPDev->PrinterData.dwFlags & PFLAGS_METRIC),
|
|
pPDev->pOemPlugins,
|
|
pPDev->devobj.hPrinter);
|
|
|
|
if (pPDev->pdm == NULL)
|
|
return FALSE;
|
|
|
|
//
|
|
// Merge with system default devmode. In the case where the input devmode
|
|
// is NULL, we want to use the system default devmode.
|
|
//
|
|
|
|
pPrinterInfo2 = MyGetPrinter(pPDev->devobj.hPrinter, 2);
|
|
|
|
if (pPrinterInfo2 && pPrinterInfo2->pDevMode &&
|
|
! BValidateAndMergeDevmodeWithOemPlugins(
|
|
pPDev->pdm,
|
|
pPDev->pUIInfo,
|
|
pPDev->pRawData,
|
|
pPrinterInfo2->pDevMode,
|
|
pPDev->pOemPlugins,
|
|
pPDev->devobj.hPrinter))
|
|
{
|
|
MemFree(pPrinterInfo2);
|
|
return FALSE;
|
|
}
|
|
|
|
MemFree(pPrinterInfo2);
|
|
|
|
//
|
|
// Merge it with the input devmode
|
|
//
|
|
|
|
if (pdmInput != NULL &&
|
|
!BValidateAndMergeDevmodeWithOemPlugins(
|
|
pPDev->pdm,
|
|
pPDev->pUIInfo,
|
|
pPDev->pRawData,
|
|
pdmInput,
|
|
pPDev->pOemPlugins,
|
|
pPDev->devobj.hPrinter))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pPDev->pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pPDev->pdm);
|
|
|
|
//
|
|
// Validate form-related devmode fields and convert information
|
|
// in public devmode fields to feature option indices
|
|
//
|
|
|
|
//
|
|
// ChangeOptionsViaID expects a combined option array
|
|
//
|
|
|
|
CombineOptionArray(pPDev->pRawData,
|
|
pPDev->pOptionsArray,
|
|
MAX_PRINTER_OPTIONS,
|
|
pPDev->pdmPrivate->aOptions,
|
|
pPDev->PrinterData.aOptions
|
|
);
|
|
|
|
VFixOptionsArray( pPDev,
|
|
|
|
/* pPDev->devobj.hPrinter,
|
|
pPDev->pInfoHeader,
|
|
pPDev->pOptionsArray,
|
|
pPDev->pdm,
|
|
pPDev->PrinterData.dwFlags & PFLAGS_METRIC, */
|
|
|
|
prcFormImageArea
|
|
);
|
|
|
|
|
|
VOptionsToDevmodeFields( pPDev) ;
|
|
|
|
SeparateOptionArray(
|
|
pPDev->pRawData,
|
|
pPDev->pOptionsArray,
|
|
pPDev->pdmPrivate->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_DOCUMENT_STICKY);
|
|
|
|
pPDev->devobj.pPublicDM = pPDev->pdm;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
VOptionsToDevmodeFields(
|
|
PDEV *pPDev
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert options in pPDev->pOptionsArray into public devmode fields
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to UIDATA structure
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PFEATURE pFeature;
|
|
POPTION pOption;
|
|
DWORD dwGID, dwFeatureIndex, dwOptionIndex;
|
|
PUIINFO pUIInfo;
|
|
PDEVMODE pdm;
|
|
|
|
//
|
|
// Go through all predefine IDs and propagate the option selection
|
|
// into appropriate devmode fields
|
|
//
|
|
|
|
pUIInfo = pPDev->pUIInfo;
|
|
pdm = pPDev->pdm;
|
|
|
|
for (dwGID=0 ; dwGID < MAX_GID ; dwGID++)
|
|
{
|
|
//
|
|
// Get the feature to get the options, and get the index
|
|
// into the option array
|
|
//
|
|
|
|
if ((pFeature = GET_PREDEFINED_FEATURE(pUIInfo, dwGID)) == NULL)
|
|
{
|
|
switch(dwGID)
|
|
{
|
|
case GID_RESOLUTION:
|
|
break; // can't happen
|
|
|
|
case GID_DUPLEX:
|
|
|
|
pdm->dmFields &= ~DM_DUPLEX;
|
|
pdm->dmDuplex = DMDUP_SIMPLEX;
|
|
break;
|
|
|
|
case GID_INPUTSLOT:
|
|
|
|
pdm->dmFields &= ~DM_DEFAULTSOURCE;
|
|
pdm->dmDefaultSource = DMBIN_ONLYONE;
|
|
break;
|
|
|
|
case GID_MEDIATYPE:
|
|
|
|
pdm->dmFields &= ~DM_MEDIATYPE;
|
|
pdm->dmMediaType = DMMEDIA_STANDARD;
|
|
break;
|
|
|
|
case GID_ORIENTATION:
|
|
|
|
pdm->dmFields &= ~DM_ORIENTATION;
|
|
pdm->dmOrientation = DMORIENT_PORTRAIT;
|
|
break;
|
|
|
|
case GID_PAGESIZE: // can't happen : required feature
|
|
break;
|
|
case GID_COLLATE:
|
|
pdm->dmFields &= ~DM_COLLATE ;
|
|
pdm->dmCollate = DMCOLLATE_FALSE ;
|
|
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pFeature);
|
|
dwOptionIndex = pPDev->pOptionsArray[dwFeatureIndex].ubCurOptIndex;
|
|
|
|
//
|
|
// Get the pointer to the option array for the feature
|
|
//
|
|
|
|
if ((pOption = PGetIndexedOption(pUIInfo, pFeature, dwOptionIndex)) == NULL)
|
|
continue;
|
|
|
|
switch(dwGID)
|
|
{
|
|
case GID_RESOLUTION:
|
|
{
|
|
PRESOLUTION pRes = (PRESOLUTION)pOption;
|
|
|
|
//
|
|
// Get to the option selected
|
|
//
|
|
|
|
pdm->dmFields |= (DM_PRINTQUALITY|DM_YRESOLUTION);
|
|
pdm->dmPrintQuality = GETQUALITY_X(pRes);
|
|
pdm->dmYResolution = GETQUALITY_Y(pRes);
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_DUPLEX:
|
|
|
|
//
|
|
// Get to the option selected
|
|
//
|
|
|
|
pdm->dmFields |= DM_DUPLEX;
|
|
pdm->dmDuplex = (SHORT) ((PDUPLEX) pOption)->dwDuplexID;
|
|
break;
|
|
|
|
case GID_INPUTSLOT:
|
|
|
|
//
|
|
// Get to the option selected
|
|
//
|
|
|
|
pdm->dmFields |= DM_DEFAULTSOURCE;
|
|
pdm->dmDefaultSource = (SHORT) ((PINPUTSLOT) pOption)->dwPaperSourceID;
|
|
break;
|
|
|
|
case GID_MEDIATYPE:
|
|
|
|
//
|
|
// Get to the option selected
|
|
//
|
|
|
|
pdm->dmFields |= DM_MEDIATYPE;
|
|
pdm->dmMediaType = (SHORT) ((PMEDIATYPE) pOption)->dwMediaTypeID;
|
|
break;
|
|
|
|
case GID_ORIENTATION:
|
|
|
|
if (((PORIENTATION) pOption)->dwRotationAngle == ROTATE_NONE)
|
|
pdm->dmOrientation = DMORIENT_PORTRAIT;
|
|
else
|
|
pdm->dmOrientation = DMORIENT_LANDSCAPE;
|
|
|
|
pdm->dmFields |= DM_ORIENTATION;
|
|
break;
|
|
|
|
case GID_COLLATE:
|
|
pdm->dmFields |= DM_COLLATE ;
|
|
pdm->dmCollate = (SHORT) ((PCOLLATE) pOption)->dwCollateID ;
|
|
|
|
break;
|
|
case GID_PAGESIZE: // taken care of by BValidateDevmodeFormFields()
|
|
// which is called from init.c:VFixOptionsArray()
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
VInitOutputCTL(
|
|
PDEV *pPDev,
|
|
PRESOLUTIONEX pResEx
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes the OUTPUTCTL struct
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// Init currrent cursor position, desired absolute and relative pos
|
|
//
|
|
|
|
pPDev->ctl.ptCursor.x = pPDev->ctl.ptCursor.y = 0;
|
|
pPDev->ctl.dwMode |= MODE_CURSOR_UNINITIALIZED;
|
|
pPDev->ctl.ptRelativePos.x = pPDev->ctl.ptRelativePos.y = 0;
|
|
pPDev->ctl.ptAbsolutePos.x = pPDev->ctl.ptAbsolutePos.y = 0;
|
|
|
|
//
|
|
// Init sColor which represent last grx and text color chosen
|
|
//
|
|
|
|
if (pPDev->pUIInfo->dwFlags & FLAG_COLOR_DEVICE)
|
|
{
|
|
//
|
|
// Force sending the color command sequence before any output
|
|
//
|
|
|
|
pPDev->ctl.sColor = -1;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The device is monochrome, don't send color command sequence
|
|
// before output
|
|
//
|
|
|
|
pPDev->ctl.sColor = 0;
|
|
|
|
}
|
|
|
|
//
|
|
// Init lLineSpacing, which represents the last line spacing chosen
|
|
// init to -1 to indicate unknown state
|
|
//
|
|
|
|
pPDev->ctl.lLineSpacing = -1;
|
|
|
|
//
|
|
// Init the sBytesPerPinPass which represents the physical number
|
|
// of bytes per row of printhead
|
|
//
|
|
|
|
pPDev->ctl.sBytesPerPinPass = (SHORT)((pResEx->dwPinsPerPhysPass + 7) >> 3);
|
|
|
|
}
|
|
|
|
BOOL
|
|
BInitOptions(
|
|
PDEV *pPDev
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function looked at the currently selected UI options (stored in
|
|
DEVMODE and merged into combined options array - pDevice->pOptionsArray)
|
|
|
|
It stored the option structures for predefined features in the PDEVICE
|
|
for later access.
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to the current PDEV structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful and FALSE if not
|
|
|
|
--*/
|
|
{
|
|
|
|
WORD wGID;
|
|
PFEATURE pFeature;
|
|
DWORD dwFeatureIndex;
|
|
POPTSELECT pOptions;
|
|
|
|
|
|
pOptions = pPDev->pOptionsArray;
|
|
|
|
for ( wGID = 0 ; wGID < MAX_GID; wGID++)
|
|
{
|
|
|
|
switch (wGID)
|
|
{
|
|
case GID_RESOLUTION:
|
|
{
|
|
//
|
|
// Required feature
|
|
//
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_RESOLUTION))
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
else
|
|
return FALSE;
|
|
|
|
pPDev->pResolution = (PRESOLUTION)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
|
|
pPDev->pResolutionEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
|
|
pPDev->pResolution->GenericOption.loRenderOffset);
|
|
|
|
ASSERT(pPDev->pResolution && pPDev->pResolutionEx);
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_PAGESIZE:
|
|
{
|
|
//
|
|
// Required feature
|
|
//
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGESIZE))
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
else
|
|
return FALSE;
|
|
|
|
pPDev->pPageSize = (PPAGESIZE)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
|
|
pPDev->pPageSizeEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
|
|
pPDev->pPageSize->GenericOption.loRenderOffset);
|
|
|
|
ASSERT(pPDev->pPageSize &&
|
|
pPDev->pPageSizeEx );
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_DUPLEX:
|
|
{
|
|
//
|
|
// Optional
|
|
//
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_DUPLEX))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pDuplex = (PDUPLEX)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pDuplex = NULL;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GID_INPUTSLOT:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_INPUTSLOT))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pInputSlot = (PINPUTSLOT)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
ASSERT(pPDev->pInputSlot);
|
|
#if 0
|
|
//
|
|
// InputSlotEx struct is deleted.
|
|
//
|
|
pPDev->pInputSlotEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
|
|
pPDev->pInputSlot->GenericOption.loRenderOffset);
|
|
ASSERT(pPDev->pInputSlotEx);
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
pPDev->pInputSlot = NULL;
|
|
// pPDev->pInputSlotEx = NULL;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case GID_MEMOPTION:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_MEMOPTION))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pMemOption = (PMEMOPTION)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pMemOption = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_COLORMODE:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_COLORMODE))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pColorMode = (PCOLORMODE)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
pPDev->pColorModeEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
|
|
pPDev->pColorMode->GenericOption.loRenderOffset);
|
|
|
|
}
|
|
else
|
|
{
|
|
pPDev->pColorMode = NULL;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GID_ORIENTATION:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_ORIENTATION))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pOrientation = (PORIENTATION)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pOrientation = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_PAGEPROTECTION:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGEPROTECTION))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pPageProtect = (PPAGEPROTECT)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pPageProtect = NULL;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GID_HALFTONING:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_HALFTONING))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pHalftone = (PHALFTONING)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pHalftone = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
#if 0
|
|
|
|
case GID_MEDIATYPE:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_MEDIATYPE))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pMediaType = (PMEDIATYPE)PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pMediaType = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
case GID_COLLATE:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_COLLATE))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pCollate = PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pCollate = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case GID_OUTPUTBIN:
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_OUTPUTBIN))
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
|
|
|
|
pPDev->pOutputBin = PGetIndexedOption(
|
|
pPDev->pUIInfo,
|
|
pFeature,
|
|
pOptions[dwFeatureIndex].ubCurOptIndex);
|
|
}
|
|
else
|
|
{
|
|
pPDev->pOutputBin = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BInitPaperFormat(
|
|
PDEV *pPDev,
|
|
RECTL *pFormImageArea
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Figure out the currently selected paper size and initialize
|
|
the PAPERFORMAT & SURFACEFORMAT structs
|
|
|
|
Arguments:
|
|
|
|
pPDev - Pointer to PDEVICE
|
|
pFormImageArea - Pointer to Imageable area of the form
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
Note:
|
|
|
|
The followings are assumptions made by this function regarding information
|
|
in the parser snapshot.
|
|
|
|
- szPaperSize in PAGESIZE is always in portrait mode.
|
|
- szImageArea in PAGESIZE is always in portrait mode.
|
|
- ptImageOrigin in PAGESIZE is always in portrait mode.
|
|
- Printer cursor offset calculation is dependent of pGlobals->bRotateCoordinate.
|
|
If this is set to TRUE, must calculate it according to the rotation angle
|
|
specified in ORIENATION.dwRotationAngle
|
|
|
|
--*/
|
|
{
|
|
PPAGESIZE pPaper;
|
|
PPAGESIZEEX pPaperEx;
|
|
RECTL rcMargins, rcImgArea, rcIntersectArea;
|
|
SIZEL szPaperSize, szImageArea;
|
|
PFN_OEMTTYGetInfo pfnOemTTYGetInfo;
|
|
DWORD cbcNeeded;
|
|
BOOL bOEMinfo = FALSE ;
|
|
|
|
|
|
|
|
//
|
|
// Get the current selected paper size and paper source
|
|
//
|
|
|
|
pPaper = pPDev->pPageSize;
|
|
pPaperEx = pPDev->pPageSizeEx;
|
|
|
|
ASSERT(pPaper && pPaperEx);
|
|
|
|
//
|
|
// Convert pFormImageArea from microns to master units
|
|
//
|
|
|
|
pFormImageArea->left = MICRON_TO_MASTER(pFormImageArea->left,
|
|
pPDev->pGlobals->ptMasterUnits.x);
|
|
|
|
pFormImageArea->top = MICRON_TO_MASTER(pFormImageArea->top ,
|
|
pPDev->pGlobals->ptMasterUnits.y);
|
|
|
|
pFormImageArea->right = MICRON_TO_MASTER(pFormImageArea->right ,
|
|
pPDev->pGlobals->ptMasterUnits.x);
|
|
|
|
pFormImageArea->bottom = MICRON_TO_MASTER(pFormImageArea->bottom ,
|
|
pPDev->pGlobals->ptMasterUnits.y);
|
|
|
|
//
|
|
// If it's a user defined paper size, use the dimensions in devmode
|
|
// otherwise get it from the pagesize option
|
|
//
|
|
|
|
if (pPaper->dwPaperSizeID == DMPAPER_USER)
|
|
{
|
|
//
|
|
// Need to convert from 0.1mm to micrometer
|
|
// .1mm * 100 gives micrometer. and convert to Master unit
|
|
//
|
|
|
|
szPaperSize.cx = MICRON_TO_MASTER(
|
|
pPDev->pdm->dmPaperWidth * 100,
|
|
pPDev->pGlobals->ptMasterUnits.x);
|
|
szPaperSize.cy = MICRON_TO_MASTER(
|
|
pPDev->pdm->dmPaperLength * 100,
|
|
pPDev->pGlobals->ptMasterUnits.y);
|
|
|
|
// calculate szImageArea after margins
|
|
}
|
|
else
|
|
{
|
|
CopyMemory(&szPaperSize, &pPaper->szPaperSize, sizeof(SIZEL));
|
|
CopyMemory(&szImageArea, &pPaperEx->szImageArea, sizeof(SIZEL));
|
|
|
|
//
|
|
// Exchange X & Y dimensions: This is used only when the paper size( like
|
|
// envelopes) does not suit the printer's paper feeding method.
|
|
// equivalent to PS_ROTATE in GPC
|
|
//
|
|
|
|
if (pPaperEx->bRotateSize)
|
|
{
|
|
VSwapL(&szPaperSize.cx, &szPaperSize.cy);
|
|
VSwapL(&pFormImageArea->right, &pFormImageArea->bottom);
|
|
}
|
|
}
|
|
|
|
//
|
|
// GetPaperMargins calculates the margins based on the paper size margins,
|
|
// forms margins, and feed margins.
|
|
// rcMargins returned is in portrait mode
|
|
//
|
|
|
|
bOEMinfo = FALSE ;
|
|
|
|
if (pPDev->pGlobals->printertype == PT_TTY)
|
|
{
|
|
if (!pPDev->pOemHookInfo || !(pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pOemEntry))
|
|
return(FALSE) ; // TTY driver must support this function.
|
|
|
|
FIX_DEVOBJ(pPDev, EP_OEMTTYGetInfo);
|
|
|
|
if(pPDev->pOemEntry)
|
|
{
|
|
if( ((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
|
|
{
|
|
HRESULT hr ;
|
|
hr = HComTTYGetInfo((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
|
|
(PDEVOBJ)pPDev, OEMTTY_INFO_MARGINS, &rcMargins, sizeof(RECTL), &cbcNeeded);
|
|
if(!SUCCEEDED(hr))
|
|
bOEMinfo = FALSE ;
|
|
else
|
|
bOEMinfo = TRUE ;
|
|
|
|
}
|
|
else if( (pfnOemTTYGetInfo = (PFN_OEMTTYGetInfo)pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pfnHook) &&
|
|
(pfnOemTTYGetInfo((PDEVOBJ)pPDev, OEMTTY_INFO_MARGINS, &rcMargins, sizeof(RECTL), &cbcNeeded)))
|
|
bOEMinfo = TRUE ;
|
|
}
|
|
}
|
|
|
|
if(bOEMinfo)
|
|
{
|
|
//
|
|
// Need to convert .1mm to Master Units
|
|
//
|
|
|
|
rcMargins.left = MICRON_TO_MASTER(rcMargins.left * 100,
|
|
pPDev->pGlobals->ptMasterUnits.x);
|
|
|
|
rcMargins.top = MICRON_TO_MASTER(rcMargins.top * 100,
|
|
pPDev->pGlobals->ptMasterUnits.y);
|
|
|
|
rcMargins.right = MICRON_TO_MASTER(rcMargins.right * 100,
|
|
pPDev->pGlobals->ptMasterUnits.x);
|
|
|
|
rcMargins.bottom = MICRON_TO_MASTER(rcMargins.bottom * 100,
|
|
pPDev->pGlobals->ptMasterUnits.y);
|
|
}
|
|
else
|
|
{
|
|
VGetPaperMargins(pPDev, pPaper, pPaperEx, szPaperSize, &rcMargins);
|
|
}
|
|
|
|
if (pPaper->dwPaperSizeID == DMPAPER_USER)
|
|
{
|
|
szImageArea.cx = szPaperSize.cx - rcMargins.left - rcMargins.right;
|
|
szImageArea.cy = szPaperSize.cy - rcMargins.top - rcMargins.bottom;
|
|
}
|
|
|
|
//
|
|
// Adjust margins and szImageArea to take into account the
|
|
// form margins, just in case the form is not a built-in form
|
|
//
|
|
|
|
rcImgArea.left = rcMargins.left;
|
|
rcImgArea.top = rcMargins.top;
|
|
rcImgArea.right = rcMargins.left + szImageArea.cx;
|
|
rcImgArea.bottom = rcMargins.top + szImageArea.cy;
|
|
|
|
if (!BIntersectRect(&rcIntersectArea, &rcImgArea, pFormImageArea))
|
|
return FALSE;
|
|
|
|
rcMargins.left = rcIntersectArea.left;
|
|
rcMargins.top = rcIntersectArea.top;
|
|
rcMargins.right = szPaperSize.cx - rcIntersectArea.right;
|
|
rcMargins.bottom = szPaperSize.cy - rcIntersectArea.bottom;
|
|
szImageArea.cx = rcIntersectArea.right - rcIntersectArea.left;
|
|
szImageArea.cy = rcIntersectArea.bottom - rcIntersectArea.top;
|
|
|
|
//
|
|
// ready to initialize PAPERFORMAT struct now
|
|
//
|
|
|
|
pPDev->pf.szPhysSizeM.cx = szPaperSize.cx;
|
|
pPDev->pf.szPhysSizeM.cy = szPaperSize.cy;
|
|
pPDev->pf.szImageAreaM.cx = szImageArea.cx;
|
|
pPDev->pf.szImageAreaM.cy = szImageArea.cy;
|
|
pPDev->pf.ptImageOriginM.x = rcMargins.left;
|
|
pPDev->pf.ptImageOriginM.y = rcMargins.top;
|
|
|
|
//
|
|
// Now, take current orientation into consideration and set up
|
|
// SURFACEFORMAT struct.
|
|
// Note that pPDev->ptGrxScale has alreay been rotated to suit the orientation.
|
|
//
|
|
if (pPDev->pdm->dmOrientation == DMORIENT_LANDSCAPE)
|
|
{
|
|
pPDev->sf.szPhysPaperG.cx = szPaperSize.cy / pPDev->ptGrxScale.x;
|
|
pPDev->sf.szPhysPaperG.cy = szPaperSize.cx / pPDev->ptGrxScale.y;
|
|
|
|
pPDev->sf.szImageAreaG.cx = szImageArea.cy / pPDev->ptGrxScale.x;
|
|
pPDev->sf.szImageAreaG.cy = szImageArea.cx / pPDev->ptGrxScale.y;
|
|
|
|
//
|
|
// 2 scenarios for landscape mode
|
|
// CC_90, rotate CC 90 degrees, for dot matrix style printers
|
|
// CC_270, rotate CC 270 degrees, for Laser Jet style printers
|
|
//
|
|
|
|
if ( pPDev->pOrientation && pPDev->pOrientation->dwRotationAngle == ROTATE_90)
|
|
{
|
|
pPDev->sf.ptImageOriginG.x = rcMargins.bottom / pPDev->ptGrxScale.x;
|
|
pPDev->sf.ptImageOriginG.y = rcMargins.left / pPDev->ptGrxScale.y;
|
|
}
|
|
else
|
|
{
|
|
pPDev->sf.ptImageOriginG.x = rcMargins.top / pPDev->ptGrxScale.x;
|
|
pPDev->sf.ptImageOriginG.y = rcMargins.right / pPDev->ptGrxScale.y;
|
|
}
|
|
|
|
if (!pPDev->pOrientation || pPDev->pGlobals->bRotateCoordinate == FALSE)
|
|
{
|
|
pPDev->sf.ptPrintOffsetM.x = pPDev->pf.ptImageOriginM.x - pPaperEx->ptPrinterCursorOrig.x;
|
|
pPDev->sf.ptPrintOffsetM.y = pPDev->pf.ptImageOriginM.y - pPaperEx->ptPrinterCursorOrig.y;
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( pPDev->pOrientation->dwRotationAngle == ROTATE_90)
|
|
{
|
|
pPDev->sf.ptPrintOffsetM.x =
|
|
rcMargins.bottom + pPaperEx->ptPrinterCursorOrig.y - pPDev->pf.szPhysSizeM.cy;
|
|
pPDev->sf.ptPrintOffsetM.y =
|
|
rcMargins.left - pPaperEx->ptPrinterCursorOrig.x;
|
|
}
|
|
else
|
|
{
|
|
pPDev->sf.ptPrintOffsetM.x =
|
|
rcMargins.top - pPaperEx->ptPrinterCursorOrig.y;
|
|
pPDev->sf.ptPrintOffsetM.y =
|
|
rcMargins.right + pPaperEx->ptPrinterCursorOrig.x - pPDev->pf.szPhysSizeM.cx;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPDev->sf.szPhysPaperG.cx = szPaperSize.cx / pPDev->ptGrxScale.x;
|
|
pPDev->sf.szPhysPaperG.cy = szPaperSize.cy / pPDev->ptGrxScale.y;
|
|
pPDev->sf.szImageAreaG.cx = szImageArea.cx / pPDev->ptGrxScale.x;
|
|
pPDev->sf.szImageAreaG.cy = szImageArea.cy / pPDev->ptGrxScale.y;
|
|
|
|
pPDev->sf.ptImageOriginG.x = rcMargins.left / pPDev->ptGrxScale.x;
|
|
pPDev->sf.ptImageOriginG.y = rcMargins.top / pPDev->ptGrxScale.y;
|
|
|
|
pPDev->sf.ptPrintOffsetM.x = pPDev->pf.ptImageOriginM.x - pPaperEx->ptPrinterCursorOrig.x;
|
|
pPDev->sf.ptPrintOffsetM.y = pPDev->pf.ptImageOriginM.y - pPaperEx->ptPrinterCursorOrig.y;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
VGetPaperMargins(
|
|
PDEV *pPDev,
|
|
PAGESIZE *pPageSize,
|
|
PAGESIZEEX *pPageSizeEx,
|
|
SIZEL szPhysSize,
|
|
PRECTL prcMargins
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Calculate the margins based on paper margins and the input slot feed margins.
|
|
|
|
Arguments:
|
|
|
|
pPDev - Pointer to PDEVICE
|
|
pPageSize - pointer to PAGESIZE
|
|
pPageSizeEx - Pointer to PAGESIZEEX
|
|
szPhysSize - physical dimensions (after applying *RotateSize?)
|
|
prcMargins - Pointer to RECTL to hold the margins calculated
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Note:
|
|
|
|
All margins calculations are in Portrait mode.
|
|
The margins returned in prcMargins are in portrait mode
|
|
|
|
Assumed that physical paper size, image area, and image origin in binary
|
|
data are in portrait mode.
|
|
|
|
--*/
|
|
{
|
|
if (pPageSize->dwPaperSizeID == DMPAPER_USER)
|
|
{
|
|
if(pPageSizeEx->strCustCursorOriginX.dwCount == 5 &&
|
|
pPageSizeEx->strCustCursorOriginY.dwCount == 5 &&
|
|
pPageSizeEx->strCustPrintableOriginX.dwCount == 5 &&
|
|
pPageSizeEx->strCustPrintableOriginY.dwCount == 5 &&
|
|
pPageSizeEx->strCustPrintableSizeX.dwCount == 5 &&
|
|
pPageSizeEx->strCustPrintableSizeY.dwCount == 5 ) // if all parameters present...
|
|
{
|
|
SIZEL szImageArea; // *PrintableArea, for CUSTOMSIZE options
|
|
POINT ptImageOrigin; // *PrintableOrigin, for CUSTOMSIZE options
|
|
BYTE *pInvocationStr; // points to parameter reference: "%dddd"
|
|
PARAMETER *pParameter; // points to parameter structure referenced by "%dddd"
|
|
BOOL bMaxRepeat = FALSE; // dummy placeholder.
|
|
|
|
|
|
// init standard variable for papersize! since these are not yet initialized at this time!
|
|
// this implies GPD writer may only reference the standard vars "PhysPaperLength"
|
|
// and "PhysPaperWidth" in these parameters.
|
|
|
|
pPDev->pf.szPhysSizeM.cx = szPhysSize.cx;
|
|
pPDev->pf.szPhysSizeM.cy = szPhysSize.cy;
|
|
pPDev->arStdPtrs[SV_PHYSPAPERLENGTH]= &pPDev->pf.szPhysSizeM.cy;
|
|
pPDev->arStdPtrs[SV_PHYSPAPERWIDTH] = &pPDev->pf.szPhysSizeM.cx;
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustCursorOriginX.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
pPageSizeEx->ptPrinterCursorOrig.x = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustCursorOriginY.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
pPageSizeEx->ptPrinterCursorOrig.y = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableOriginX.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
ptImageOrigin.x = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableOriginY.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
ptImageOrigin.y = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableSizeX.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
szImageArea.cx = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableSizeY.loOffset);
|
|
// pInvocationStr[0] == '%'
|
|
pParameter = PGetParameter(pPDev, pInvocationStr + 1);
|
|
szImageArea.cy = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
|
|
|
|
prcMargins->left = ptImageOrigin.x;
|
|
prcMargins->top = ptImageOrigin.y;
|
|
prcMargins->right = szPhysSize.cx - szImageArea.cx - ptImageOrigin.x;
|
|
prcMargins->bottom = szPhysSize.cy - szImageArea.cy - ptImageOrigin.y;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwHorMargin, dwLeftMargin;
|
|
|
|
//
|
|
// calculate the margins and printable area based on info in pPageSizeEx
|
|
//
|
|
prcMargins->top = pPageSizeEx->dwTopMargin;
|
|
prcMargins->bottom = pPageSizeEx->dwBottomMargin;
|
|
|
|
//
|
|
// Calculate the horizontal margin and adjust it if the user specified
|
|
// centering the printable area along the paper path
|
|
//
|
|
if((DWORD)szPhysSize.cx < pPageSizeEx->dwMaxPrintableWidth)
|
|
dwHorMargin = 0;
|
|
else
|
|
dwHorMargin = szPhysSize.cx - pPageSizeEx->dwMaxPrintableWidth;
|
|
//
|
|
// Determine the horizontal margins. If they are centered, then the
|
|
// Left margin is simply the overall divided in two. But, we need to
|
|
// consider both the printer's and form's margins, and choose the largest.
|
|
//
|
|
if( pPageSizeEx->bCenterPrintArea)
|
|
dwLeftMargin = (dwHorMargin / 2);
|
|
else
|
|
dwLeftMargin = 0;
|
|
|
|
prcMargins->left = dwLeftMargin < pPageSizeEx->dwMinLeftMargin ?
|
|
pPageSizeEx->dwMinLeftMargin : dwLeftMargin;
|
|
|
|
if( dwHorMargin > (DWORD)prcMargins->left ) // still have margin to distribute
|
|
prcMargins->right = dwHorMargin - prcMargins->left;
|
|
else
|
|
prcMargins->right = 0;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
prcMargins->left = pPageSizeEx->ptImageOrigin.x;
|
|
prcMargins->top = pPageSizeEx->ptImageOrigin.y;
|
|
prcMargins->right = szPhysSize.cx - pPageSizeEx->szImageArea.cx
|
|
- pPageSizeEx->ptImageOrigin.x;
|
|
prcMargins->bottom = szPhysSize.cy - pPageSizeEx->szImageArea.cy
|
|
- pPageSizeEx->ptImageOrigin.y;
|
|
|
|
}
|
|
|
|
//
|
|
// All margins are positive or zero
|
|
//
|
|
|
|
if( prcMargins->top < 0 )
|
|
prcMargins->top = 0;
|
|
|
|
if( prcMargins->bottom < 0 )
|
|
prcMargins->bottom = 0;
|
|
|
|
if( prcMargins->left < 0 )
|
|
prcMargins->left = 0;
|
|
|
|
if( prcMargins->right < 0 )
|
|
prcMargins->right = 0;
|
|
|
|
}
|
|
|
|
VOID
|
|
VInitFYMove(
|
|
PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the fYMove flag in PDEVICE from reading the
|
|
YMoveAttributes keyword
|
|
|
|
Arguments:
|
|
|
|
pPDEV - Pointer to PDEVICE
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PLISTNODE pListNode = LISTNODEPTR(pPDev->pDriverInfo,
|
|
pPDev->pGlobals->liYMoveAttributes);
|
|
pPDev->fYMove = 0;
|
|
|
|
while (pListNode)
|
|
{
|
|
|
|
if (pListNode->dwData == YMOVE_FAVOR_LINEFEEDSPACING)
|
|
pPDev->fYMove |= FYMOVE_FAVOR_LINEFEEDSPACING;
|
|
|
|
if (pListNode->dwData == YMOVE_SENDCR_FIRST)
|
|
pPDev->fYMove |= FYMOVE_SEND_CR_FIRST;
|
|
|
|
if (pListNode->dwNextItem == END_OF_LIST)
|
|
break;
|
|
else
|
|
pListNode = LISTNODEPTR(pPDev->pDriverInfo,
|
|
pListNode->dwNextItem);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
VInitFMode(
|
|
PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the fMode flag in PDEVICE to reflect the settings saved
|
|
in Devmode.dmPrivate.dwFlags AND to reflect the device capabilities
|
|
|
|
Arguments:
|
|
|
|
pPDEV - Pointer to PDEVICE
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (pPDev->pdmPrivate->dwFlags & DXF_NOEMFSPOOL)
|
|
pPDev->fMode |= PF_NOEMFSPOOL;
|
|
|
|
//
|
|
// Adjust memory for page protection only if the user selects
|
|
// to turn on page protection and this feature exists.
|
|
//
|
|
|
|
if ( (pPDev->PrinterData.dwFlags & PFLAGS_PAGE_PROTECTION) &&
|
|
pPDev->pPageProtect &&
|
|
(pPDev->pPageProtect->dwPageProtectID == PAGEPRO_ON) )
|
|
{
|
|
//
|
|
// Look up the page protection value in the PAGESIZE struct for the
|
|
// paper size selected
|
|
//
|
|
|
|
DWORD dwPageMem = pPDev->pPageSize->dwPageProtectionMemory;
|
|
|
|
if (dwPageMem < pPDev->dwFreeMem)
|
|
{
|
|
pPDev->fMode |= PF_PAGEPROTECT;
|
|
pPDev->dwFreeMem -= dwPageMem;
|
|
}
|
|
|
|
ASSERT(pPDev->dwFreeMem > 0);
|
|
}
|
|
|
|
//
|
|
// Check whether the device can do landscape rotation
|
|
//
|
|
if (pPDev->pOrientation && pPDev->pOrientation->dwRotationAngle != ROTATE_NONE &&
|
|
pPDev->pGlobals->bRotateRasterData == FALSE)
|
|
{
|
|
//
|
|
// bRotateRasterData is set to TRUE if the device can rotate
|
|
// graphics data. Otherwise, the driver will have to do it.
|
|
// PF_ROTATE is set to indicate that the driver needs to rotate
|
|
// the graphics data, for when we do banding.
|
|
//
|
|
|
|
pPDev->fMode |= PF_ROTATE;
|
|
|
|
if (pPDev->pOrientation->dwRotationAngle == ROTATE_90)
|
|
pPDev->fMode |= PF_CCW_ROTATE90;
|
|
}
|
|
|
|
//
|
|
// Init X and Y move CMD capabilities
|
|
//
|
|
|
|
if (pPDev->arCmdTable[CMD_XMOVERELLEFT] == NULL &&
|
|
pPDev->arCmdTable[CMD_XMOVERELRIGHT] == NULL)
|
|
{
|
|
pPDev->fMode |= PF_NO_RELX_MOVE;
|
|
}
|
|
|
|
if (pPDev->arCmdTable[CMD_YMOVERELUP] == NULL &&
|
|
pPDev->arCmdTable[CMD_YMOVERELDOWN] == NULL)
|
|
{
|
|
pPDev->fMode |= PF_NO_RELY_MOVE;
|
|
}
|
|
|
|
if (pPDev->arCmdTable[CMD_XMOVEABSOLUTE] == NULL &&
|
|
pPDev->arCmdTable[CMD_XMOVERELRIGHT] == NULL)
|
|
{
|
|
pPDev->fMode |= PF_NO_XMOVE_CMD;
|
|
}
|
|
|
|
if (pPDev->arCmdTable[CMD_YMOVEABSOLUTE] == NULL &&
|
|
pPDev->arCmdTable[CMD_YMOVERELDOWN] == NULL)
|
|
{
|
|
pPDev->fMode |= PF_NO_YMOVE_CMD;
|
|
}
|
|
|
|
if (pPDev->arCmdTable[CMD_SETRECTWIDTH] != NULL &&
|
|
pPDev->arCmdTable[CMD_SETRECTHEIGHT] != NULL)
|
|
{
|
|
pPDev->fMode |= PF_RECT_FILL;
|
|
}
|
|
|
|
if (pPDev->arCmdTable[CMD_RECTWHITEFILL] != NULL)
|
|
pPDev->fMode |= PF_RECTWHITE_FILL;
|
|
|
|
//
|
|
// Init brush selection capabilities
|
|
//
|
|
|
|
if (pPDev->arCmdTable[CMD_DOWNLOAD_PATTERN] )
|
|
pPDev->fMode |= PF_DOWNLOAD_PATTERN;
|
|
|
|
if (pPDev->arCmdTable[CMD_SELECT_PATTERN])
|
|
pPDev->fMode |= PF_SHADING_PATTERN;
|
|
|
|
//
|
|
// BUG_BUG, need to get rid of CMD_WHITETEXTON, CMD_WHITETEXTOFF once
|
|
// all the GPD changes have completed for CMD_SELECT_WHITEBRUSH, CMD_SELECT_BLACKBRUSH
|
|
// no harm done either way.
|
|
|
|
if ( (pPDev->arCmdTable[CMD_SELECT_WHITEBRUSH] &&
|
|
pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH]) ||
|
|
(pPDev->arCmdTable[CMD_WHITETEXTON] &&
|
|
pPDev->arCmdTable[CMD_WHITETEXTOFF]) )
|
|
pPDev->fMode |= PF_WHITEBLACK_BRUSH;
|
|
|
|
//
|
|
// Init raster mirroring flag
|
|
//
|
|
if (pPDev->pGlobals->bMirrorRasterPage)
|
|
pPDev->fMode2 |= PF2_MIRRORING_ENABLED;
|
|
|
|
}
|
|
|
|
|
|
INT
|
|
iHypot(
|
|
INT iX,
|
|
INT iY
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Calculates the length of the hypotenous of a right triangle whose
|
|
sides are passed in as parameters
|
|
|
|
Arguments:
|
|
|
|
iX, iY - Sides of a right triangle
|
|
|
|
Return Value:
|
|
|
|
The hypotenous of the triangle
|
|
|
|
--*/
|
|
{
|
|
register INT iHypo;
|
|
|
|
INT iDelta, iTarget;
|
|
|
|
/*
|
|
* Finds the hypoteneous of a right triangle with legs equal to x
|
|
* and y. Assumes x, y, hypo are integers.
|
|
* Use sq(x) + sq(y) = sq(hypo);
|
|
* Start with MAX(x, y),
|
|
* use sq(x + 1) = sq(x) + 2x + 1 to incrementally get to the
|
|
* target hypotenouse.
|
|
*/
|
|
|
|
iHypo = max( iX, iY );
|
|
iTarget = min( iX,iY );
|
|
iTarget = iTarget * iTarget;
|
|
|
|
for( iDelta = 0; iDelta < iTarget; iHypo++ )
|
|
iDelta += (iHypo << 1) + 1;
|
|
|
|
|
|
return iHypo;
|
|
}
|
|
|
|
|
|
INT
|
|
iGCD(
|
|
INT i0,
|
|
INT i1
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Calculates the Greatest Common Divisor. Use Euclid's algorith.
|
|
|
|
Arguments:
|
|
|
|
i0, i1 - the first and second number
|
|
|
|
Return Value:
|
|
|
|
The greatest common divisor
|
|
|
|
--*/
|
|
{
|
|
int iRem; /* Will be the remainder */
|
|
|
|
|
|
if( i0 < i1 )
|
|
{
|
|
/* Need to interchange them */
|
|
iRem = i0;
|
|
i0 = i1;
|
|
i1 = iRem;
|
|
}
|
|
|
|
while( iRem = (i0 % i1) )
|
|
{
|
|
/* Step along to the next value */
|
|
i0 = i1;
|
|
i1 = iRem;
|
|
}
|
|
|
|
return i1; /* The answer! */
|
|
}
|
|
|
|
BOOL
|
|
BIntersectRect(
|
|
OUT PRECTL prcDest,
|
|
IN PRECTL prcRect1,
|
|
IN PRECTL prcRect2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Intersect the Rec1 and Rect2
|
|
and store the result in the destination rectangle
|
|
|
|
Arguments:
|
|
|
|
prcDest - Points to the destination rectangle
|
|
prcSrc - Points to the source rectangle
|
|
|
|
Return Value:
|
|
|
|
FALSE if the intersected rectangle is empty
|
|
TRUE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
ASSERT(prcDest != NULL && prcRect1 != NULL && prcRect2 != NULL);
|
|
|
|
if (prcRect1->left < prcRect2->left)
|
|
prcDest->left = prcRect2->left;
|
|
else
|
|
prcDest->left = prcRect1->left;
|
|
|
|
|
|
if (prcRect1->top < prcRect2->top)
|
|
prcDest->top = prcRect2->top;
|
|
else
|
|
prcDest->top = prcRect1->top;
|
|
|
|
if (prcRect1->right > prcRect2->right)
|
|
prcDest->right = prcRect2->right;
|
|
else
|
|
prcDest->right = prcRect1->right;
|
|
|
|
if (prcRect1->bottom > prcRect2->bottom)
|
|
prcDest->bottom = prcRect2->bottom;
|
|
else
|
|
prcDest->bottom = prcRect1->bottom;
|
|
|
|
return (prcDest->right > prcDest->left) &&
|
|
(prcDest->bottom > prcDest->top);
|
|
}
|
|
|
|
|
|
VOID
|
|
SetRop3(
|
|
PDEV *pPDev,
|
|
DWORD dwRop3
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function set the Rop3 value for the Raster and Font module
|
|
|
|
Arguments:
|
|
pPDev Pointer to PDEVICE
|
|
dwRop3 Rop3 value
|
|
Return Value:
|
|
|
|
FALSE if the intersected rectangle is empty
|
|
TRUE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
ASSERT(VALID_PDEV(pPDev));
|
|
|
|
pPDev->dwRop3 = dwRop3;
|
|
|
|
}
|
|
|
|
VOID
|
|
VUnloadFreeBinaryData(
|
|
IN PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function frees the binary data
|
|
|
|
Arguments:
|
|
|
|
pPDev - Pointer to PDEV
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
INT iCmd;
|
|
|
|
//
|
|
// Call parser to free memory allocated for binary data
|
|
//
|
|
|
|
if (pPDev->pRawData)
|
|
UnloadRawBinaryData(pPDev->pRawData);
|
|
|
|
if (pPDev->pInfoHeader)
|
|
FreeBinaryData(pPDev->pInfoHeader);
|
|
|
|
pPDev->pRawData = NULL;
|
|
pPDev->pInfoHeader = NULL;
|
|
pPDev->pUIInfo = NULL;
|
|
//
|
|
// pPDev->pUIInfo is reset so update the winresdata pUIInfo also.
|
|
//
|
|
pPDev->WinResData.pUIInfo = NULL;
|
|
|
|
pPDev->pDriverInfo = NULL;
|
|
pPDev->pGlobals = NULL;
|
|
|
|
for (iCmd = 0; iCmd < CMD_MAX; iCmd++)
|
|
{
|
|
pPDev->arCmdTable[iCmd] = NULL;
|
|
}
|
|
|
|
pPDev->pOrientation = NULL;
|
|
pPDev->pResolution = NULL;
|
|
pPDev->pResolutionEx = NULL;
|
|
pPDev->pColorMode = NULL;
|
|
pPDev->pColorModeEx = NULL;
|
|
pPDev->pDuplex = NULL;
|
|
pPDev->pPageSize = NULL;
|
|
pPDev->pPageSizeEx = NULL;
|
|
pPDev->pInputSlot = NULL;
|
|
pPDev->pMemOption = NULL;
|
|
pPDev->pHalftone = NULL;
|
|
pPDev->pPageProtect = NULL;
|
|
|
|
}
|
|
|
|
BOOL
|
|
BReloadBinaryData(
|
|
IN PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function reloads the binary data and reinitializes the
|
|
offsets and pointers for access to snapshot data
|
|
|
|
Arguments:
|
|
|
|
pPDev - Pointer to PDEV
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE if successful, otherwise FALSE
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Reloads binary data and reinit data pointers
|
|
//
|
|
|
|
if (! (pPDev->pRawData = LoadRawBinaryData(pPDev->pDriverInfo3->pDataFile)) ||
|
|
! (pPDev->pInfoHeader = InitBinaryData(pPDev->pRawData, NULL, pPDev->pOptionsArray)) ||
|
|
! (pPDev->pDriverInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loDriverOffset)) ||
|
|
! (pPDev->pUIInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loUIInfoOffset)) ||
|
|
! (pPDev->pGlobals = &(pPDev->pDriverInfo->Globals)) )
|
|
return FALSE;
|
|
|
|
//
|
|
// pPDev->pUIInfo is reset so update the winresdata pUIInfo also.
|
|
//
|
|
pPDev->WinResData.pUIInfo = pPDev->pUIInfo;
|
|
|
|
//
|
|
// Rebuilds the command table
|
|
//
|
|
|
|
if (BInitCmdTable(pPDev) == FALSE)
|
|
return FALSE;
|
|
|
|
//
|
|
// Rebuilds all the options pointers in PDEV
|
|
//
|
|
|
|
if (BInitOptions(pPDev) == FALSE)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|