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.
1666 lines
51 KiB
1666 lines
51 KiB
/*++
|
|
|
|
Copyright (c) 1996-1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
utils.c
|
|
|
|
Abstract:
|
|
|
|
Utility functions used by the GPC-to-GPD converter
|
|
|
|
Environment:
|
|
|
|
user-mode only.
|
|
|
|
Revision History:
|
|
|
|
10/17/96 -zhanw-
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#include "gpc2gpd.h"
|
|
|
|
//
|
|
// define global read-only variables
|
|
//
|
|
|
|
BYTE gbHexChar[16] = {'0','1','2','3','4','5','6','7','8','9',
|
|
'A','B','C','D','E','F'};
|
|
|
|
DWORD gdwErrFlag[NUM_ERRS] = {
|
|
ERR_BAD_GPCDATA,
|
|
ERR_OUT_OF_MEMORY,
|
|
ERR_WRITE_FILE,
|
|
ERR_MD_CMD_CALLBACK,
|
|
ERR_CM_GEN_FAV_XY,
|
|
ERR_CM_XM_RESET_FONT,
|
|
ERR_CM_XM_ABS_NO_LEFT,
|
|
ERR_CM_YM_TRUNCATE,
|
|
ERR_RF_MIN_IS_WHITE,
|
|
ERR_INCONSISTENT_PAGEPROTECT,
|
|
ERR_NON_ZERO_FEED_MARGINS_ON_RT90_PRINTER,
|
|
ERR_BAD_GPC_CMD_STRING,
|
|
ERR_RES_BO_RESET_FONT,
|
|
ERR_RES_BO_OEMGRXFILTER,
|
|
ERR_CM_YM_RES_DEPENDENT,
|
|
ERR_MOVESCALE_NOT_FACTOR_OF_MASTERUNITS,
|
|
ERR_NO_CMD_CALLBACK_PARAMS,
|
|
ERR_HAS_DUPLEX_ON_CMD,
|
|
ERR_PSRC_MAN_PROMPT,
|
|
ERR_PS_SUGGEST_LNDSCP,
|
|
ERR_HAS_SECOND_FONT_ID_CMDS,
|
|
ERR_DLI_FMT_CAPSL,
|
|
ERR_DLI_FMT_PPDS,
|
|
ERR_DLI_GEN_DLPAGE,
|
|
ERR_DLI_GEN_7BIT_CHARSET,
|
|
ERR_DC_SEND_PALETTE,
|
|
ERR_RES_BO_NO_ADJACENT,
|
|
ERR_MD_NO_ADJACENT,
|
|
ERR_CURSOR_ORIGIN_ADJUSTED,
|
|
ERR_PRINTABLE_ORIGIN_ADJUSTED,
|
|
ERR_PRINTABLE_AREA_ADJUSTED,
|
|
ERR_MOVESCALE_NOT_FACTOR_INTO_SOME_RESSCALE
|
|
};
|
|
|
|
PSTR gpstrErrMsg[NUM_ERRS] = {
|
|
"Error: Bad GPC data.\r\n",
|
|
"Error: Out of system memory.\r\n",
|
|
"Error: Cannot write to the GPD file.\r\n",
|
|
"Warning: MODELDATA.fGeneral MD_CMD_CALLBACK is set.\r\n",
|
|
"Warning: CURSORMODE.fGeneral CM_GEN_FAV_XY is set.\r\n",
|
|
"Warning: CURSORMOVE.fXMove CM_XM_RESET_FONT is set.\r\n",
|
|
"Warning: CURSORMOVE.fXMove CM_XM_ABS_NO_LEFT is set.\r\n",
|
|
"Warning: CURSORMOVE.fYMove CM_YM_TRUNCATE is set.\r\n",
|
|
"Warning: RECTFILL.fGeneral RF_MIN_IS_WHITE is set.\r\n",
|
|
"Error: Inconsistent GPC data: some PAPERSIZE have PageProtect On/Off cmds while others do not. PageProtect feature is not generated.\r\n",
|
|
"Error: Some PAPERSOURCE have non-zero top/bottom margins on this RT90 printer. Check the GPD file for details.\r\n",
|
|
"Error: Some GPC command strings are illegal. Search for !ERR! in the GPD file.\r\n",
|
|
"Warning: Some RESOLUTION have RES_BO_RESET_FONT flag set. Check the GPD file for details.\r\n",
|
|
"Error: Some RESOLUTION have RES_BO_OEMGRXFILTER flag set. Check the GPD file for details.\r\n",
|
|
"Error: The generated *YMoveUnit value is wrong because Y move cmds have dependency on the resolution. Correct it manually.\r\n",
|
|
"Error: The MoveUnits are not factors of the MasterUnits. Correct the GPC using Unitool before converting.\r\n",
|
|
"Error: At least one callback command is generated. Check the GPD file to see if you need any parameters.\r\n",
|
|
"Warning: PAGECONTROL has non-NULL DUPLEX_ON command.\r\n",
|
|
"Warning: Some PAPERSOURCE have PSRC_MAN_PROMPT flag set. Check the GPD file for details.\r\n",
|
|
"Warning: Some PAPERSIZE have PS_SUGGEST_LNDSCP flag set. Check the GPD file for details.\r\n",
|
|
"Warning: DOWNLOADINFO has non-NULL xxx_SECOND_FONT_ID_xxx commands.\r\n",
|
|
"Error: DLI_FMT_CAPSL flag is set. Must supply custom code to support this font format.\r\n",
|
|
"Error: DLI_FMT_PPDS flag is set. Must supply custom code to support this font format.\r\n",
|
|
"Warning: DLI_GEN_DLPAGE flag is set.\r\n",
|
|
"Warning: DLI_GEN_7BIT_CHARSET flag is set.\r\n",
|
|
"Warning: DEVCOLOR.fGeneral DC_SEND_PALETTE flag is set.\r\n",
|
|
"Warning: Some RESOLUTION have RES_BO_NO_ADJACENT flag set. Check the GPD file for details.\r\n",
|
|
"Warning: MODELDATA.fGeneral MD_NO_ADJACENT is set.\r\n",
|
|
"Warning: Some *CursorOrigin values have been adjusted. Check the GPD file for details.\r\n",
|
|
"Warning: Some *PrintableOrigin values have been adjusted. Check the GPD file for details.\r\n",
|
|
"Warning: Some *PrintableArea values have been adjusted. Check the GPD file for details.\r\n",
|
|
"Warning: Please check that every *PrintableOrigin (X,Y) factor evenly into the move unit scale X/Y.\r\n"
|
|
};
|
|
|
|
//
|
|
// define standard variable name strings
|
|
//
|
|
PSTR gpstrSVNames[SV_MAX] = {
|
|
"NumOfDataBytes",
|
|
"RasterDataWidthInBytes",
|
|
"RasterDataHeightInPixels",
|
|
"NumOfCopies",
|
|
"PrintDirInCCDegrees",
|
|
"DestX",
|
|
"DestY",
|
|
"DestXRel",
|
|
"DestYRel",
|
|
"LinefeedSpacing",
|
|
"RectXSize",
|
|
"RectYSize",
|
|
"GrayPercentage",
|
|
"NextFontID",
|
|
"NextGlyph",
|
|
"PhysPaperLength",
|
|
"PhysPaperWidth",
|
|
"FontHeight",
|
|
"FontWidth",
|
|
"FontMaxWidth",
|
|
"FontBold",
|
|
"FontItalic",
|
|
"FontUnderline",
|
|
"FontStrikeThru",
|
|
"CurrentFontID",
|
|
"TextYRes",
|
|
"TextXRes",
|
|
"GraphicsYRes",
|
|
"GraphicsXRes",
|
|
"Rop3",
|
|
"RedValue",
|
|
"GreenValue",
|
|
"BlueValue",
|
|
"PaletteIndexToProgram",
|
|
"CurrentPaletteIndex"
|
|
|
|
};
|
|
//
|
|
// define the standard variable id heap. It consists of a series of id runs.
|
|
// Each run is a sequence of standard variable id's (SV_xxx value, 0-based)
|
|
// ended by -1 (0xFFFFFFFF). The runs are constructed based on the need of
|
|
// GPC commands. Basically, one run corresponds to one GPC command that
|
|
// requires parameters. If more than one GPC command share the same set of
|
|
// parameters, then they can share the same run.
|
|
//
|
|
DWORD gdwSVLists[] = {
|
|
EOR, // place holder for all GPC commands that has no parameter
|
|
SV_NUMDATABYTES, // CMD_RES_SENDBLOCK can have 3 params
|
|
SV_HEIGHTINPIXELS,
|
|
SV_WIDTHINBYTES,
|
|
EOR,
|
|
SV_COPIES, // offset 5. CMD_PC_MULT_COPIES
|
|
EOR,
|
|
SV_DESTX, // offset 7
|
|
EOR,
|
|
SV_DESTY, // offset 9
|
|
EOR,
|
|
SV_DESTXREL, // offset 11
|
|
EOR,
|
|
SV_DESTYREL, // offset 13
|
|
EOR,
|
|
SV_LINEFEEDSPACING, // offset 15
|
|
EOR,
|
|
SV_DESTXREL, // offset 17
|
|
SV_DESTYREL,
|
|
EOR,
|
|
SV_DESTX, // offset 20
|
|
SV_DESTY,
|
|
EOR,
|
|
SV_RECTXSIZE, // offset 23
|
|
EOR,
|
|
SV_RECTYSIZE, // offset 25
|
|
EOR,
|
|
SV_GRAYPERCENT, // offset 27
|
|
EOR,
|
|
SV_NEXTFONTID, // offset 29
|
|
EOR,
|
|
SV_CURRENTFONTID, // offset 31
|
|
EOR,
|
|
SV_NEXTGLYPH, // offset 33
|
|
EOR,
|
|
SV_PHYSPAPERLENGTH, // offset 35
|
|
SV_PHYSPAPERWIDTH,
|
|
EOR,
|
|
SV_PRINTDIRECTION, // offset 38
|
|
EOR,
|
|
SV_NUMDATABYTES, // offset 40
|
|
EOR,
|
|
SV_REDVALUE, // offset 42
|
|
SV_GREENVALUE,
|
|
SV_BLUEVALUE,
|
|
SV_PALETTEINDEXTOPROGRAM,
|
|
EOR,
|
|
SV_CURRENTPALETTEINDEX, // offset 47
|
|
EOR
|
|
};
|
|
//
|
|
// map CMD_xxx id to the corresponding DWORD offset to the standard variable
|
|
// id heap. That is, gdwSVLists[gawCmdtoSVOffset[CMD_RES_SELECTRES]] is the
|
|
// beginning of a parameter run for GPC's command CMD_RES_SELECTRES. If the
|
|
// first element in the run of EOR, that means the command takes no param.
|
|
//
|
|
WORD gawCmdtoSVOffset[MAXCMD+MAXECMD] = {
|
|
0, // CMD_RES_SELECTRES
|
|
0, // CMD_RES_BEGINGRAPHICS
|
|
0, // CMD_RES_ENDGRAPHICS
|
|
1, // CMD_RES_SENDBLOCK
|
|
0, // CMD_RES_ENDBLOCK
|
|
|
|
0, // CMD_CMP_NONE
|
|
0, // CMD_CMP_RLE
|
|
0, // CMD_CMP_TIFF
|
|
0, // CMD_CMP_DELTAROW
|
|
0, // CMD_CMP_BITREPEAT
|
|
0, // CMD_CMP_FE_RLE
|
|
|
|
0, // CMD_PC_BEGIN_DOC
|
|
0, // CMD_PC_BEGIN_PAGE
|
|
0, // CMD_PC_DUPLEX_ON
|
|
0, // CMD_PC_ENDDOC
|
|
0, // CMD_PC_ENDPAGE
|
|
0, // CMD_PC_DUPLEX_OFF
|
|
0, // CMD_PC_ABORT
|
|
0, // CMD_PC_PORTRAIT, CMD_PC_ORIENTATION
|
|
0, // CMD_PC_LANDSCAPE
|
|
5, // CMD_PC_MULT_COPIES
|
|
0, // CMD_PC_DUPLEX_VERT
|
|
0, // CMD_PC_DUPLEX_HORZ
|
|
38, // CMD_PC_PRINT_DIR
|
|
0, // CMD_PC_JOB_SEPARATION
|
|
|
|
7, // CMD_CM_XM_ABS
|
|
11, // CMD_CM_XM_REL
|
|
11, // CMD_CM_XM_RELLEFT
|
|
9, // CMD_CM_YM_ABS
|
|
13, // CMD_CM_YM_REL
|
|
13, // CMD_CM_YM_RELUP
|
|
15, // CMD_CM_YM_LINESPACING
|
|
17, // CMD_CM_XY_REL
|
|
20, // CMD_CM_XY_ABS
|
|
0, // CMD_CM_CR
|
|
0, // CMD_CM_LF
|
|
0, // CMD_CM_FF
|
|
0, // CMD_CM_BS
|
|
0, // CMD_CM_UNI_DIR
|
|
0, // CMD_CM_UNI_DIR_OFF
|
|
0, // CMD_CM_PUSH_POS
|
|
0, // CMD_CM_POP_POS
|
|
|
|
0, // CMD_FS_BOLD_ON
|
|
0, // CMD_FS_BOLD_OFF
|
|
0, // CMD_FS_ITALIC_ON
|
|
0, // CMD_FS_ITALIC_OFF
|
|
0, // CMD_FS_UNDERLINE_ON
|
|
0, // CMD_FS_UNDERLINE_OFF
|
|
0, // CMD_FS_DOUBLEUNDERLINE_ON
|
|
0, // CMD_FS_DOUBLEUNDERLINE_OFF
|
|
0, // CMD_FS_STRIKETHRU_ON
|
|
0, // CMD_FS_STRIKETHRU_OFF
|
|
0, // CMD_FS_WHITE_TEXT_ON
|
|
0, // CMD_FS_WHITE_TEXT_OFF
|
|
0, // CMD_FS_SINGLE_BYTE
|
|
0, // CMD_FS_DOUBLE_BYTE
|
|
0, // CMD_FS_VERT_ON
|
|
0, // CMD_FS_VERT_OFF
|
|
|
|
0, // CMD_DC_TC_BLACK
|
|
0, // CMD_DC_TC_RED
|
|
0, // CMD_DC_TC_GREEN
|
|
0, // CMD_DC_TC_YELLOW
|
|
0, // CMD_DC_TC_BLUE
|
|
0, // CMD_DC_TC_MAGENTA
|
|
0, // CMD_DC_TC_CYAN
|
|
0, // CMD_DC_TC_WHITE
|
|
0, // CMD_DC_GC_SETCOLORMODE
|
|
0, // CMD_DC_PC_START
|
|
42, // CMD_DC_PC_ENTRY
|
|
0, // CMD_DC_PC_END
|
|
47, // CMD_DC_PC_SELECTINDEX
|
|
0, // CMD_DC_SETMONOMODE
|
|
|
|
40, // CMD_DC_GC_PLANE1
|
|
40, // CMD_DC_GC_PLANE2
|
|
40, // CMD_DC_GC_PLANE3
|
|
40, // CMD_DC_GC_PLANE4
|
|
|
|
23, // CMD_RF_X_SIZE
|
|
25, // CMD_RF_Y_SIZE
|
|
27, // CMD_RF_GRAY_FILL
|
|
0, // CMD_RF_WHITE_FILL
|
|
|
|
0, // Reserved
|
|
0, // CMD_BEGIN_DL_JOB
|
|
0, // CMD_BEGIN_FONT_DL
|
|
29, // CMD_SET_FONT_ID
|
|
0, // CMD_SEND_FONT_DCPT --- this command is no longer used.
|
|
31, // CMD_SELECT_FONT_ID
|
|
33, // CMD_SET_CHAR_CODE
|
|
0, // CMD_SEND_CHAR_DCPT --- this command is no longer used.
|
|
0, // CMD_END_FONT_DL
|
|
0, // CMD_MAKE_PERM
|
|
0, // CMD_MAKE_TEMP
|
|
0, // CMD_END_DL_JOB
|
|
0, // CMD_DEL_FONT
|
|
0, // CMD_DEL_ALL_FONTS
|
|
0, // CMD_SET_SECOND_FONT_ID --- used only by CAPSL. Obsolete.
|
|
0, // CMD_SELECT_SECOND_FONT_ID --- used only by CAPSL. Obsolete.
|
|
|
|
0, // CMD_TEXTQUALITY
|
|
0, // CMD_PAPERSOURCE
|
|
0, // CMD_PAPERQUALITY
|
|
0, // CMD_PAPERDEST
|
|
35, // CMD_PAPERSIZE
|
|
35, // CMD_PAPERSIZE_LAND
|
|
0, // CMD_PAGEPROTECT_ON
|
|
0, // CMD_PAGEPROTECT_OFF
|
|
0, // CMD_IMAGECONTROL
|
|
0 // CMD_PRINTDENSITY
|
|
};
|
|
|
|
PSTR gpstrFeatureName[FID_MAX] = {
|
|
"OutputBin",
|
|
"ImageControl",
|
|
"PrintDensity"
|
|
};
|
|
|
|
PSTR gpstrFeatureDisplayNameMacro[FID_MAX] = { // reference value macro names
|
|
"OUTPUTBIN_DISPLAY",
|
|
"IMAGECONTROL_DISPLAY",
|
|
"PRINTDENSITY_DISPLAY"
|
|
};
|
|
|
|
PSTR gpstrFeatureDisplayName[FID_MAX] = { // reference names
|
|
"Output Bin",
|
|
"Image Control",
|
|
"Print Density"
|
|
};
|
|
|
|
INT gintFeatureDisplayNameID[FID_MAX] = { // reference string resource ids
|
|
2111, // these values must match definitions in printer5\inc\common.rc
|
|
2112,
|
|
2113
|
|
};
|
|
|
|
WORD gwFeatureMDOI[FID_MAX] = {
|
|
MD_OI_PAPERDEST,
|
|
MD_OI_IMAGECONTROL,
|
|
MD_OI_PRINTDENSITY
|
|
};
|
|
|
|
WORD gwFeatureOCDWordOffset[FID_MAX] = {
|
|
3,
|
|
3,
|
|
2
|
|
};
|
|
|
|
WORD gwFeatureHE[FID_MAX] = {
|
|
HE_PAPERDEST,
|
|
HE_IMAGECONTROL,
|
|
HE_PRINTDENSITY
|
|
};
|
|
|
|
WORD gwFeatureORD[FID_MAX] = {
|
|
PC_ORD_PAPER_DEST,
|
|
PC_ORD_IMAGECONTROL,
|
|
PC_ORD_PRINTDENSITY
|
|
};
|
|
|
|
WORD gwFeatureCMD[FID_MAX] = {
|
|
CMD_PAPERDEST,
|
|
CMD_IMAGECONTROL,
|
|
CMD_PRINTDENSITY
|
|
};
|
|
//
|
|
// define the mapping between standard paper size id to the standard
|
|
// PaperSize option name
|
|
//
|
|
PSTR gpstrStdPSName[DMPAPER_COUNT] = {
|
|
"LETTER",
|
|
"LETTERSMALL",
|
|
"TABLOID",
|
|
"LEDGER",
|
|
"LEGAL",
|
|
"STATEMENT",
|
|
"EXECUTIVE",
|
|
"A3",
|
|
"A4",
|
|
"A4SMALL",
|
|
"A5",
|
|
"B4",
|
|
"B5",
|
|
"FOLIO",
|
|
"QUARTO",
|
|
"10X14",
|
|
"11X17",
|
|
"NOTE",
|
|
"ENV_9",
|
|
"ENV_10",
|
|
"ENV_11",
|
|
"ENV_12",
|
|
"ENV_14",
|
|
"CSHEET",
|
|
"DSHEET",
|
|
"ESHEET",
|
|
"ENV_DL",
|
|
"ENV_C5",
|
|
"ENV_C3",
|
|
"ENV_C4",
|
|
"ENV_C6",
|
|
"ENV_C65",
|
|
"ENV_B4",
|
|
"ENV_B5",
|
|
"ENV_B6",
|
|
"ENV_ITALY",
|
|
"ENV_MONARCH",
|
|
"ENV_PERSONAL",
|
|
"FANFOLD_US",
|
|
"FANFOLD_STD_GERMAN",
|
|
"FANFOLD_LGL_GERMAN",
|
|
"ISO_B4",
|
|
"JAPANESE_POSTCARD",
|
|
"9X11",
|
|
"10X11",
|
|
"15X11",
|
|
"ENV_INVITE",
|
|
"", // RESERVED_48
|
|
"", // RESERVED_49
|
|
"LETTER_EXTRA",
|
|
"LEGAL_EXTRA",
|
|
"TABLOID_EXTRA",
|
|
"A4_EXTRA",
|
|
"LETTER_TRANSVERSE",
|
|
"A4_TRANSVERSE",
|
|
"LETTER_EXTRA_TRANSVERSE",
|
|
"A_PLUS",
|
|
"B_PLUS",
|
|
"LETTER_PLUS",
|
|
"A4_PLUS",
|
|
"A5_TRANSVERSE",
|
|
"B5_TRANSVERSE",
|
|
"A3_EXTRA",
|
|
"A5_EXTRA",
|
|
"B5_EXTRA",
|
|
"A2",
|
|
"A3_TRANSVERSE",
|
|
"A3_EXTRA_TRANSVERSE",
|
|
"DBL_JAPANESE_POSTCARD",
|
|
"A6",
|
|
"JENV_KAKU2",
|
|
"JENV_KAKU3",
|
|
"JENV_CHOU3",
|
|
"JENV_CHOU4",
|
|
"LETTER_ROTATED",
|
|
"A3_ROTATED",
|
|
"A4_ROTATED",
|
|
"A5_ROTATED",
|
|
"B4_JIS_ROTATED",
|
|
"B5_JIS_ROTATED",
|
|
"JAPANESE_POSTCARD_ROTATED",
|
|
"DBL_JAPANESE_POSTCARD_ROTATED",
|
|
"A6_ROTATED",
|
|
"JENV_KAKU2_ROTATED",
|
|
"JENV_KAKU3_ROTATED",
|
|
"JENV_CHOU3_ROTATED",
|
|
"JENV_CHOU4_ROTATED",
|
|
"B6_JIS",
|
|
"B6_JIS_ROTATED",
|
|
"12X11",
|
|
"JENV_YOU4",
|
|
"JENV_YOU4_ROTATED",
|
|
"P16K",
|
|
"P32K",
|
|
"P32KBIG",
|
|
"PENV_1",
|
|
"PENV_2",
|
|
"PENV_3",
|
|
"PENV_4",
|
|
"PENV_5",
|
|
"PENV_6",
|
|
"PENV_7",
|
|
"PENV_8",
|
|
"PENV_9",
|
|
"PENV_10",
|
|
"P16K_ROTATED",
|
|
"P32K_ROTATED",
|
|
"P32KBIG_ROTATED",
|
|
"PENV_1_ROTATED",
|
|
"PENV_2_ROTATED",
|
|
"PENV_3_ROTATED",
|
|
"PENV_4_ROTATED",
|
|
"PENV_5_ROTATED",
|
|
"PENV_6_ROTATED",
|
|
"PENV_7_ROTATED",
|
|
"PENV_8_ROTATED",
|
|
"PENV_9_ROTATED",
|
|
"PENV_10_ROTATED"
|
|
};
|
|
|
|
PSTR gpstrStdPSDisplayNameMacro[DMPAPER_COUNT] = {
|
|
"LETTER_DISPLAY",
|
|
"LETTERSMALL_DISPLAY",
|
|
"TABLOID_DISPLAY",
|
|
"LEDGER_DISPLAY",
|
|
"LEGAL_DISPLAY",
|
|
"STATEMENT_DISPLAY",
|
|
"EXECUTIVE_DISPLAY",
|
|
"A3_DISPLAY",
|
|
"A4_DISPLAY",
|
|
"A4SMALL_DISPLAY",
|
|
"A5_DISPLAY",
|
|
"B4_DISPLAY",
|
|
"B5_DISPLAY",
|
|
"FOLIO_DISPLAY",
|
|
"QUARTO",
|
|
"10X14_DISPLAY",
|
|
"11X17_DISPLAY",
|
|
"NOTE_DISPLAY",
|
|
"ENV_9_DISPLAY",
|
|
"ENV_10_DISPLAY",
|
|
"ENV_11_DISPLAY",
|
|
"ENV_12_DISPLAY",
|
|
"ENV_14_DISPLAY",
|
|
"CSHEET_DISPLAY",
|
|
"DSHEET_DISPLAY",
|
|
"ESHEET_DISPLAY",
|
|
"ENV_DL_DISPLAY",
|
|
"ENV_C5_DISPLAY",
|
|
"ENV_C3_DISPLAY",
|
|
"ENV_C4_DISPLAY",
|
|
"ENV_C6_DISPLAY",
|
|
"ENV_C65_DISPLAY",
|
|
"ENV_B4_DISPLAY",
|
|
"ENV_B5_DISPLAY",
|
|
"ENV_B6_DISPLAY",
|
|
"ENV_ITALY_DISPLAY",
|
|
"ENV_MONARCH_DISPLAY",
|
|
"ENV_PERSONAL_DISPLAY",
|
|
"FANFOLD_US_DISPLAY",
|
|
"FANFOLD_STD_GERMAN_DISPLAY",
|
|
"FANFOLD_LGL_GERMAN_DISPLAY",
|
|
"ISO_B4_DISPLAY",
|
|
"JAPANESE_POSTCARD_DISPLAY",
|
|
"9X11_DISPLAY",
|
|
"10X11_DISPLAY",
|
|
"15X11_DISPLAY",
|
|
"ENV_INVITE_DISPLAY",
|
|
"", // RESERVED--DO NOT USE
|
|
"", // RESERVED--DO NOT USE
|
|
"LETTER_EXTRA_DISPLAY",
|
|
"LEGAL_EXTRA_DISPLAY",
|
|
"TABLOID_EXTRA_DISPLAY",
|
|
"A4_EXTRA_DISPLAY",
|
|
"LETTER_TRANSVERSE_DISPLAY",
|
|
"A4_TRANSVERSE_DISPLAY",
|
|
"LETTER_EXTRA_TRANSVERSE_DISPLAY",
|
|
"A_PLUS_DISPLAY",
|
|
"B_PLUS_DISPLAY",
|
|
"LETTER_PLUS_DISPLAY",
|
|
"A4_PLUS_DISPLAY",
|
|
"A5_TRANSVERSE_DISPLAY",
|
|
"B5_TRANSVERSE_DISPLAY",
|
|
"A3_EXTRA_DISPLAY",
|
|
"A5_EXTRA_DISPLAY",
|
|
"B5_EXTRA_DISPLAY",
|
|
"A2_DISPLAY",
|
|
"A3_TRANSVERSE_DISPLAY",
|
|
"A3_EXTRA_TRANSVERSE_DISPLAY",
|
|
"DBL_JAPANESE_POSTCARD_DISPLAY",
|
|
"A6_DISPLAY",
|
|
"JENV_KAKU2_DISPLAY",
|
|
"JENV_KAKU3_DISPLAY",
|
|
"JENV_CHOU3_DISPLAY",
|
|
"JENV_CHOU4_DISPLAY",
|
|
"LETTER_ROTATED_DISPLAY",
|
|
"A3_ROTATED_DISPLAY",
|
|
"A4_ROTATED_DISPLAY",
|
|
"A5_ROTATED_DISPLAY",
|
|
"B4_JIS_ROTATED_DISPLAY",
|
|
"B5_JIS_ROTATED_DISPLAY",
|
|
"JAPANESE_POSTCARD_ROTATED_DISPLAY",
|
|
"DBL_JAPANESE_POSTCARD_ROTATED_DISPLAY",
|
|
"A6_ROTATED_DISPLAY",
|
|
"JENV_KAKU2_ROTATED_DISPLAY",
|
|
"JENV_KAKU3_ROTATED_DISPLAY",
|
|
"JENV_CHOU3_ROTATED_DISPLAY",
|
|
"JENV_CHOU4_ROTATED_DISPLAY",
|
|
"B6_JIS_DISPLAY",
|
|
"B6_JIS_ROTATED_DISPLAY",
|
|
"12X11_DISPLAY",
|
|
"JENV_YOU4_DISPLAY",
|
|
"JENV_YOU4_ROTATED_DISPLAY",
|
|
"P16K_DISPLAY",
|
|
"P32K_DISPLAY",
|
|
"P32KBIG_DISPLAY",
|
|
"PENV_1_DISPLAY",
|
|
"PENV_2_DISPLAY",
|
|
"PENV_3_DISPLAY",
|
|
"PENV_4_DISPLAY",
|
|
"PENV_5_DISPLAY",
|
|
"PENV_6_DISPLAY",
|
|
"PENV_7_DISPLAY",
|
|
"PENV_8_DISPLAY",
|
|
"PENV_9_DISPLAY",
|
|
"PENV_10_DISPLAY",
|
|
"P16K_ROTATED_DISPLAY",
|
|
"P32K_ROTATED_DISPLAY",
|
|
"P32KBIG_ROTATED_DISPLAY",
|
|
"PENV_1_ROTATED_DISPLAY",
|
|
"PENV_2_ROTATED_DISPLAY",
|
|
"PENV_3_ROTATED_DISPLAY",
|
|
"PENV_4_ROTATED_DISPLAY",
|
|
"PENV_5_ROTATED_DISPLAY",
|
|
"PENV_6_ROTATED_DISPLAY",
|
|
"PENV_7_ROTATED_DISPLAY",
|
|
"PENV_8_ROTATED_DISPLAY",
|
|
"PENV_9_ROTATED_DISPLAY",
|
|
"PENV_10_ROTATED_DISPLAY",
|
|
};
|
|
|
|
PSTR gpstrStdPSDisplayName[DMPAPER_COUNT] = {
|
|
"Letter",
|
|
"Letter Small",
|
|
"Tabloid",
|
|
"Ledger",
|
|
"Legal",
|
|
"Statement",
|
|
"Executive",
|
|
"A3",
|
|
"A4",
|
|
"A4 Small",
|
|
"A5",
|
|
"B4 (JIS)",
|
|
"B5 (JIS)",
|
|
"Folio",
|
|
"Quarto",
|
|
"10x14",
|
|
"11x17",
|
|
"Note",
|
|
"Envelope #9",
|
|
"Envelope #10",
|
|
"Envelope #11",
|
|
"Envelope #12",
|
|
"Envelope #14",
|
|
"C size sheet",
|
|
"D size sheet",
|
|
"E size sheet",
|
|
"Envelope DL",
|
|
"Envelope C5",
|
|
"Envelope C3",
|
|
"Envelope C4",
|
|
"Envelope C6",
|
|
"Envelope C65",
|
|
"Envelope B4",
|
|
"Envelope B5",
|
|
"Envelope B6",
|
|
"Envelope",
|
|
"Envelope Monarch",
|
|
"6 3/4 Envelope",
|
|
"US Std Fanfold",
|
|
"German Std Fanfold",
|
|
"German Legal Fanfold",
|
|
"B4 (ISO)",
|
|
"Japanese Postcard",
|
|
"9x11",
|
|
"10x11",
|
|
"15x11",
|
|
"Envelope Invite",
|
|
"",
|
|
"",
|
|
"Letter Extra",
|
|
"Legal Extra",
|
|
"Tabloid Extra",
|
|
"A4 Extra",
|
|
"Letter Transverse",
|
|
"A4 Transverse",
|
|
"Letter Extra Transverse",
|
|
"Super A",
|
|
"Super B",
|
|
"Letter Plus",
|
|
"A4 Plus",
|
|
"A5 Transverse",
|
|
"B5 (JIS) Transverse",
|
|
"A3 Extra",
|
|
"A5 Extra",
|
|
"B5 (ISO) Extra",
|
|
"A2",
|
|
"A3 Transverse",
|
|
"A3 Extra Transverse",
|
|
"Japanese Double Postcard",
|
|
"A6",
|
|
"Japanese Envelope Kaku #2",
|
|
"Japanese Envelope Kaku #3",
|
|
"Japanese Envelope Chou #3",
|
|
"Japanese Envelope Chou #4",
|
|
"Letter Rotated",
|
|
"A3 Rotated",
|
|
"A4 Rotated",
|
|
"A5 Rotated",
|
|
"B4 (JIS) Rotated",
|
|
"B5 (JIS) Rotated",
|
|
"Japanese Postcard Rotated",
|
|
"Double Japanese Postcard Rotated",
|
|
"A6 Rotated",
|
|
"Japanese Envelope Kaku #2 Rotated",
|
|
"Japanese Envelope Kaku #3 Rotated",
|
|
"Japanese Envelope Chou #3 Rotated",
|
|
"Japanese Envelope Chou #4 Rotated",
|
|
"B6 (JIS)",
|
|
"B6 (JIS) Rotated",
|
|
"12x11",
|
|
"Japanese Envelope You #4",
|
|
"Japanese Envelope You #4 Rotated",
|
|
"PRC 16K",
|
|
"PRC 32K",
|
|
"PRC 32K(Big)",
|
|
"PRC Envelope #1",
|
|
"PRC Envelope #2",
|
|
"PRC Envelope #3",
|
|
"PRC Envelope #4",
|
|
"PRC Envelope #5",
|
|
"PRC Envelope #6",
|
|
"PRC Envelope #7",
|
|
"PRC Envelope #8",
|
|
"PRC Envelope #9",
|
|
"PRC Envelope #10",
|
|
"PRC 16K Rotated",
|
|
"PRC 32K Rotated",
|
|
"PRC 32K(Big) Rotated",
|
|
"PRC Envelope #1 Rotated",
|
|
"PRC Envelope #2 Rotated",
|
|
"PRC Envelope #3 Rotated",
|
|
"PRC Envelope #4 Rotated",
|
|
"PRC Envelope #5 Rotated",
|
|
"PRC Envelope #6 Rotated",
|
|
"PRC Envelope #7 Rotated",
|
|
"PRC Envelope #8 Rotated",
|
|
"PRC Envelope #9 Rotated",
|
|
"PRC Envelope #10 Rotated"
|
|
};
|
|
|
|
|
|
PSTR gpstrStdIBName[DMBIN_LAST] = {
|
|
"UPPER",
|
|
"LOWER",
|
|
"MIDDLE",
|
|
"MANUAL",
|
|
"ENVFEED",
|
|
"ENVMANUAL",
|
|
"AUTO",
|
|
"TRACTOR",
|
|
"SMALLFMT",
|
|
"LARGEFMT",
|
|
"LARGECAPACITY",
|
|
"", // non-contiguous id's
|
|
"",
|
|
"CASSETTE",
|
|
""
|
|
};
|
|
|
|
PSTR gpstrStdIBDisplayNameMacro[DMBIN_LAST] = {
|
|
"UPPER_TRAY_DISPLAY",
|
|
"LOWER_TRAY_DISPLAY",
|
|
"MIDDLE_TRAY_DISPLAY",
|
|
"MANUAL_FEED_DISPLAY",
|
|
"ENV_FEED_DISPLAY",
|
|
"ENV_MANUAL_DISPLAY",
|
|
"AUTO_DISPLAY",
|
|
"TRACTOR_DISPLAY",
|
|
"SMALL_FORMAT_DISPLAY",
|
|
"LARGE_FORMAT_DISPLAY",
|
|
"LARGE_CAP_DISPLAY",
|
|
"", // non-contiguous id's
|
|
"",
|
|
"CASSETTE_DISPLAY",
|
|
""
|
|
};
|
|
|
|
PSTR gpstrStdIBDisplayName[DMBIN_LAST] = {
|
|
"Upper Paper tray", // DMBIN_FIRST
|
|
"Lower Paper tray", // DMBIN_UPPER
|
|
"Middle Paper tray", // DMBIN_LOWER
|
|
"Manual Paper feed", // DMBIN_MANUAL
|
|
"Envelope Feeder", // DMBIN_ENVELOPE
|
|
"Envelope, Manual Feed", // DMBIN_ENVMANUAL
|
|
"Auto", // DMBIN_AUTO
|
|
"Tractor feed", // DMBIN_TRACTOR
|
|
"Small Format", // DMBIN_SMALLFMT
|
|
"Large Format", // DMBIN_LARGEFMT
|
|
"Large Capacity" // DMBIN_LARGECAPACITY(11)
|
|
"",
|
|
"",
|
|
"Cassette", // DMBIN_CASETTE(14)
|
|
"Automatically Select" // DMBIN_FORMSOURCE(15)
|
|
};
|
|
|
|
|
|
PSTR gpstrStdMTName[DMMEDIA_LAST] = {
|
|
"STANDARD",
|
|
"TRANSPARENCY",
|
|
"GLOSSY"
|
|
};
|
|
|
|
PSTR gpstrStdMTDisplayNameMacro[DMMEDIA_LAST] = {
|
|
"PLAIN_PAPER_DISPLAY",
|
|
"TRANSPARENCY_DISPLAY",
|
|
"GLOSSY_PAPER_DISPLAY"
|
|
};
|
|
|
|
PSTR gpstrStdMTDisplayName[DMMEDIA_LAST] = {
|
|
"Plain Paper",
|
|
"Transparency",
|
|
"Glossy Paper"
|
|
};
|
|
|
|
|
|
PSTR gpstrStdTQName[DMTEXT_LAST] = {
|
|
"LETTER_QUALITY",
|
|
"NEAR_LETTER_QUALITY",
|
|
"MEMO_QUALITY",
|
|
"DRAFT_QUALITY",
|
|
"TEXT_QUALITY"
|
|
};
|
|
|
|
PSTR gpstrStdTQDisplayNameMacro[DMTEXT_LAST] = {
|
|
"LETTER_QUALITY_DISPLAY",
|
|
"NEAR_LETTER_QUALITY_DISPLAY",
|
|
"MEMO_QUALITY_DISPLAY",
|
|
"DRAFT_QUALITY_DISPLAY",
|
|
"TEXT_QUALITY_DISPLAY"
|
|
};
|
|
|
|
PSTR gpstrStdTQDisplayName[DMTEXT_LAST] = {
|
|
"Letter Quality",
|
|
"Near Letter Quality",
|
|
"Memo Quality",
|
|
"Draft",
|
|
"Text Quality"
|
|
};
|
|
|
|
|
|
PSTR gpstrPositionName[BAPOS_MAX] = {
|
|
"NONE",
|
|
"CENTER",
|
|
"LEFT",
|
|
"RIGHT"
|
|
};
|
|
|
|
PSTR gpstrFaceDirName[FD_MAX] = {
|
|
"FACEUP",
|
|
"FACEDOWN"
|
|
};
|
|
|
|
PSTR gpstrColorName[8] = {
|
|
"NONE",
|
|
"RED",
|
|
"GREEN",
|
|
"BLUE",
|
|
"CYAN",
|
|
"MAGENTA",
|
|
"YELLOW",
|
|
"BLACK"
|
|
};
|
|
|
|
WORD gwColorPlaneCmdID[4] = {
|
|
CMD_DC_GC_PLANE1,
|
|
CMD_DC_GC_PLANE2,
|
|
CMD_DC_GC_PLANE3,
|
|
CMD_DC_GC_PLANE4
|
|
};
|
|
|
|
PSTR gpstrColorPlaneCmdName[8] = {
|
|
"NONE",
|
|
"CmdSendRedData",
|
|
"CmdSendGreenData",
|
|
"CmdSendBlueData",
|
|
"CmdSendCyanData",
|
|
"CmdSendMagentaData",
|
|
"CmdSendYellowData",
|
|
"CmdSendBlackData"
|
|
};
|
|
|
|
PSTR gpstrSectionName[7] = {
|
|
"", // SS_UNINITIALIZED
|
|
"JOB_SETUP", // SS_JOBSETUP
|
|
"DOC_SETUP", // SS_DOCSETUP
|
|
"PAGE_SETUP", // SS_PAGESETUP
|
|
"PAGE_FINISH", // SS_PAGEFINISH
|
|
"DOC_FINISH", // SS_DOCFINISH
|
|
"JOB_FINISH" // SS_JOBFINISH
|
|
};
|
|
|
|
|
|
void *
|
|
GetTableInfo(
|
|
IN PDH pdh, /* Base address of GPC data */
|
|
IN int iResType, /* Resource type - HE_... values */
|
|
IN int iIndex) /* Desired index for this entry */
|
|
{
|
|
int iLimit;
|
|
|
|
//
|
|
// Returns NULL if the requested data is out of range.
|
|
//
|
|
if (iResType >= pdh->sMaxHE)
|
|
return NULL;
|
|
iLimit = pdh->rghe[iResType].sCount;
|
|
|
|
if (iLimit <= 0 || iIndex < 0 || iIndex >= iLimit )
|
|
return NULL;
|
|
|
|
return (PBYTE)pdh + pdh->rghe[iResType].sOffset +
|
|
pdh->rghe[iResType].sLength * iIndex;
|
|
}
|
|
|
|
#if !defined(DEVSTUDIO) // MDS has its own version of this
|
|
void _cdecl
|
|
VOut(
|
|
PCONVINFO pci,
|
|
PSTR pstrFormat,
|
|
...)
|
|
/*++
|
|
Routine Description:
|
|
This function formats a sequence of bytes and writes to the GPD file.
|
|
|
|
Arguments:
|
|
pci - conversionr related info
|
|
pstrFormat - the formatting string
|
|
... - optional arguments needed by formatting
|
|
|
|
Return Value:
|
|
None
|
|
--*/
|
|
{
|
|
va_list ap;
|
|
DWORD dwNumBytesWritten;
|
|
BYTE aubBuf[MAX_GPD_ENTRY_BUFFER_SIZE];
|
|
int iSize;
|
|
|
|
va_start(ap, pstrFormat);
|
|
StringCchPrintfA((PSTR)aubBuf, CCHOF(aubBuf), pstrFormat, ap);
|
|
va_end(ap);
|
|
iSize = strlen(aubBuf);
|
|
|
|
if (pci->dwMode & FM_VOUT_LIST)
|
|
{
|
|
//
|
|
// check for the extra comma before the closing bracket
|
|
//
|
|
if (aubBuf[iSize-4] == ',' && aubBuf[iSize-3] == ')')
|
|
{
|
|
aubBuf[iSize-4] = aubBuf[iSize-3]; // ')'
|
|
aubBuf[iSize-3] = aubBuf[iSize-2]; // '\r'
|
|
aubBuf[iSize-2] = aubBuf[iSize-1]; // '\n'
|
|
iSize--;
|
|
}
|
|
}
|
|
if (!WriteFile(pci->hGPDFile, aubBuf, iSize, &dwNumBytesWritten, NULL) ||
|
|
dwNumBytesWritten != (DWORD)iSize)
|
|
pci->dwErrorCode |= ERR_WRITE_FILE;
|
|
// continue even if an error has occurred.
|
|
}
|
|
|
|
#endif // defined(DEVSTUDIO)
|
|
|
|
void
|
|
EnterStringMode(
|
|
OUT PBYTE pBuf,
|
|
IN OUT PINT pIndex,
|
|
IN OUT PWORD pwCMode)
|
|
/*++
|
|
Routine Description:
|
|
This function enters the STRING mode and emits necessary characters to
|
|
the output buffer.
|
|
|
|
Arguments:
|
|
pBuf: the output buffer
|
|
pIndex: pBuf[*pIndex] is where the next character should be written.
|
|
The index should be updated if any character is emitted.
|
|
pwCMode: pointer to the current mode value. It's updated per request.
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (!(*pwCMode & MODE_STRING))
|
|
{
|
|
pBuf[(*pIndex)++] = '"';
|
|
*pwCMode |= MODE_STRING;
|
|
}
|
|
//
|
|
// if we are also in HEX mode, exit HEX mode.
|
|
//
|
|
else if (*pwCMode & MODE_HEX)
|
|
{
|
|
pBuf[(*pIndex)++] = '>';
|
|
*pwCMode &= ~MODE_HEX;
|
|
}
|
|
}
|
|
|
|
void
|
|
ExitStringMode(
|
|
OUT PBYTE pBuf,
|
|
IN OUT PINT pIndex,
|
|
IN OUT PWORD pwCMode)
|
|
/*++
|
|
Routine Description:
|
|
This function exits the STRING mode and emits necessary characters to
|
|
the output buffer. Check to see if we need to exit HEX mode first.
|
|
|
|
Arguments:
|
|
pBuf: the output buffer
|
|
pIndex: pBuf[*pIndex] is where the next character should be written.
|
|
The index should be updated if any character is emitted.
|
|
pwCMode: pointer to the current mode value. It's updated per request.
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (*pwCMode & MODE_HEX)
|
|
{
|
|
pBuf[(*pIndex)++] = '>';
|
|
*pwCMode &= ~MODE_HEX;
|
|
}
|
|
if (*pwCMode & MODE_STRING)
|
|
{
|
|
pBuf[(*pIndex)++] = '"';
|
|
*pwCMode &= ~MODE_STRING;
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
EnterHexMode(
|
|
OUT PBYTE pBuf,
|
|
IN OUT PINT pIndex,
|
|
IN OUT PWORD pwCMode)
|
|
/*++
|
|
Routine Description:
|
|
This function enters the HEX mode and emits necessary characters to
|
|
the output buffer.
|
|
|
|
Arguments:
|
|
pBuf: the output buffer
|
|
pIndex: pBuf[*pIndex] is where the next character should be written.
|
|
The index should be updated if any character is emitted.
|
|
pwCMode: pointer to the current mode value. It's updated per request.
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// if we are not in STRING mode, enter STRING mode first.
|
|
//
|
|
if (!(*pwCMode & MODE_STRING))
|
|
{
|
|
pBuf[(*pIndex)++] = '"';
|
|
*pwCMode |= MODE_STRING;
|
|
}
|
|
if (!(*pwCMode & MODE_HEX))
|
|
{
|
|
pBuf[(*pIndex)++] = '<';
|
|
*pwCMode |= MODE_HEX;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
BBuildCmdStr(
|
|
IN OUT PCONVINFO pci,
|
|
IN WORD wCmdID,
|
|
IN WORD ocd)
|
|
/*++
|
|
Routine Description:
|
|
This function builds the null-terminated GPD command string, including
|
|
double quotes, stadard variable references, parameter format, newlines
|
|
(except the ending newline), and continuation character "+" if
|
|
applicable. If the GPC command contains a callback id, fill the id in
|
|
pci->wCmdCallbackID. Otherwise, fill it with 0 and fill pci->wCmdLen with
|
|
the command length. If there is no command (NOOCD), fill both with 0.
|
|
|
|
This function handles the special case where CM_YM_RES_DEPENDENT bit
|
|
is set. In that case, the parameter expression needs to add
|
|
(ValueIn / ptTextScale.y) as the first thing before considering other
|
|
fields in EXTCD structure. All values passed in by Unidrv5 are in the
|
|
master units, no exception. For this case, pci->pcm is set to the model's
|
|
CURSORMOVE structure, and pci->pres is set to the current resolution
|
|
being considered.
|
|
|
|
This function handles the special case where RES_DM_GDI is not set (i.e.
|
|
V_BYTE style output) and wCmdID is CMD_RES_SENDBLOCK. In that case, we need
|
|
to add artifical divider equal to (pci->pres->sPinsPerPass / 8).
|
|
This is to match the hard-coded conversion from NumOfDataBytes to the number
|
|
of columns (in both Win95 Unidrv and NT4 RASDD).
|
|
|
|
This function handles the special case for compression commands --- it would
|
|
generate the "" command string (length == 2) even if it's NOOCD because the
|
|
driver relies on its existence to enable compression code.
|
|
|
|
Arguments:
|
|
pci: the conversion related info
|
|
wCmdID: GPC command id. It's unique for each command in GPC.
|
|
ocd: offset to the GPC CD structure on the GPC heap. The offset is
|
|
relative to the beginning of the heap (instead of beginning of
|
|
GPC data).
|
|
|
|
Return Value:
|
|
TRUE if there is a real command. Otherwise, return FALSE (i.e. NOOCD).
|
|
|
|
--*/
|
|
{
|
|
PCD pcd; // pointer to GPC's CD structure
|
|
PBYTE pBuf; // buffer to hold the composed GPD cmd
|
|
INT i = 0; // the next byte to write in the buffer
|
|
INT iPrevLines = 0; // the total # of bytes written for previous lines
|
|
|
|
pci->wCmdCallbackID = 0;
|
|
pBuf = pci->aubCmdBuf;
|
|
|
|
if (ocd != (WORD)NOOCD)
|
|
{
|
|
pcd = (PCD)((PBYTE)(pci->pdh) + (pci->pdh)->loHeap + ocd);
|
|
if (pcd->bCmdCbId > 0)
|
|
{
|
|
//
|
|
// Command callback case. For simplicity, we do not write out
|
|
// any parameters since each command takes different parameters.
|
|
// Instead, we give a warning and ask the minidriver developer
|
|
// to fill in *Param entry. After all, he may need different
|
|
// parameters than what GPC dictates.
|
|
//
|
|
pci->wCmdCallbackID = (WORD)pcd->bCmdCbId;
|
|
pci->dwErrorCode |= ERR_NO_CMD_CALLBACK_PARAMS;
|
|
}
|
|
else
|
|
{
|
|
WORD wCMode = 0; // bit flags indicating the conversion mode
|
|
WORD wFmtLen; // size of command string remaining
|
|
PSTR pFmt; // pointer into command string
|
|
PEXTCD pextcd; // points at next parameter's EXTCD
|
|
WORD wCount; // number of parameters
|
|
WORD wNextParam=0; // index of the next actual param
|
|
PDWORD pdwSVList;
|
|
|
|
pFmt = (PSTR)(pcd + 1);
|
|
wFmtLen = pcd->wLength;
|
|
pextcd = GETEXTCD(pci->pdh, pcd);
|
|
wCount = pcd->wCount;
|
|
pdwSVList = &(gdwSVLists[gawCmdtoSVOffset[wCmdID]]);
|
|
|
|
|
|
while (wFmtLen > 0)
|
|
{
|
|
if (*pFmt != CMD_MARKER)
|
|
{
|
|
if (IS_CHAR_READABLE(*pFmt))
|
|
{
|
|
EnterStringMode(pBuf, &i, &wCMode);
|
|
//
|
|
// check if it's the special character: ", <.
|
|
// If so, add the escape letter '%'
|
|
//
|
|
if (*pFmt == '"' || *pFmt == '<' )
|
|
pBuf[i++] = '%';
|
|
pBuf[i++] = *(pFmt++);
|
|
}
|
|
else // non-readable ASCII: write out hex strings.
|
|
{
|
|
EnterHexMode(pBuf, &i, &wCMode);
|
|
pBuf[i++] = gbHexChar[(*pFmt & 0xF0) >> 4];
|
|
pBuf[i++] = gbHexChar[*pFmt & 0x0F];
|
|
*(pFmt++);
|
|
}
|
|
wFmtLen --;
|
|
}
|
|
else if (wFmtLen > 1 && *(++pFmt) == CMD_MARKER)
|
|
{
|
|
//
|
|
// We have 2 '%' character to write out.
|
|
//
|
|
EnterStringMode(pBuf, &i, &wCMode);
|
|
pBuf[i++] = *pFmt;
|
|
pBuf[i++] = *(pFmt++);
|
|
wFmtLen -= 2;
|
|
}
|
|
else if (wFmtLen > 1) // we have a parameter format string
|
|
{
|
|
INT iParam; // index of the actual param used
|
|
DWORD dwSV; // GPD standard variable id
|
|
|
|
|
|
wFmtLen--; // to account for already eaten '%'
|
|
ExitStringMode(pBuf, &i, &wCMode);
|
|
//
|
|
// insert a white space before the param segment
|
|
//
|
|
pBuf[i++] = ' ';
|
|
pBuf[i++] = '%';
|
|
//
|
|
// first, the format string
|
|
//
|
|
while (wFmtLen > 0 && *pFmt >= '0' && *pFmt <= '9')
|
|
{
|
|
pBuf[i++] = *(pFmt++);
|
|
wFmtLen--;
|
|
}
|
|
if (wFmtLen > 0)
|
|
{
|
|
pBuf[i++] = *(pFmt++); // copy the format letter d,D,...
|
|
wFmtLen--;
|
|
}
|
|
else
|
|
{
|
|
pci->dwErrorCode |= ERR_BAD_GPC_CMD_STRING;
|
|
pBuf[i++] = '!';
|
|
pBuf[i++] = 'E';
|
|
pBuf[i++] = 'R';
|
|
pBuf[i++] = 'R';
|
|
pBuf[i++] = '!';
|
|
break; // exit the while (wFmtLen > 0) loop
|
|
}
|
|
//
|
|
// second, the limits if applicable.
|
|
//
|
|
// 12/19/97 zhanw
|
|
// Note: Win95 Unidrv uses !XCD_GEN_NO_MAX and
|
|
// pextcd->sMax if it's greater than 0 (for the cases of
|
|
// CMD_XM_LINESPACING and CMD_GEN_MAY_REPEAT), and it
|
|
// does NOT use pextcd->sMin at all. NT4 RASDD uses
|
|
// !XCD_GEN_NO_MIN and pextcd->sMin (any value, no
|
|
// particular purpose), and it uses pextcd->sMax without
|
|
// checking !XCD_GEN_NO_MAX (hacky way to handle
|
|
// max-repeat for CMD_RES_SENDBLOCK). Also, Unitool
|
|
// defaults pextcd->sMin to 0.
|
|
// Given that NT4 and Win95 share the same GPC source,
|
|
// the following code should suit both drivers' behavior.
|
|
//
|
|
//
|
|
if (pcd->wCount > 0)
|
|
{
|
|
//
|
|
// in this case, a valid EXTCD may specify limits
|
|
//
|
|
if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
|
|
pextcd->sMax > 0)
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"[%d,%d]",
|
|
(pextcd->fGeneral & XCD_GEN_NO_MIN) ?
|
|
0 : (WORD)pextcd->sMin,
|
|
(WORD)pextcd->sMax);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
}
|
|
// PatRyan - add limits for CmdCopies
|
|
if (wCmdID == CMD_PC_MULT_COPIES)
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"[1,%d]",
|
|
pci->ppc->sMaxCopyCount);
|
|
i += strlen(&(pBuf[i]));
|
|
//
|
|
// third, the value.
|
|
//
|
|
if (pcd->wCount == 0)
|
|
{
|
|
//
|
|
// For this case, each format string wants
|
|
// the next parameter without modification
|
|
//
|
|
dwSV = pdwSVList[wNextParam++];
|
|
if (wCmdID == CMD_RES_SENDBLOCK &&
|
|
!(pci->pres->fDump & RES_DM_GDI) &&
|
|
dwSV == SV_NUMDATABYTES &&
|
|
pci->pres->sPinsPerPass != 8)
|
|
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"{%s / %d}",
|
|
gpstrSVNames[dwSV],
|
|
pci->pres->sPinsPerPass / 8);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
else
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"{%s}",
|
|
gpstrSVNames[dwSV]);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
short sSBDDiv = 1; // special case for CmdSendBlockData
|
|
|
|
if (pci->pdh->wVersion < GPC_VERSION3)
|
|
// For this case, each EXTCD wants the next parameter
|
|
iParam = wNextParam++;
|
|
else
|
|
// For this case, each EXTCD specifies the parameter
|
|
iParam = pextcd->wParam;
|
|
|
|
dwSV = pdwSVList[iParam];
|
|
|
|
if (wCmdID == CMD_RES_SENDBLOCK &&
|
|
!(pci->pres->fDump & RES_DM_GDI) &&
|
|
dwSV == SV_NUMDATABYTES)
|
|
{
|
|
//
|
|
// sPinsPerPass is always a multiplier of 8.
|
|
//
|
|
sSBDDiv = pci->pres->sPinsPerPass / 8;
|
|
}
|
|
|
|
pBuf[i++] = '{';
|
|
//
|
|
// check if max_repeat is needed.
|
|
// Special case for CMD_CM_YM_LINESPACING: never use
|
|
// "max_repeat" by definition.
|
|
//
|
|
if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
|
|
pextcd->sMax > 0 &&
|
|
(pcd->fGeneral & CMD_GEN_MAY_REPEAT) &&
|
|
wCmdID != CMD_CM_YM_LINESPACING)
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"max_repeat(");
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
//
|
|
// compose the expression.
|
|
// Optimize for special cases.
|
|
//
|
|
if (pextcd->sPreAdd != 0)
|
|
pBuf[i++] = '(';
|
|
if (pextcd->sUnitMult > 1)
|
|
pBuf[i++] = '(';
|
|
if (pextcd->sUnitDiv > 1 || sSBDDiv > 1)
|
|
pBuf[i++] = '(';
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"%s ", gpstrSVNames[dwSV]);
|
|
i += strlen(&(pBuf[i]));
|
|
//
|
|
// special check for CM_YM_RES_DEPENDENT flag
|
|
//
|
|
if ((wCmdID == CMD_CM_YM_ABS ||
|
|
wCmdID == CMD_CM_YM_REL ||
|
|
wCmdID == CMD_CM_YM_RELUP ||
|
|
wCmdID == CMD_CM_YM_LINESPACING) &&
|
|
(pci->pcm->fYMove & CM_YM_RES_DEPENDENT) &&
|
|
pci->pres->ptTextScale.y != 1)
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"/ %d ",
|
|
pci->pres->ptTextScale.y);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
//
|
|
// continue with normal processing
|
|
//
|
|
if (pextcd->sPreAdd > 0)
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"+ %d) ",
|
|
pextcd->sPreAdd);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
else if (pextcd->sPreAdd < 0)
|
|
{
|
|
StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"- %d) ",
|
|
-pextcd->sPreAdd);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
if (pextcd->sUnitMult > 1)
|
|
{
|
|
i += StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"* %d) ",
|
|
pextcd->sUnitMult);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
if (pextcd->sUnitDiv > 1 || sSBDDiv > 1)
|
|
{
|
|
i += StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
((pextcd->fGeneral & XCD_GEN_MODULO) ?
|
|
"MOD %d) " : "/ %d) "),
|
|
((pextcd->sUnitDiv) ? pextcd->sUnitDiv : 1) * sSBDDiv);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
if (pextcd->sUnitAdd > 0)
|
|
{
|
|
i += StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"+ %d",
|
|
pextcd->sUnitAdd);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
else if (pextcd->sUnitAdd < 0)
|
|
{
|
|
i += StringCchPrintfA((PSTR)&(pBuf[i]),
|
|
CCHOF(pci->aubCmdBuf) - i,
|
|
"- %d",
|
|
pextcd->sUnitAdd);
|
|
i += strlen(&(pBuf[i]));
|
|
}
|
|
//
|
|
// check if need to close max_repeat
|
|
//
|
|
if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
|
|
pextcd->sMax > 0 &&
|
|
(pcd->fGeneral & CMD_GEN_MAY_REPEAT) &&
|
|
wCmdID != CMD_CM_YM_LINESPACING)
|
|
pBuf[i++] = ')';
|
|
|
|
pBuf[i++] = '}'; // close the value portion
|
|
}
|
|
pextcd++; // advance to next EXTCD
|
|
} // end param case
|
|
else
|
|
{
|
|
pci->dwErrorCode |= ERR_BAD_GPC_CMD_STRING;
|
|
pBuf[i++] = '!';
|
|
pBuf[i++] = 'E';
|
|
pBuf[i++] = 'R';
|
|
pBuf[i++] = 'R';
|
|
pBuf[i++] = '!';
|
|
|
|
break; // exit the while (wFmtLen > 0) loop
|
|
}
|
|
//
|
|
// check if the string is already quite long. If so,
|
|
// start a new line.
|
|
//
|
|
if ((i - iPrevLines) >= MAX_GPD_CMD_LINE_LENGTH)
|
|
{
|
|
ExitStringMode(pBuf, &i, &wCMode);
|
|
pBuf[i++] = '\r';
|
|
pBuf[i++] = '\n';
|
|
iPrevLines = i;
|
|
pBuf[i++] = '+';
|
|
pBuf[i++] = ' ';
|
|
}
|
|
} // while (wFmtLen > 0)
|
|
//
|
|
// finished processing the format string. Exit properly
|
|
//
|
|
ExitStringMode(pBuf, &i, &wCMode);
|
|
}
|
|
} // !NOOCD case
|
|
else if (wCmdID == CMD_CMP_TIFF || wCmdID == CMD_CMP_DELTAROW ||
|
|
wCmdID == CMD_CMP_FE_RLE)
|
|
{
|
|
pBuf[i++] = '"'; // generate "" command string
|
|
pBuf[i++] = '"';
|
|
}
|
|
pBuf[i] = 0;
|
|
pci->wCmdLen = (WORD)i;
|
|
return (i != 0 || pci->wCmdCallbackID != 0);
|
|
}
|
|
|
|
void
|
|
VOutputOrderedCmd(
|
|
IN OUT PCONVINFO pci,// contain info about the cmd to output
|
|
PSTR pstrCmdName, // cmd name such as "CmdSelect"
|
|
SEQSECTION ss, // sequence section id (ENUM type defined in GPD.H)
|
|
WORD wOrder, // order number within the section
|
|
BOOL bIndent) // whether to use 2-level indentation or not
|
|
{
|
|
//
|
|
// check for no-cmd case
|
|
//
|
|
if (wOrder > 0 && (pci->wCmdLen > 0 || pci->wCmdCallbackID > 0))
|
|
{
|
|
VOut(pci, "%s*Command: %s\r\n%s{\r\n",
|
|
bIndent? " " : "",
|
|
pstrCmdName,
|
|
bIndent? " " : "");
|
|
VOut(pci, "%s*Order: %s.%d\r\n",
|
|
bIndent? " " : " ",
|
|
gpstrSectionName[ss],
|
|
wOrder);
|
|
if (pci->wCmdCallbackID > 0)
|
|
{
|
|
VOut(pci, "%s*CallbackID: %d\r\n",
|
|
bIndent? " " : " ",
|
|
pci->wCmdCallbackID);
|
|
VOut(pci, "*%% Error: you must check if this command callback requires any parameters!\r\n");
|
|
}
|
|
else
|
|
VOut(pci, "%s*Cmd: %s\r\n",
|
|
bIndent? " " : " ",
|
|
pci->aubCmdBuf);
|
|
VOut(pci, "%s}\r\n", bIndent? " " : "");
|
|
}
|
|
}
|
|
|
|
void
|
|
VOutputSelectionCmd(
|
|
IN OUT PCONVINFO pci,// contain info about the cmd to output
|
|
IN BOOL bDocSetup, // whether in DOC_SETUP or PAGE_SETUP section
|
|
IN WORD wOrder) // order number within the section
|
|
//
|
|
// This function outputs an option selection command which uses level 2
|
|
// indentation.
|
|
//
|
|
{
|
|
VOutputOrderedCmd(pci, "CmdSelect",
|
|
bDocSetup? SS_DOCSETUP : SS_PAGESETUP,
|
|
wOrder, TRUE);
|
|
}
|
|
|
|
void
|
|
VOutputConfigCmd(
|
|
IN OUT PCONVINFO pci,// contain info about the cmd to output
|
|
IN PSTR pstrCmdName, // command name
|
|
IN SEQSECTION ss, // sequence section id
|
|
IN WORD wOrder) // order number within the section
|
|
//
|
|
// This function outputs a printer configuration command at the root level.
|
|
//
|
|
{
|
|
VOutputOrderedCmd(pci, pstrCmdName, ss, wOrder, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
VOutputCmdBase(
|
|
IN OUT PCONVINFO pci, // contain info about the cmd to output
|
|
PSTR pstrCmdName, // cmd name such as "CmdXMoveAbsolute"
|
|
BOOL bExtern, // whether to add EXTERN_GLOBAL prefix
|
|
BOOL bIndent) // whter to use level 2 indentation
|
|
{
|
|
if (pci->wCmdLen > 0)
|
|
VOut(pci, "%s%s*Command: %s { *Cmd : %s }\r\n",
|
|
bIndent? " " : "",
|
|
bExtern ? "EXTERN_GLOBAL: " : "",
|
|
pstrCmdName, pci->aubCmdBuf);
|
|
else if (pci->wCmdCallbackID > 0)
|
|
VOut(pci, "%s%s*Command: %s { *CallbackID: %d }\r\n",
|
|
bIndent? " " : "",
|
|
bExtern ? "EXTERN_GLOBAL: " : "",
|
|
pstrCmdName,
|
|
pci->wCmdCallbackID);
|
|
}
|
|
|
|
void
|
|
VOutputCmd(
|
|
IN OUT PCONVINFO pci, // contain info about the cmd to output
|
|
IN PSTR pstrCmdName)
|
|
//
|
|
// This function outputs printing commands at the root level (i.e. no
|
|
// indentation). It uses the shortcut format: *Command: <name> : <cmd>
|
|
// unless the callback is used.
|
|
//
|
|
{
|
|
VOutputCmdBase(pci, pstrCmdName, FALSE, FALSE);
|
|
}
|
|
|
|
void
|
|
VOutputExternCmd(
|
|
IN OUT PCONVINFO pci,
|
|
IN PSTR pstrCmdName)
|
|
//
|
|
// This function outputs the printing commands inside feature option
|
|
// construct, i.e. they should be prefixed with "EXTERN_GLOBAL" and use
|
|
// level 2 indentation.
|
|
//
|
|
{
|
|
//
|
|
// 1/7/97 ZhanW
|
|
// According to PeterWo, constructs don't need EXTERN_GLOBAL prefix
|
|
//
|
|
VOutputCmdBase(pci, pstrCmdName, FALSE, TRUE);
|
|
}
|
|
|
|
void
|
|
VOutputCmd2(
|
|
IN OUT PCONVINFO pci,
|
|
IN PSTR pstrCmdName)
|
|
//
|
|
// This function outputs printing commands with one level dependency,
|
|
// i.e. they should use level 2 indentation.
|
|
//
|
|
{
|
|
VOutputCmdBase(pci, pstrCmdName, FALSE, TRUE);
|
|
}
|
|
|
|
WORD gwDefaultCmdOrder[] = {
|
|
PC_ORD_PAPER_SOURCE,
|
|
PC_ORD_PAPER_DEST,
|
|
PC_ORD_PAPER_SIZE,
|
|
PC_ORD_RESOLUTION,
|
|
PC_ORD_TEXTQUALITY,
|
|
0,
|
|
};
|
|
|
|
BOOL
|
|
BInDocSetup(
|
|
IN PCONVINFO pci,
|
|
IN WORD ord,
|
|
OUT PWORD pwOrder)
|
|
/*++
|
|
Routine Description:
|
|
This function determines the section and the order number of the given
|
|
command.
|
|
|
|
Arguments:
|
|
pci: pointer to CONVINFO
|
|
ord: PC_ORD_xxx id identifying the command.
|
|
pwOrder: to store the order number as in GPC
|
|
|
|
Return:
|
|
TRUE if the command should be in DOC_SETUP section.
|
|
Note that for both NT RASDD and Win95 Unidrv:
|
|
1. All commands before PC_ORD_BEGINPAGE (exclusive) are sent per
|
|
job and per ResetDC. So they should be in DOC_SETUP section.
|
|
2. All commands after PC_ORD_BEGINPAGE (inclusive) is sent at the
|
|
beginning of each page. So they should be in PAGE_SETUP section.
|
|
|
|
--*/
|
|
{
|
|
PWORD pOrds;
|
|
BOOL bDocSetup = TRUE;
|
|
WORD count;
|
|
|
|
if (pci->ppc->orgwOrder == (WORD)NOT_USED)
|
|
pOrds = gwDefaultCmdOrder;
|
|
else
|
|
pOrds = (PWORD)((PBYTE)pci->pdh + pci->pdh->loHeap +
|
|
pci->ppc->orgwOrder);
|
|
|
|
for (count = 1; *pOrds != 0 && *pOrds != ord; count++, pOrds++)
|
|
{
|
|
if (bDocSetup && *pOrds == PC_ORD_BEGINPAGE)
|
|
bDocSetup = FALSE;
|
|
}
|
|
if (*pOrds == 0)
|
|
*pwOrder = 0; // didn't find the cmd in the sequence
|
|
else // *pOrds == ord
|
|
{
|
|
*pwOrder = count;
|
|
if (ord == PC_ORD_BEGINPAGE)
|
|
bDocSetup = FALSE;
|
|
}
|
|
return bDocSetup;
|
|
|
|
}
|