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.
853 lines
28 KiB
853 lines
28 KiB
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
semanchk.c
|
|
|
|
Abstract:
|
|
|
|
function for checking GPD semantics which involves dependency between
|
|
entries.
|
|
|
|
Environment:
|
|
|
|
user-mode only.
|
|
|
|
Revision History:
|
|
|
|
02/15/97 -zhanw-
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#ifndef KERNEL_MODE
|
|
|
|
#include "gpdparse.h"
|
|
|
|
|
|
// ---- functions defined in semanchk.c ---- //
|
|
|
|
BOOL
|
|
BCheckGPDSemantics(
|
|
IN PINFOHEADER pInfoHdr,
|
|
POPTSELECT poptsel // assume fully initialized
|
|
) ;
|
|
|
|
// ------- end function declarations ------- //
|
|
|
|
|
|
BOOL
|
|
BCheckGPDSemantics(
|
|
IN PINFOHEADER pInfoHdr,
|
|
POPTSELECT poptsel // assume fully initialized
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function checks if the given snapshot makes sense. It covers only
|
|
conditionally required entries and printing commands since other
|
|
statically required entries are already covered by snapshot functions.
|
|
|
|
Arguments:
|
|
pInfoHdr: pointer to INFOHEADER structure.
|
|
|
|
Return Value:
|
|
TRUE if the semantics is correct. Otherwise, FALSE.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwFeaIndex, dwI, dwNumOpts, dwListIndex ,
|
|
dwMoveUnitsX, dwMoveUnitsY, dwResX, dwResY ;
|
|
BOOL bStatus = TRUE ; // until fails.
|
|
PGPDDRIVERINFO pDrvInfo ;
|
|
PUIINFO pUIInfo ;
|
|
PFEATURE pFeature ;
|
|
|
|
|
|
if(!pInfoHdr)
|
|
return FALSE ;
|
|
pDrvInfo = (PGPDDRIVERINFO) GET_DRIVER_INFO_FROM_INFOHEADER(pInfoHdr) ;
|
|
if(!pDrvInfo)
|
|
return FALSE ;
|
|
pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ;
|
|
if(!pUIInfo)
|
|
return FALSE ;
|
|
|
|
|
|
// Fix for bug 6774
|
|
|
|
if(pUIInfo->dwPrintRate && (pUIInfo->dwPrintRateUnit == INVALID_INDEX))
|
|
{
|
|
ERR(("*PrintRateUnit must be present if *PrintRate exists.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
// end fix for bug 6774
|
|
|
|
//
|
|
// 1. global printing entries
|
|
//
|
|
// - *MemoryUsage cannot be an empty list if *Memory feature exists.
|
|
//
|
|
// - *XMoveUnit (*YMoveUnit) must be non-trivial (greater than 1) if
|
|
// there is any x-move (y-move) command.
|
|
//
|
|
// - *DefaultFont cannot be 0 if *DeviceFonts is not an empty list.
|
|
//
|
|
// - CmdCR, CmdLF, and CmdFF are always required.
|
|
//
|
|
|
|
|
|
|
|
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_MEMOPTION ) &&
|
|
(pDrvInfo->Globals.liMemoryUsage == END_OF_LIST) )
|
|
{
|
|
ERR(("*MemoryUsage cannot be an empty list if *Memory feature exists.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
}
|
|
|
|
|
|
if((COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_XMOVERELLEFT ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT )) &&
|
|
pDrvInfo->Globals.ptDeviceUnits.x <= 1)
|
|
{
|
|
ERR(("*XMoveUnit must be > 1 if any x-move command exists.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if((COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_YMOVERELUP ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN )) &&
|
|
pDrvInfo->Globals.ptDeviceUnits.y <= 1)
|
|
{
|
|
ERR(("*YMoveUnit must be > 1 if any y-move command exists.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if((pDrvInfo->Globals.liDeviceFontList != END_OF_LIST) &&
|
|
(pDrvInfo->Globals.dwDefaultFont == 0) )
|
|
{
|
|
ERR(("*DefaultFont cannot be 0 if *DeviceFonts is not an empty list.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
}
|
|
|
|
if (!COMMANDPTR(pDrvInfo , CMD_FORMFEED ) ||
|
|
!COMMANDPTR(pDrvInfo , CMD_CARRIAGERETURN ) ||
|
|
!COMMANDPTR(pDrvInfo , CMD_LINEFEED ) )
|
|
{
|
|
ERR(("CmdCR, CmdLF, and CmdFF are always required.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
// are there an integral number of master units per
|
|
// moveunit?
|
|
|
|
if( pDrvInfo->Globals.ptMasterUnits.x %
|
|
pDrvInfo->Globals.ptDeviceUnits.x )
|
|
{
|
|
ERR(("Must be whole number of master units per x move unit.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
if( pDrvInfo->Globals.ptMasterUnits.y %
|
|
pDrvInfo->Globals.ptDeviceUnits.y )
|
|
{
|
|
ERR(("Must be whole number of master units per y move unit.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if(pDrvInfo->Globals.ptDeviceUnits.x > 1)
|
|
{
|
|
dwMoveUnitsX = pDrvInfo->Globals.ptMasterUnits.x /
|
|
pDrvInfo->Globals.ptDeviceUnits.x ;
|
|
}
|
|
else
|
|
dwMoveUnitsX = 1 ;
|
|
|
|
if(pDrvInfo->Globals.ptDeviceUnits.y > 1)
|
|
{
|
|
dwMoveUnitsY = pDrvInfo->Globals.ptMasterUnits.y /
|
|
pDrvInfo->Globals.ptDeviceUnits.y ;
|
|
}
|
|
else
|
|
dwMoveUnitsY = 1 ;
|
|
|
|
if(!dwMoveUnitsX || !dwMoveUnitsY)
|
|
{
|
|
ERR(("master units cannot be coarser than X or Y MoveUnit.\n")) ;
|
|
return FALSE ;
|
|
}
|
|
|
|
|
|
//
|
|
// 2. printing commands
|
|
//
|
|
// - if *XMoveThreshold (*YMoveThreshold) is 0, then CmdXMoveAbsolute
|
|
// (CmdYMoveAbsolute) must exist. Similarly, if *XMoveThreshold
|
|
// (*YMoveThreshold) is *, then CmdXMoveRelRight (CmdYMoveRelDown and
|
|
// (CmdYMoveRelUp) must exist.
|
|
//
|
|
|
|
#if 0
|
|
// if Threshold is omitted by user, its set to 0 by default
|
|
// by the snapshot code. So this check will fail when
|
|
// everything is ok.
|
|
|
|
|
|
if((pDrvInfo->Globals.dwXMoveThreshold == 0) &&
|
|
!COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE ))
|
|
{
|
|
ERR(("*CmdXMoveAbsolute must exist if *XMoveThreshold is 0.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if((pDrvInfo->Globals.dwYMoveThreshold == 0) &&
|
|
!COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE ))
|
|
{
|
|
ERR(("*CmdYMoveAbsolute must exist if *YMoveThreshold is 0.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
#endif
|
|
|
|
|
|
if((pDrvInfo->Globals.dwXMoveThreshold == WILDCARD_VALUE) &&
|
|
!COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT ) )
|
|
{
|
|
ERR(("XMoveRelativeRight must exist if *XMoveThreshold is *.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if((pDrvInfo->Globals.dwYMoveThreshold == WILDCARD_VALUE) &&
|
|
!COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN ))
|
|
{
|
|
ERR(("YMoveRelativeDown must exist if *YMoveThreshold is *.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
// - CmdSendBlockData must exist if *PrinterType is not TTY.
|
|
|
|
if((pDrvInfo->Globals.printertype != PT_TTY) &&
|
|
!COMMANDPTR(pDrvInfo , CMD_SENDBLOCKDATA ))
|
|
{
|
|
ERR(("*CmdSendBlockData must exist if *PrinterType is not TTY.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
|
|
//
|
|
// - CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be consistent
|
|
// in their presence (i.e. all or none). Furthermore, if
|
|
// CmdSetFontID/CmdSelectFontID/CmdSetCharCode all exist, then
|
|
// *FontFormat must be one of the pre-defined constants.
|
|
//
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_SETFONTID ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_SELECTFONTID ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_SETCHARCODE ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 3)
|
|
{
|
|
ERR(("CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be present or absent together.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if((dwI == 3) && (pDrvInfo->Globals.fontformat == UNUSED_ITEM) )
|
|
{
|
|
ERR(("if font cmds exist, then *FontFormat must be defined\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
|
|
// - CmdBoldOn and CmdBoldOff must be paired (i.e. both or none). The
|
|
// same goes for:
|
|
// CmdItalicOn & CmdItalicOff,
|
|
// CmdUnderlineOn & CmdUnderlineOff,
|
|
// CmdStrikeThruOn & CmdStrikeThruOff,
|
|
// CmdWhiteTextOn & CmdWhiteTextOff,
|
|
// CmdSelectSingleByteMode & CmdSelectDoubleByteMode,
|
|
// CmdVerticalPrintingOn/CmdVerticalPrintingOff.
|
|
//
|
|
// - CmdSetRectWidth and CmdSetRectHeight must be paired.
|
|
//
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_BOLDON ) )
|
|
dwI++ ;
|
|
if(dwI && (COMMANDPTR(pDrvInfo , CMD_BOLDOFF ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdBoldOn and CmdBoldOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_ITALICON) )
|
|
dwI++ ;
|
|
if(dwI && (COMMANDPTR(pDrvInfo , CMD_ITALICOFF ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdItalicOn & CmdItalicOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_UNDERLINEON ) )
|
|
dwI++ ;
|
|
if(dwI && (COMMANDPTR(pDrvInfo , CMD_UNDERLINEOFF ) ||
|
|
COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdUnderlineOn & CmdUnderlineOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUON ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUOFF ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdStrikeThruOn & CmdStrikeThruOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTON ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTOFF ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdWhiteTextOn & CmdWhiteTextOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_SELECTSINGLEBYTEMODE ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_SELECTDOUBLEBYTEMODE ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdSelectSingleByteMode & CmdSelectDoubleByteMode must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGON ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGOFF ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdVerticalPrintingOn/CmdVerticalPrintingOff must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwI = 0 ;
|
|
|
|
if(COMMANDPTR(pDrvInfo , CMD_SETRECTWIDTH ) )
|
|
dwI++ ;
|
|
if(COMMANDPTR(pDrvInfo , CMD_SETRECTHEIGHT ) )
|
|
dwI++ ;
|
|
|
|
if(dwI && dwI != 2)
|
|
{
|
|
ERR(("CmdSetRectWidth and CmdSetRectHeight must be paired.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
|
|
|
|
// Note because this check involves looking at the command table
|
|
// which is snapshot specific, we cannot perform this for every
|
|
// option as Zhanw requested. Only the current option.
|
|
//
|
|
// 3. special entries in various types of *Option constructs
|
|
//
|
|
// - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
|
|
// *ColorPlaneOrder cannot be an empty list.
|
|
//
|
|
// - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
|
|
// and *DevBPP is 1, search through its *ColorPlaneOrder list:
|
|
// if YELLOW is in the list, then CmdSendYellowData must exist. The
|
|
// same goes for other colors: MAGENTA, CYAN, BLACK, RED, GREEN, BLUE.
|
|
|
|
pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ;
|
|
|
|
pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_COLORMODE) ;
|
|
if(pFeature)
|
|
{
|
|
PCOLORMODE pColorMode ;
|
|
PCOLORMODEEX pCMex ;
|
|
PLISTNODE pLNode ;
|
|
DWORD dwOptIndex ;
|
|
|
|
|
|
dwNumOpts = pFeature->Options.dwCount ;
|
|
|
|
pColorMode = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
|
|
|
|
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_COLORMODE ) )
|
|
{
|
|
dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ;
|
|
|
|
|
|
pCMex = OFFSET_TO_POINTER(pInfoHdr,
|
|
pColorMode[dwOptIndex].GenericOption.loRenderOffset) ;
|
|
|
|
if((pCMex->dwPrinterNumOfPlanes > 1) &&
|
|
(pCMex->liColorPlaneOrder == END_OF_LIST) )
|
|
{
|
|
ERR(("*ColorPlaneOrder must be specified if *DevNumOfPlanes > 1.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
if((pCMex->dwPrinterNumOfPlanes > 1) &&
|
|
(pCMex->dwPrinterBPP == 1) )
|
|
{
|
|
for(dwListIndex = pCMex->liColorPlaneOrder ;
|
|
pLNode = LISTNODEPTR(pDrvInfo , dwListIndex ) ;
|
|
dwListIndex = pLNode->dwNextItem)
|
|
{
|
|
switch(pLNode->dwData)
|
|
{
|
|
case COLOR_YELLOW:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDYELLOWDATA))
|
|
{
|
|
ERR(("*CmdSendYellowData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_MAGENTA:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDMAGENTADATA))
|
|
{
|
|
ERR(("*CmdSendMagentaData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_CYAN:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDCYANDATA))
|
|
{
|
|
ERR(("*CmdSendCyanData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_BLACK:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDBLACKDATA))
|
|
{
|
|
ERR(("*CmdSendBlackData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_RED:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDREDDATA))
|
|
{
|
|
ERR(("*CmdSendRedData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_GREEN:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDGREENDATA))
|
|
{
|
|
ERR(("*CmdSendGreenData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
case COLOR_BLUE:
|
|
{
|
|
if(!COMMANDPTR(pDrvInfo , CMD_SENDBLUEDATA))
|
|
{
|
|
ERR(("*CmdSendBlueData must exist.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
break ;
|
|
}
|
|
default:
|
|
{
|
|
ERR(("Unrecogized color.\n")) ;
|
|
bStatus = FALSE ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dwResX = dwResY = 1 ; // default in case something goes wrong.
|
|
|
|
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_RESOLUTION ) )
|
|
{
|
|
pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION) ;
|
|
if(pFeature)
|
|
{
|
|
PRESOLUTION pRes ;
|
|
DWORD dwOptIndex ;
|
|
|
|
dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ;
|
|
dwNumOpts = pFeature->Options.dwCount ;
|
|
|
|
|
|
pRes = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
|
|
|
|
for(dwI = 0 ; dwI < dwNumOpts ; dwI++)
|
|
{
|
|
|
|
if( pDrvInfo->Globals.ptMasterUnits.x < pRes[dwI].iXdpi )
|
|
{
|
|
ERR(("master units cannot be coarser than x res unit.\n")) ;
|
|
return FALSE ; // fatal error
|
|
}
|
|
if( pDrvInfo->Globals.ptMasterUnits.x % pRes[dwI].iXdpi )
|
|
{
|
|
ERR(("Must be whole number of master units per x res unit.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
if( pDrvInfo->Globals.ptMasterUnits.y < pRes[dwI].iYdpi )
|
|
{
|
|
ERR(("master units cannot be coarser than y res unit.\n")) ;
|
|
return FALSE ;
|
|
}
|
|
if ( pDrvInfo->Globals.ptMasterUnits.y % pRes[dwI].iYdpi )
|
|
{
|
|
ERR(("Must be whole number of master units per y res unit.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
}
|
|
|
|
// number of master units per resolution unit.
|
|
|
|
dwResX = pDrvInfo->Globals.ptMasterUnits.x /
|
|
pRes[dwOptIndex].iXdpi ;
|
|
dwResY = pDrvInfo->Globals.ptMasterUnits.y /
|
|
pRes[dwOptIndex].iYdpi ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(("Resolution is a required feature.\n")) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// - For each non-standard Halftone option, *rcHPPatternID must be
|
|
// greater than 0 and *HTPatternSize must be a pair of postive integers.
|
|
// NOTE: check with DanielC --- should we enforce that xSize==ySize?
|
|
//
|
|
|
|
// Halftone check is performed in BinitSpecialFeatureOptionFields
|
|
// see postproc.c
|
|
|
|
pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE) ;
|
|
if(pFeature)
|
|
{
|
|
PPAGESIZE pPagesize ;
|
|
PPAGESIZEEX pPageSzEx ;
|
|
|
|
dwNumOpts = pFeature->Options.dwCount ;
|
|
|
|
pPagesize = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
|
|
|
|
for(dwI = 0 ; dwI < dwNumOpts ; dwI++)
|
|
{
|
|
if(GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGEPROTECTION) &&
|
|
!pPagesize[dwI].dwPageProtectionMemory)
|
|
{
|
|
ERR(("*PageProtectMem must be greater than 0 if PageProtect feature exists.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
break ;
|
|
}
|
|
pPageSzEx = OFFSET_TO_POINTER(pInfoHdr,
|
|
pPagesize[dwI].GenericOption.loRenderOffset) ;
|
|
if(pPagesize[dwI].dwPaperSizeID != DMPAPER_USER)
|
|
{
|
|
INT iPDx, iPDy ; // holds page dimensions
|
|
// in same coordinate system as ImageableArea
|
|
|
|
if(pPageSzEx->bRotateSize)
|
|
{
|
|
iPDx = (INT)pPagesize[dwI].szPaperSize.cy ;
|
|
iPDy = (INT)pPagesize[dwI].szPaperSize.cx ;
|
|
}
|
|
else
|
|
{
|
|
iPDx = (INT)pPagesize[dwI].szPaperSize.cx ;
|
|
iPDy = (INT)pPagesize[dwI].szPaperSize.cy ;
|
|
}
|
|
|
|
if((iPDx <= 0) || (iPDy <= 0))
|
|
{
|
|
ERR(("*PageDimensions is required for non-standard sizes.\n")) ;
|
|
bStatus = FALSE ;
|
|
break ;
|
|
}
|
|
if(((INT)pPageSzEx->szImageArea.cx <= 0) ||
|
|
((INT)pPageSzEx->szImageArea.cy <= 0) )
|
|
{
|
|
ERR(("*PrintableArea is required and must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
break ;
|
|
}
|
|
if(((INT)pPageSzEx->ptImageOrigin.x < 0) ||
|
|
((INT)pPageSzEx->ptImageOrigin.y < 0) )
|
|
|
|
{
|
|
ERR(("*PrintableOrigin is required and cannot be negative.\n")) ;
|
|
bStatus = FALSE ;
|
|
break ;
|
|
}
|
|
|
|
if((pPageSzEx->szImageArea.cx % dwResX) ||
|
|
(pPageSzEx->szImageArea.cy % dwResY) )
|
|
{
|
|
ERR(("*PrintableArea must be a integral number of ResolutionUnits.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
break ;
|
|
}
|
|
if((pPageSzEx->ptImageOrigin.x % dwResX) ||
|
|
(pPageSzEx->ptImageOrigin.y % dwResY) )
|
|
{
|
|
ERR(("*PrintableOrigin must be a integral number of ResolutionUnits.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
break ;
|
|
}
|
|
|
|
|
|
if(pDrvInfo->Globals.bRotateCoordinate)
|
|
{ // zhanw assumes printing offset is zero otherwise
|
|
if((pPageSzEx->ptImageOrigin.x % dwMoveUnitsX) ||
|
|
(pPageSzEx->ptImageOrigin.y % dwMoveUnitsY) )
|
|
|
|
{
|
|
ERR(("*PrintableOrigin must be a integral number of MoveUnits.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
break ;
|
|
}
|
|
if((pPageSzEx->ptPrinterCursorOrig.x % dwMoveUnitsX) ||
|
|
(pPageSzEx->ptPrinterCursorOrig.y % dwMoveUnitsY) )
|
|
|
|
{
|
|
ERR(("*CursorOrigin must be a integral number of MoveUnits.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
break ;
|
|
}
|
|
}
|
|
else if((pPageSzEx->ptImageOrigin.x != pPageSzEx->ptPrinterCursorOrig.x) ||
|
|
(pPageSzEx->ptImageOrigin.y != pPageSzEx->ptPrinterCursorOrig.y) )
|
|
|
|
{
|
|
; // this may be unnecessary.
|
|
// ERR(("For non-rotating printers, *PrintableOrigin should be same as *CursorOrigin.\n")) ;
|
|
}
|
|
|
|
if((iPDx + iPDx/100 < pPageSzEx->szImageArea.cx + pPageSzEx->ptImageOrigin.x) ||
|
|
(iPDy + iPDy/100 < pPageSzEx->szImageArea.cy + pPageSzEx->ptImageOrigin.y) )
|
|
{
|
|
// I give up to 1 percent leeway
|
|
ERR(("*PrintableArea must be contained within *PageDimensions.\n")) ;
|
|
bStatus = FALSE ;
|
|
break ;
|
|
}
|
|
}
|
|
else // (dwPaperSizeID == DMPAPER_USER)
|
|
{
|
|
if(((INT)pPageSzEx->ptMinSize.x <= 0) ||
|
|
((INT)pPageSzEx->ptMinSize.y <= 0) )
|
|
{
|
|
ERR(("If User Defined papersize exists *MinSize is required and must be positive.\n")) ;
|
|
#ifdef STRICT_CHECKS
|
|
bStatus = FALSE ;
|
|
#endif
|
|
}
|
|
if(((INT)pPageSzEx->ptMaxSize.x <= 0) ||
|
|
((INT)pPageSzEx->ptMaxSize.y <= 0) )
|
|
{
|
|
ERR(("If User Defined papersize exists *MaxSize is required and must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
if((INT)pPageSzEx->dwMaxPrintableWidth <= 0)
|
|
{
|
|
ERR(("If User Defined papersize exists *MaxPrintableWidth is required and must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// - For each PaperSize option, *PageProtectMem must be greater than 0
|
|
// if PageProtect feature exists.
|
|
//
|
|
// - For all non-CUSTOMSIZE PaperSize options, *PrintableArea and
|
|
// *PrintableOrigin must be explicitly defined. Specifically,
|
|
// *PrintableArea must be a pair of positive integers, and
|
|
// *PrintableOrigin must be a pair of non-negative integers.
|
|
// note: BInitSnapshotTable function assigns
|
|
// UNUSED_ITEM (-1) as the default value for *PrintableOrigin.
|
|
//
|
|
// - For CUSTOMSIZE option, *MinSize, *MaxSize, and *MaxPrintableWidth
|
|
// must be explicitly defined. Specifically, both *MinSize and *MaxSize
|
|
// must be a pair of positive integers. *MaxPrintableWidth must be a
|
|
// positive integer.
|
|
// BInitSnapshotTable function assigns 0 (instead of NO_LIMIT_NUM)
|
|
// as the default value for *MaxPrintableWidth.
|
|
//
|
|
// - For all non-standard non-CUSTOMSIZE PaperSize options, *PageDimensions
|
|
// must be explicitly defined. Specifically, it must be a pair of positive
|
|
// integers.
|
|
//
|
|
// - For any feature or option, if *Installable entry is TRUE, then
|
|
// either *InstallableFeatureName or *rcInstallableFeatureNameID must
|
|
// be present in that particular feature or option construct.
|
|
//
|
|
// - If any feature or option has *Installable being TRUE, then
|
|
// either *InstalledOptionName/*NotInstalledOptionName or
|
|
// *rcInstalledOptionNameID/*rcNotInstalledOptionNameID must be
|
|
// defined at the root level.
|
|
//
|
|
|
|
// once synthetic features are created by BCreateSynthFeatures()
|
|
// they undergo the same checks at createsnapshot time as
|
|
// other features, triggering a warning if the Names of the feature and
|
|
// its options are absent.
|
|
#if 1
|
|
{
|
|
DWORD dwNumFea, dwFea, dwNumOpt, dwOpt, dwOptSize ;
|
|
PENHARRAYREF pearTableContents ;
|
|
PBYTE pubRaw ; // raw binary data.
|
|
PBYTE pubOptions ; // points to start of array of OPTIONS
|
|
PFEATURE pFea ;
|
|
PBYTE pubnRaw ; // Parser's raw binary data.
|
|
PSTATICFIELDS pStatic ;
|
|
|
|
pubnRaw = pInfoHdr->RawData.pvPrivateData ;
|
|
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
|
|
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
|
|
|
|
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
|
|
|
|
dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
|
|
|
|
pFea = (PFEATURE)((PBYTE)pInfoHdr + pUIInfo->loFeatureList) ;
|
|
|
|
for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
|
|
{
|
|
if(!pFea[dwFea].iHelpIndex)
|
|
{
|
|
ERR(("*HelpIndex must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwNumOpt = pFea[dwFea].Options.dwCount ;
|
|
pubOptions = (PBYTE)pInfoHdr + pFea[dwFea].Options.loOffset ;
|
|
dwOptSize = pFea[dwFea].dwOptionSize ;
|
|
|
|
for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++)
|
|
{
|
|
if(!((POPTION)(pubOptions + dwOptSize * dwOpt))->iHelpIndex )
|
|
{
|
|
ERR(("*HelpIndex must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
{
|
|
DWORD dwNumFea, dwFea, dwNumOpt, dwOpt;
|
|
PENHARRAYREF pearTableContents ;
|
|
PBYTE pubRaw ; // raw binary data.
|
|
PBYTE pubOptions ; // points to start of array of OPTIONS
|
|
PFEATURE pFea ;
|
|
|
|
pubRaw = pInfoHdr->RawData.pvPrivateData ;
|
|
|
|
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
|
|
|
|
dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
|
|
|
|
for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
|
|
{
|
|
pFea = PGetIndexedFeature(pUIInfo, dwFea) ;
|
|
|
|
if(!pFea->iHelpIndex)
|
|
{
|
|
ERR(("*HelpIndex must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
|
|
dwNumOpt = pFea->Options.dwCount ;
|
|
|
|
for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++)
|
|
{
|
|
pubOptions = PGetIndexedOption(pUIInfo, pFea, dwOpt);
|
|
|
|
if(!((POPTION)pubOptions))->iHelpIndex )
|
|
{
|
|
ERR(("*HelpIndex must be positive.\n")) ;
|
|
bStatus = FALSE ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
return (bStatus);
|
|
}
|
|
|
|
|
|
#endif
|