Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1666 lines
51 KiB

  1. /*++
  2. Copyright (c) 1996-1997 Microsoft Corporation
  3. Module Name:
  4. utils.c
  5. Abstract:
  6. Utility functions used by the GPC-to-GPD converter
  7. Environment:
  8. user-mode only.
  9. Revision History:
  10. 10/17/96 -zhanw-
  11. Created it.
  12. --*/
  13. #include "gpc2gpd.h"
  14. //
  15. // define global read-only variables
  16. //
  17. BYTE gbHexChar[16] = {'0','1','2','3','4','5','6','7','8','9',
  18. 'A','B','C','D','E','F'};
  19. DWORD gdwErrFlag[NUM_ERRS] = {
  20. ERR_BAD_GPCDATA,
  21. ERR_OUT_OF_MEMORY,
  22. ERR_WRITE_FILE,
  23. ERR_MD_CMD_CALLBACK,
  24. ERR_CM_GEN_FAV_XY,
  25. ERR_CM_XM_RESET_FONT,
  26. ERR_CM_XM_ABS_NO_LEFT,
  27. ERR_CM_YM_TRUNCATE,
  28. ERR_RF_MIN_IS_WHITE,
  29. ERR_INCONSISTENT_PAGEPROTECT,
  30. ERR_NON_ZERO_FEED_MARGINS_ON_RT90_PRINTER,
  31. ERR_BAD_GPC_CMD_STRING,
  32. ERR_RES_BO_RESET_FONT,
  33. ERR_RES_BO_OEMGRXFILTER,
  34. ERR_CM_YM_RES_DEPENDENT,
  35. ERR_MOVESCALE_NOT_FACTOR_OF_MASTERUNITS,
  36. ERR_NO_CMD_CALLBACK_PARAMS,
  37. ERR_HAS_DUPLEX_ON_CMD,
  38. ERR_PSRC_MAN_PROMPT,
  39. ERR_PS_SUGGEST_LNDSCP,
  40. ERR_HAS_SECOND_FONT_ID_CMDS,
  41. ERR_DLI_FMT_CAPSL,
  42. ERR_DLI_FMT_PPDS,
  43. ERR_DLI_GEN_DLPAGE,
  44. ERR_DLI_GEN_7BIT_CHARSET,
  45. ERR_DC_SEND_PALETTE,
  46. ERR_RES_BO_NO_ADJACENT,
  47. ERR_MD_NO_ADJACENT,
  48. ERR_CURSOR_ORIGIN_ADJUSTED,
  49. ERR_PRINTABLE_ORIGIN_ADJUSTED,
  50. ERR_PRINTABLE_AREA_ADJUSTED,
  51. ERR_MOVESCALE_NOT_FACTOR_INTO_SOME_RESSCALE
  52. };
  53. PSTR gpstrErrMsg[NUM_ERRS] = {
  54. "Error: Bad GPC data.\r\n",
  55. "Error: Out of system memory.\r\n",
  56. "Error: Cannot write to the GPD file.\r\n",
  57. "Warning: MODELDATA.fGeneral MD_CMD_CALLBACK is set.\r\n",
  58. "Warning: CURSORMODE.fGeneral CM_GEN_FAV_XY is set.\r\n",
  59. "Warning: CURSORMOVE.fXMove CM_XM_RESET_FONT is set.\r\n",
  60. "Warning: CURSORMOVE.fXMove CM_XM_ABS_NO_LEFT is set.\r\n",
  61. "Warning: CURSORMOVE.fYMove CM_YM_TRUNCATE is set.\r\n",
  62. "Warning: RECTFILL.fGeneral RF_MIN_IS_WHITE is set.\r\n",
  63. "Error: Inconsistent GPC data: some PAPERSIZE have PageProtect On/Off cmds while others do not. PageProtect feature is not generated.\r\n",
  64. "Error: Some PAPERSOURCE have non-zero top/bottom margins on this RT90 printer. Check the GPD file for details.\r\n",
  65. "Error: Some GPC command strings are illegal. Search for !ERR! in the GPD file.\r\n",
  66. "Warning: Some RESOLUTION have RES_BO_RESET_FONT flag set. Check the GPD file for details.\r\n",
  67. "Error: Some RESOLUTION have RES_BO_OEMGRXFILTER flag set. Check the GPD file for details.\r\n",
  68. "Error: The generated *YMoveUnit value is wrong because Y move cmds have dependency on the resolution. Correct it manually.\r\n",
  69. "Error: The MoveUnits are not factors of the MasterUnits. Correct the GPC using Unitool before converting.\r\n",
  70. "Error: At least one callback command is generated. Check the GPD file to see if you need any parameters.\r\n",
  71. "Warning: PAGECONTROL has non-NULL DUPLEX_ON command.\r\n",
  72. "Warning: Some PAPERSOURCE have PSRC_MAN_PROMPT flag set. Check the GPD file for details.\r\n",
  73. "Warning: Some PAPERSIZE have PS_SUGGEST_LNDSCP flag set. Check the GPD file for details.\r\n",
  74. "Warning: DOWNLOADINFO has non-NULL xxx_SECOND_FONT_ID_xxx commands.\r\n",
  75. "Error: DLI_FMT_CAPSL flag is set. Must supply custom code to support this font format.\r\n",
  76. "Error: DLI_FMT_PPDS flag is set. Must supply custom code to support this font format.\r\n",
  77. "Warning: DLI_GEN_DLPAGE flag is set.\r\n",
  78. "Warning: DLI_GEN_7BIT_CHARSET flag is set.\r\n",
  79. "Warning: DEVCOLOR.fGeneral DC_SEND_PALETTE flag is set.\r\n",
  80. "Warning: Some RESOLUTION have RES_BO_NO_ADJACENT flag set. Check the GPD file for details.\r\n",
  81. "Warning: MODELDATA.fGeneral MD_NO_ADJACENT is set.\r\n",
  82. "Warning: Some *CursorOrigin values have been adjusted. Check the GPD file for details.\r\n",
  83. "Warning: Some *PrintableOrigin values have been adjusted. Check the GPD file for details.\r\n",
  84. "Warning: Some *PrintableArea values have been adjusted. Check the GPD file for details.\r\n",
  85. "Warning: Please check that every *PrintableOrigin (X,Y) factor evenly into the move unit scale X/Y.\r\n"
  86. };
  87. //
  88. // define standard variable name strings
  89. //
  90. PSTR gpstrSVNames[SV_MAX] = {
  91. "NumOfDataBytes",
  92. "RasterDataWidthInBytes",
  93. "RasterDataHeightInPixels",
  94. "NumOfCopies",
  95. "PrintDirInCCDegrees",
  96. "DestX",
  97. "DestY",
  98. "DestXRel",
  99. "DestYRel",
  100. "LinefeedSpacing",
  101. "RectXSize",
  102. "RectYSize",
  103. "GrayPercentage",
  104. "NextFontID",
  105. "NextGlyph",
  106. "PhysPaperLength",
  107. "PhysPaperWidth",
  108. "FontHeight",
  109. "FontWidth",
  110. "FontMaxWidth",
  111. "FontBold",
  112. "FontItalic",
  113. "FontUnderline",
  114. "FontStrikeThru",
  115. "CurrentFontID",
  116. "TextYRes",
  117. "TextXRes",
  118. "GraphicsYRes",
  119. "GraphicsXRes",
  120. "Rop3",
  121. "RedValue",
  122. "GreenValue",
  123. "BlueValue",
  124. "PaletteIndexToProgram",
  125. "CurrentPaletteIndex"
  126. };
  127. //
  128. // define the standard variable id heap. It consists of a series of id runs.
  129. // Each run is a sequence of standard variable id's (SV_xxx value, 0-based)
  130. // ended by -1 (0xFFFFFFFF). The runs are constructed based on the need of
  131. // GPC commands. Basically, one run corresponds to one GPC command that
  132. // requires parameters. If more than one GPC command share the same set of
  133. // parameters, then they can share the same run.
  134. //
  135. DWORD gdwSVLists[] = {
  136. EOR, // place holder for all GPC commands that has no parameter
  137. SV_NUMDATABYTES, // CMD_RES_SENDBLOCK can have 3 params
  138. SV_HEIGHTINPIXELS,
  139. SV_WIDTHINBYTES,
  140. EOR,
  141. SV_COPIES, // offset 5. CMD_PC_MULT_COPIES
  142. EOR,
  143. SV_DESTX, // offset 7
  144. EOR,
  145. SV_DESTY, // offset 9
  146. EOR,
  147. SV_DESTXREL, // offset 11
  148. EOR,
  149. SV_DESTYREL, // offset 13
  150. EOR,
  151. SV_LINEFEEDSPACING, // offset 15
  152. EOR,
  153. SV_DESTXREL, // offset 17
  154. SV_DESTYREL,
  155. EOR,
  156. SV_DESTX, // offset 20
  157. SV_DESTY,
  158. EOR,
  159. SV_RECTXSIZE, // offset 23
  160. EOR,
  161. SV_RECTYSIZE, // offset 25
  162. EOR,
  163. SV_GRAYPERCENT, // offset 27
  164. EOR,
  165. SV_NEXTFONTID, // offset 29
  166. EOR,
  167. SV_CURRENTFONTID, // offset 31
  168. EOR,
  169. SV_NEXTGLYPH, // offset 33
  170. EOR,
  171. SV_PHYSPAPERLENGTH, // offset 35
  172. SV_PHYSPAPERWIDTH,
  173. EOR,
  174. SV_PRINTDIRECTION, // offset 38
  175. EOR,
  176. SV_NUMDATABYTES, // offset 40
  177. EOR,
  178. SV_REDVALUE, // offset 42
  179. SV_GREENVALUE,
  180. SV_BLUEVALUE,
  181. SV_PALETTEINDEXTOPROGRAM,
  182. EOR,
  183. SV_CURRENTPALETTEINDEX, // offset 47
  184. EOR
  185. };
  186. //
  187. // map CMD_xxx id to the corresponding DWORD offset to the standard variable
  188. // id heap. That is, gdwSVLists[gawCmdtoSVOffset[CMD_RES_SELECTRES]] is the
  189. // beginning of a parameter run for GPC's command CMD_RES_SELECTRES. If the
  190. // first element in the run of EOR, that means the command takes no param.
  191. //
  192. WORD gawCmdtoSVOffset[MAXCMD+MAXECMD] = {
  193. 0, // CMD_RES_SELECTRES
  194. 0, // CMD_RES_BEGINGRAPHICS
  195. 0, // CMD_RES_ENDGRAPHICS
  196. 1, // CMD_RES_SENDBLOCK
  197. 0, // CMD_RES_ENDBLOCK
  198. 0, // CMD_CMP_NONE
  199. 0, // CMD_CMP_RLE
  200. 0, // CMD_CMP_TIFF
  201. 0, // CMD_CMP_DELTAROW
  202. 0, // CMD_CMP_BITREPEAT
  203. 0, // CMD_CMP_FE_RLE
  204. 0, // CMD_PC_BEGIN_DOC
  205. 0, // CMD_PC_BEGIN_PAGE
  206. 0, // CMD_PC_DUPLEX_ON
  207. 0, // CMD_PC_ENDDOC
  208. 0, // CMD_PC_ENDPAGE
  209. 0, // CMD_PC_DUPLEX_OFF
  210. 0, // CMD_PC_ABORT
  211. 0, // CMD_PC_PORTRAIT, CMD_PC_ORIENTATION
  212. 0, // CMD_PC_LANDSCAPE
  213. 5, // CMD_PC_MULT_COPIES
  214. 0, // CMD_PC_DUPLEX_VERT
  215. 0, // CMD_PC_DUPLEX_HORZ
  216. 38, // CMD_PC_PRINT_DIR
  217. 0, // CMD_PC_JOB_SEPARATION
  218. 7, // CMD_CM_XM_ABS
  219. 11, // CMD_CM_XM_REL
  220. 11, // CMD_CM_XM_RELLEFT
  221. 9, // CMD_CM_YM_ABS
  222. 13, // CMD_CM_YM_REL
  223. 13, // CMD_CM_YM_RELUP
  224. 15, // CMD_CM_YM_LINESPACING
  225. 17, // CMD_CM_XY_REL
  226. 20, // CMD_CM_XY_ABS
  227. 0, // CMD_CM_CR
  228. 0, // CMD_CM_LF
  229. 0, // CMD_CM_FF
  230. 0, // CMD_CM_BS
  231. 0, // CMD_CM_UNI_DIR
  232. 0, // CMD_CM_UNI_DIR_OFF
  233. 0, // CMD_CM_PUSH_POS
  234. 0, // CMD_CM_POP_POS
  235. 0, // CMD_FS_BOLD_ON
  236. 0, // CMD_FS_BOLD_OFF
  237. 0, // CMD_FS_ITALIC_ON
  238. 0, // CMD_FS_ITALIC_OFF
  239. 0, // CMD_FS_UNDERLINE_ON
  240. 0, // CMD_FS_UNDERLINE_OFF
  241. 0, // CMD_FS_DOUBLEUNDERLINE_ON
  242. 0, // CMD_FS_DOUBLEUNDERLINE_OFF
  243. 0, // CMD_FS_STRIKETHRU_ON
  244. 0, // CMD_FS_STRIKETHRU_OFF
  245. 0, // CMD_FS_WHITE_TEXT_ON
  246. 0, // CMD_FS_WHITE_TEXT_OFF
  247. 0, // CMD_FS_SINGLE_BYTE
  248. 0, // CMD_FS_DOUBLE_BYTE
  249. 0, // CMD_FS_VERT_ON
  250. 0, // CMD_FS_VERT_OFF
  251. 0, // CMD_DC_TC_BLACK
  252. 0, // CMD_DC_TC_RED
  253. 0, // CMD_DC_TC_GREEN
  254. 0, // CMD_DC_TC_YELLOW
  255. 0, // CMD_DC_TC_BLUE
  256. 0, // CMD_DC_TC_MAGENTA
  257. 0, // CMD_DC_TC_CYAN
  258. 0, // CMD_DC_TC_WHITE
  259. 0, // CMD_DC_GC_SETCOLORMODE
  260. 0, // CMD_DC_PC_START
  261. 42, // CMD_DC_PC_ENTRY
  262. 0, // CMD_DC_PC_END
  263. 47, // CMD_DC_PC_SELECTINDEX
  264. 0, // CMD_DC_SETMONOMODE
  265. 40, // CMD_DC_GC_PLANE1
  266. 40, // CMD_DC_GC_PLANE2
  267. 40, // CMD_DC_GC_PLANE3
  268. 40, // CMD_DC_GC_PLANE4
  269. 23, // CMD_RF_X_SIZE
  270. 25, // CMD_RF_Y_SIZE
  271. 27, // CMD_RF_GRAY_FILL
  272. 0, // CMD_RF_WHITE_FILL
  273. 0, // Reserved
  274. 0, // CMD_BEGIN_DL_JOB
  275. 0, // CMD_BEGIN_FONT_DL
  276. 29, // CMD_SET_FONT_ID
  277. 0, // CMD_SEND_FONT_DCPT --- this command is no longer used.
  278. 31, // CMD_SELECT_FONT_ID
  279. 33, // CMD_SET_CHAR_CODE
  280. 0, // CMD_SEND_CHAR_DCPT --- this command is no longer used.
  281. 0, // CMD_END_FONT_DL
  282. 0, // CMD_MAKE_PERM
  283. 0, // CMD_MAKE_TEMP
  284. 0, // CMD_END_DL_JOB
  285. 0, // CMD_DEL_FONT
  286. 0, // CMD_DEL_ALL_FONTS
  287. 0, // CMD_SET_SECOND_FONT_ID --- used only by CAPSL. Obsolete.
  288. 0, // CMD_SELECT_SECOND_FONT_ID --- used only by CAPSL. Obsolete.
  289. 0, // CMD_TEXTQUALITY
  290. 0, // CMD_PAPERSOURCE
  291. 0, // CMD_PAPERQUALITY
  292. 0, // CMD_PAPERDEST
  293. 35, // CMD_PAPERSIZE
  294. 35, // CMD_PAPERSIZE_LAND
  295. 0, // CMD_PAGEPROTECT_ON
  296. 0, // CMD_PAGEPROTECT_OFF
  297. 0, // CMD_IMAGECONTROL
  298. 0 // CMD_PRINTDENSITY
  299. };
  300. PSTR gpstrFeatureName[FID_MAX] = {
  301. "OutputBin",
  302. "ImageControl",
  303. "PrintDensity"
  304. };
  305. PSTR gpstrFeatureDisplayNameMacro[FID_MAX] = { // reference value macro names
  306. "OUTPUTBIN_DISPLAY",
  307. "IMAGECONTROL_DISPLAY",
  308. "PRINTDENSITY_DISPLAY"
  309. };
  310. PSTR gpstrFeatureDisplayName[FID_MAX] = { // reference names
  311. "Output Bin",
  312. "Image Control",
  313. "Print Density"
  314. };
  315. INT gintFeatureDisplayNameID[FID_MAX] = { // reference string resource ids
  316. 2111, // these values must match definitions in printer5\inc\common.rc
  317. 2112,
  318. 2113
  319. };
  320. WORD gwFeatureMDOI[FID_MAX] = {
  321. MD_OI_PAPERDEST,
  322. MD_OI_IMAGECONTROL,
  323. MD_OI_PRINTDENSITY
  324. };
  325. WORD gwFeatureOCDWordOffset[FID_MAX] = {
  326. 3,
  327. 3,
  328. 2
  329. };
  330. WORD gwFeatureHE[FID_MAX] = {
  331. HE_PAPERDEST,
  332. HE_IMAGECONTROL,
  333. HE_PRINTDENSITY
  334. };
  335. WORD gwFeatureORD[FID_MAX] = {
  336. PC_ORD_PAPER_DEST,
  337. PC_ORD_IMAGECONTROL,
  338. PC_ORD_PRINTDENSITY
  339. };
  340. WORD gwFeatureCMD[FID_MAX] = {
  341. CMD_PAPERDEST,
  342. CMD_IMAGECONTROL,
  343. CMD_PRINTDENSITY
  344. };
  345. //
  346. // define the mapping between standard paper size id to the standard
  347. // PaperSize option name
  348. //
  349. PSTR gpstrStdPSName[DMPAPER_COUNT] = {
  350. "LETTER",
  351. "LETTERSMALL",
  352. "TABLOID",
  353. "LEDGER",
  354. "LEGAL",
  355. "STATEMENT",
  356. "EXECUTIVE",
  357. "A3",
  358. "A4",
  359. "A4SMALL",
  360. "A5",
  361. "B4",
  362. "B5",
  363. "FOLIO",
  364. "QUARTO",
  365. "10X14",
  366. "11X17",
  367. "NOTE",
  368. "ENV_9",
  369. "ENV_10",
  370. "ENV_11",
  371. "ENV_12",
  372. "ENV_14",
  373. "CSHEET",
  374. "DSHEET",
  375. "ESHEET",
  376. "ENV_DL",
  377. "ENV_C5",
  378. "ENV_C3",
  379. "ENV_C4",
  380. "ENV_C6",
  381. "ENV_C65",
  382. "ENV_B4",
  383. "ENV_B5",
  384. "ENV_B6",
  385. "ENV_ITALY",
  386. "ENV_MONARCH",
  387. "ENV_PERSONAL",
  388. "FANFOLD_US",
  389. "FANFOLD_STD_GERMAN",
  390. "FANFOLD_LGL_GERMAN",
  391. "ISO_B4",
  392. "JAPANESE_POSTCARD",
  393. "9X11",
  394. "10X11",
  395. "15X11",
  396. "ENV_INVITE",
  397. "", // RESERVED_48
  398. "", // RESERVED_49
  399. "LETTER_EXTRA",
  400. "LEGAL_EXTRA",
  401. "TABLOID_EXTRA",
  402. "A4_EXTRA",
  403. "LETTER_TRANSVERSE",
  404. "A4_TRANSVERSE",
  405. "LETTER_EXTRA_TRANSVERSE",
  406. "A_PLUS",
  407. "B_PLUS",
  408. "LETTER_PLUS",
  409. "A4_PLUS",
  410. "A5_TRANSVERSE",
  411. "B5_TRANSVERSE",
  412. "A3_EXTRA",
  413. "A5_EXTRA",
  414. "B5_EXTRA",
  415. "A2",
  416. "A3_TRANSVERSE",
  417. "A3_EXTRA_TRANSVERSE",
  418. "DBL_JAPANESE_POSTCARD",
  419. "A6",
  420. "JENV_KAKU2",
  421. "JENV_KAKU3",
  422. "JENV_CHOU3",
  423. "JENV_CHOU4",
  424. "LETTER_ROTATED",
  425. "A3_ROTATED",
  426. "A4_ROTATED",
  427. "A5_ROTATED",
  428. "B4_JIS_ROTATED",
  429. "B5_JIS_ROTATED",
  430. "JAPANESE_POSTCARD_ROTATED",
  431. "DBL_JAPANESE_POSTCARD_ROTATED",
  432. "A6_ROTATED",
  433. "JENV_KAKU2_ROTATED",
  434. "JENV_KAKU3_ROTATED",
  435. "JENV_CHOU3_ROTATED",
  436. "JENV_CHOU4_ROTATED",
  437. "B6_JIS",
  438. "B6_JIS_ROTATED",
  439. "12X11",
  440. "JENV_YOU4",
  441. "JENV_YOU4_ROTATED",
  442. "P16K",
  443. "P32K",
  444. "P32KBIG",
  445. "PENV_1",
  446. "PENV_2",
  447. "PENV_3",
  448. "PENV_4",
  449. "PENV_5",
  450. "PENV_6",
  451. "PENV_7",
  452. "PENV_8",
  453. "PENV_9",
  454. "PENV_10",
  455. "P16K_ROTATED",
  456. "P32K_ROTATED",
  457. "P32KBIG_ROTATED",
  458. "PENV_1_ROTATED",
  459. "PENV_2_ROTATED",
  460. "PENV_3_ROTATED",
  461. "PENV_4_ROTATED",
  462. "PENV_5_ROTATED",
  463. "PENV_6_ROTATED",
  464. "PENV_7_ROTATED",
  465. "PENV_8_ROTATED",
  466. "PENV_9_ROTATED",
  467. "PENV_10_ROTATED"
  468. };
  469. PSTR gpstrStdPSDisplayNameMacro[DMPAPER_COUNT] = {
  470. "LETTER_DISPLAY",
  471. "LETTERSMALL_DISPLAY",
  472. "TABLOID_DISPLAY",
  473. "LEDGER_DISPLAY",
  474. "LEGAL_DISPLAY",
  475. "STATEMENT_DISPLAY",
  476. "EXECUTIVE_DISPLAY",
  477. "A3_DISPLAY",
  478. "A4_DISPLAY",
  479. "A4SMALL_DISPLAY",
  480. "A5_DISPLAY",
  481. "B4_DISPLAY",
  482. "B5_DISPLAY",
  483. "FOLIO_DISPLAY",
  484. "QUARTO",
  485. "10X14_DISPLAY",
  486. "11X17_DISPLAY",
  487. "NOTE_DISPLAY",
  488. "ENV_9_DISPLAY",
  489. "ENV_10_DISPLAY",
  490. "ENV_11_DISPLAY",
  491. "ENV_12_DISPLAY",
  492. "ENV_14_DISPLAY",
  493. "CSHEET_DISPLAY",
  494. "DSHEET_DISPLAY",
  495. "ESHEET_DISPLAY",
  496. "ENV_DL_DISPLAY",
  497. "ENV_C5_DISPLAY",
  498. "ENV_C3_DISPLAY",
  499. "ENV_C4_DISPLAY",
  500. "ENV_C6_DISPLAY",
  501. "ENV_C65_DISPLAY",
  502. "ENV_B4_DISPLAY",
  503. "ENV_B5_DISPLAY",
  504. "ENV_B6_DISPLAY",
  505. "ENV_ITALY_DISPLAY",
  506. "ENV_MONARCH_DISPLAY",
  507. "ENV_PERSONAL_DISPLAY",
  508. "FANFOLD_US_DISPLAY",
  509. "FANFOLD_STD_GERMAN_DISPLAY",
  510. "FANFOLD_LGL_GERMAN_DISPLAY",
  511. "ISO_B4_DISPLAY",
  512. "JAPANESE_POSTCARD_DISPLAY",
  513. "9X11_DISPLAY",
  514. "10X11_DISPLAY",
  515. "15X11_DISPLAY",
  516. "ENV_INVITE_DISPLAY",
  517. "", // RESERVED--DO NOT USE
  518. "", // RESERVED--DO NOT USE
  519. "LETTER_EXTRA_DISPLAY",
  520. "LEGAL_EXTRA_DISPLAY",
  521. "TABLOID_EXTRA_DISPLAY",
  522. "A4_EXTRA_DISPLAY",
  523. "LETTER_TRANSVERSE_DISPLAY",
  524. "A4_TRANSVERSE_DISPLAY",
  525. "LETTER_EXTRA_TRANSVERSE_DISPLAY",
  526. "A_PLUS_DISPLAY",
  527. "B_PLUS_DISPLAY",
  528. "LETTER_PLUS_DISPLAY",
  529. "A4_PLUS_DISPLAY",
  530. "A5_TRANSVERSE_DISPLAY",
  531. "B5_TRANSVERSE_DISPLAY",
  532. "A3_EXTRA_DISPLAY",
  533. "A5_EXTRA_DISPLAY",
  534. "B5_EXTRA_DISPLAY",
  535. "A2_DISPLAY",
  536. "A3_TRANSVERSE_DISPLAY",
  537. "A3_EXTRA_TRANSVERSE_DISPLAY",
  538. "DBL_JAPANESE_POSTCARD_DISPLAY",
  539. "A6_DISPLAY",
  540. "JENV_KAKU2_DISPLAY",
  541. "JENV_KAKU3_DISPLAY",
  542. "JENV_CHOU3_DISPLAY",
  543. "JENV_CHOU4_DISPLAY",
  544. "LETTER_ROTATED_DISPLAY",
  545. "A3_ROTATED_DISPLAY",
  546. "A4_ROTATED_DISPLAY",
  547. "A5_ROTATED_DISPLAY",
  548. "B4_JIS_ROTATED_DISPLAY",
  549. "B5_JIS_ROTATED_DISPLAY",
  550. "JAPANESE_POSTCARD_ROTATED_DISPLAY",
  551. "DBL_JAPANESE_POSTCARD_ROTATED_DISPLAY",
  552. "A6_ROTATED_DISPLAY",
  553. "JENV_KAKU2_ROTATED_DISPLAY",
  554. "JENV_KAKU3_ROTATED_DISPLAY",
  555. "JENV_CHOU3_ROTATED_DISPLAY",
  556. "JENV_CHOU4_ROTATED_DISPLAY",
  557. "B6_JIS_DISPLAY",
  558. "B6_JIS_ROTATED_DISPLAY",
  559. "12X11_DISPLAY",
  560. "JENV_YOU4_DISPLAY",
  561. "JENV_YOU4_ROTATED_DISPLAY",
  562. "P16K_DISPLAY",
  563. "P32K_DISPLAY",
  564. "P32KBIG_DISPLAY",
  565. "PENV_1_DISPLAY",
  566. "PENV_2_DISPLAY",
  567. "PENV_3_DISPLAY",
  568. "PENV_4_DISPLAY",
  569. "PENV_5_DISPLAY",
  570. "PENV_6_DISPLAY",
  571. "PENV_7_DISPLAY",
  572. "PENV_8_DISPLAY",
  573. "PENV_9_DISPLAY",
  574. "PENV_10_DISPLAY",
  575. "P16K_ROTATED_DISPLAY",
  576. "P32K_ROTATED_DISPLAY",
  577. "P32KBIG_ROTATED_DISPLAY",
  578. "PENV_1_ROTATED_DISPLAY",
  579. "PENV_2_ROTATED_DISPLAY",
  580. "PENV_3_ROTATED_DISPLAY",
  581. "PENV_4_ROTATED_DISPLAY",
  582. "PENV_5_ROTATED_DISPLAY",
  583. "PENV_6_ROTATED_DISPLAY",
  584. "PENV_7_ROTATED_DISPLAY",
  585. "PENV_8_ROTATED_DISPLAY",
  586. "PENV_9_ROTATED_DISPLAY",
  587. "PENV_10_ROTATED_DISPLAY",
  588. };
  589. PSTR gpstrStdPSDisplayName[DMPAPER_COUNT] = {
  590. "Letter",
  591. "Letter Small",
  592. "Tabloid",
  593. "Ledger",
  594. "Legal",
  595. "Statement",
  596. "Executive",
  597. "A3",
  598. "A4",
  599. "A4 Small",
  600. "A5",
  601. "B4 (JIS)",
  602. "B5 (JIS)",
  603. "Folio",
  604. "Quarto",
  605. "10x14",
  606. "11x17",
  607. "Note",
  608. "Envelope #9",
  609. "Envelope #10",
  610. "Envelope #11",
  611. "Envelope #12",
  612. "Envelope #14",
  613. "C size sheet",
  614. "D size sheet",
  615. "E size sheet",
  616. "Envelope DL",
  617. "Envelope C5",
  618. "Envelope C3",
  619. "Envelope C4",
  620. "Envelope C6",
  621. "Envelope C65",
  622. "Envelope B4",
  623. "Envelope B5",
  624. "Envelope B6",
  625. "Envelope",
  626. "Envelope Monarch",
  627. "6 3/4 Envelope",
  628. "US Std Fanfold",
  629. "German Std Fanfold",
  630. "German Legal Fanfold",
  631. "B4 (ISO)",
  632. "Japanese Postcard",
  633. "9x11",
  634. "10x11",
  635. "15x11",
  636. "Envelope Invite",
  637. "",
  638. "",
  639. "Letter Extra",
  640. "Legal Extra",
  641. "Tabloid Extra",
  642. "A4 Extra",
  643. "Letter Transverse",
  644. "A4 Transverse",
  645. "Letter Extra Transverse",
  646. "Super A",
  647. "Super B",
  648. "Letter Plus",
  649. "A4 Plus",
  650. "A5 Transverse",
  651. "B5 (JIS) Transverse",
  652. "A3 Extra",
  653. "A5 Extra",
  654. "B5 (ISO) Extra",
  655. "A2",
  656. "A3 Transverse",
  657. "A3 Extra Transverse",
  658. "Japanese Double Postcard",
  659. "A6",
  660. "Japanese Envelope Kaku #2",
  661. "Japanese Envelope Kaku #3",
  662. "Japanese Envelope Chou #3",
  663. "Japanese Envelope Chou #4",
  664. "Letter Rotated",
  665. "A3 Rotated",
  666. "A4 Rotated",
  667. "A5 Rotated",
  668. "B4 (JIS) Rotated",
  669. "B5 (JIS) Rotated",
  670. "Japanese Postcard Rotated",
  671. "Double Japanese Postcard Rotated",
  672. "A6 Rotated",
  673. "Japanese Envelope Kaku #2 Rotated",
  674. "Japanese Envelope Kaku #3 Rotated",
  675. "Japanese Envelope Chou #3 Rotated",
  676. "Japanese Envelope Chou #4 Rotated",
  677. "B6 (JIS)",
  678. "B6 (JIS) Rotated",
  679. "12x11",
  680. "Japanese Envelope You #4",
  681. "Japanese Envelope You #4 Rotated",
  682. "PRC 16K",
  683. "PRC 32K",
  684. "PRC 32K(Big)",
  685. "PRC Envelope #1",
  686. "PRC Envelope #2",
  687. "PRC Envelope #3",
  688. "PRC Envelope #4",
  689. "PRC Envelope #5",
  690. "PRC Envelope #6",
  691. "PRC Envelope #7",
  692. "PRC Envelope #8",
  693. "PRC Envelope #9",
  694. "PRC Envelope #10",
  695. "PRC 16K Rotated",
  696. "PRC 32K Rotated",
  697. "PRC 32K(Big) Rotated",
  698. "PRC Envelope #1 Rotated",
  699. "PRC Envelope #2 Rotated",
  700. "PRC Envelope #3 Rotated",
  701. "PRC Envelope #4 Rotated",
  702. "PRC Envelope #5 Rotated",
  703. "PRC Envelope #6 Rotated",
  704. "PRC Envelope #7 Rotated",
  705. "PRC Envelope #8 Rotated",
  706. "PRC Envelope #9 Rotated",
  707. "PRC Envelope #10 Rotated"
  708. };
  709. PSTR gpstrStdIBName[DMBIN_LAST] = {
  710. "UPPER",
  711. "LOWER",
  712. "MIDDLE",
  713. "MANUAL",
  714. "ENVFEED",
  715. "ENVMANUAL",
  716. "AUTO",
  717. "TRACTOR",
  718. "SMALLFMT",
  719. "LARGEFMT",
  720. "LARGECAPACITY",
  721. "", // non-contiguous id's
  722. "",
  723. "CASSETTE",
  724. ""
  725. };
  726. PSTR gpstrStdIBDisplayNameMacro[DMBIN_LAST] = {
  727. "UPPER_TRAY_DISPLAY",
  728. "LOWER_TRAY_DISPLAY",
  729. "MIDDLE_TRAY_DISPLAY",
  730. "MANUAL_FEED_DISPLAY",
  731. "ENV_FEED_DISPLAY",
  732. "ENV_MANUAL_DISPLAY",
  733. "AUTO_DISPLAY",
  734. "TRACTOR_DISPLAY",
  735. "SMALL_FORMAT_DISPLAY",
  736. "LARGE_FORMAT_DISPLAY",
  737. "LARGE_CAP_DISPLAY",
  738. "", // non-contiguous id's
  739. "",
  740. "CASSETTE_DISPLAY",
  741. ""
  742. };
  743. PSTR gpstrStdIBDisplayName[DMBIN_LAST] = {
  744. "Upper Paper tray", // DMBIN_FIRST
  745. "Lower Paper tray", // DMBIN_UPPER
  746. "Middle Paper tray", // DMBIN_LOWER
  747. "Manual Paper feed", // DMBIN_MANUAL
  748. "Envelope Feeder", // DMBIN_ENVELOPE
  749. "Envelope, Manual Feed", // DMBIN_ENVMANUAL
  750. "Auto", // DMBIN_AUTO
  751. "Tractor feed", // DMBIN_TRACTOR
  752. "Small Format", // DMBIN_SMALLFMT
  753. "Large Format", // DMBIN_LARGEFMT
  754. "Large Capacity" // DMBIN_LARGECAPACITY(11)
  755. "",
  756. "",
  757. "Cassette", // DMBIN_CASETTE(14)
  758. "Automatically Select" // DMBIN_FORMSOURCE(15)
  759. };
  760. PSTR gpstrStdMTName[DMMEDIA_LAST] = {
  761. "STANDARD",
  762. "TRANSPARENCY",
  763. "GLOSSY"
  764. };
  765. PSTR gpstrStdMTDisplayNameMacro[DMMEDIA_LAST] = {
  766. "PLAIN_PAPER_DISPLAY",
  767. "TRANSPARENCY_DISPLAY",
  768. "GLOSSY_PAPER_DISPLAY"
  769. };
  770. PSTR gpstrStdMTDisplayName[DMMEDIA_LAST] = {
  771. "Plain Paper",
  772. "Transparency",
  773. "Glossy Paper"
  774. };
  775. PSTR gpstrStdTQName[DMTEXT_LAST] = {
  776. "LETTER_QUALITY",
  777. "NEAR_LETTER_QUALITY",
  778. "MEMO_QUALITY",
  779. "DRAFT_QUALITY",
  780. "TEXT_QUALITY"
  781. };
  782. PSTR gpstrStdTQDisplayNameMacro[DMTEXT_LAST] = {
  783. "LETTER_QUALITY_DISPLAY",
  784. "NEAR_LETTER_QUALITY_DISPLAY",
  785. "MEMO_QUALITY_DISPLAY",
  786. "DRAFT_QUALITY_DISPLAY",
  787. "TEXT_QUALITY_DISPLAY"
  788. };
  789. PSTR gpstrStdTQDisplayName[DMTEXT_LAST] = {
  790. "Letter Quality",
  791. "Near Letter Quality",
  792. "Memo Quality",
  793. "Draft",
  794. "Text Quality"
  795. };
  796. PSTR gpstrPositionName[BAPOS_MAX] = {
  797. "NONE",
  798. "CENTER",
  799. "LEFT",
  800. "RIGHT"
  801. };
  802. PSTR gpstrFaceDirName[FD_MAX] = {
  803. "FACEUP",
  804. "FACEDOWN"
  805. };
  806. PSTR gpstrColorName[8] = {
  807. "NONE",
  808. "RED",
  809. "GREEN",
  810. "BLUE",
  811. "CYAN",
  812. "MAGENTA",
  813. "YELLOW",
  814. "BLACK"
  815. };
  816. WORD gwColorPlaneCmdID[4] = {
  817. CMD_DC_GC_PLANE1,
  818. CMD_DC_GC_PLANE2,
  819. CMD_DC_GC_PLANE3,
  820. CMD_DC_GC_PLANE4
  821. };
  822. PSTR gpstrColorPlaneCmdName[8] = {
  823. "NONE",
  824. "CmdSendRedData",
  825. "CmdSendGreenData",
  826. "CmdSendBlueData",
  827. "CmdSendCyanData",
  828. "CmdSendMagentaData",
  829. "CmdSendYellowData",
  830. "CmdSendBlackData"
  831. };
  832. PSTR gpstrSectionName[7] = {
  833. "", // SS_UNINITIALIZED
  834. "JOB_SETUP", // SS_JOBSETUP
  835. "DOC_SETUP", // SS_DOCSETUP
  836. "PAGE_SETUP", // SS_PAGESETUP
  837. "PAGE_FINISH", // SS_PAGEFINISH
  838. "DOC_FINISH", // SS_DOCFINISH
  839. "JOB_FINISH" // SS_JOBFINISH
  840. };
  841. void *
  842. GetTableInfo(
  843. IN PDH pdh, /* Base address of GPC data */
  844. IN int iResType, /* Resource type - HE_... values */
  845. IN int iIndex) /* Desired index for this entry */
  846. {
  847. int iLimit;
  848. //
  849. // Returns NULL if the requested data is out of range.
  850. //
  851. if (iResType >= pdh->sMaxHE)
  852. return NULL;
  853. iLimit = pdh->rghe[iResType].sCount;
  854. if (iLimit <= 0 || iIndex < 0 || iIndex >= iLimit )
  855. return NULL;
  856. return (PBYTE)pdh + pdh->rghe[iResType].sOffset +
  857. pdh->rghe[iResType].sLength * iIndex;
  858. }
  859. #if !defined(DEVSTUDIO) // MDS has its own version of this
  860. void _cdecl
  861. VOut(
  862. PCONVINFO pci,
  863. PSTR pstrFormat,
  864. ...)
  865. /*++
  866. Routine Description:
  867. This function formats a sequence of bytes and writes to the GPD file.
  868. Arguments:
  869. pci - conversionr related info
  870. pstrFormat - the formatting string
  871. ... - optional arguments needed by formatting
  872. Return Value:
  873. None
  874. --*/
  875. {
  876. va_list ap;
  877. DWORD dwNumBytesWritten;
  878. BYTE aubBuf[MAX_GPD_ENTRY_BUFFER_SIZE];
  879. int iSize;
  880. va_start(ap, pstrFormat);
  881. StringCchPrintfA((PSTR)aubBuf, CCHOF(aubBuf), pstrFormat, ap);
  882. va_end(ap);
  883. iSize = strlen(aubBuf);
  884. if (pci->dwMode & FM_VOUT_LIST)
  885. {
  886. //
  887. // check for the extra comma before the closing bracket
  888. //
  889. if (aubBuf[iSize-4] == ',' && aubBuf[iSize-3] == ')')
  890. {
  891. aubBuf[iSize-4] = aubBuf[iSize-3]; // ')'
  892. aubBuf[iSize-3] = aubBuf[iSize-2]; // '\r'
  893. aubBuf[iSize-2] = aubBuf[iSize-1]; // '\n'
  894. iSize--;
  895. }
  896. }
  897. if (!WriteFile(pci->hGPDFile, aubBuf, iSize, &dwNumBytesWritten, NULL) ||
  898. dwNumBytesWritten != (DWORD)iSize)
  899. pci->dwErrorCode |= ERR_WRITE_FILE;
  900. // continue even if an error has occurred.
  901. }
  902. #endif // defined(DEVSTUDIO)
  903. void
  904. EnterStringMode(
  905. OUT PBYTE pBuf,
  906. IN OUT PINT pIndex,
  907. IN OUT PWORD pwCMode)
  908. /*++
  909. Routine Description:
  910. This function enters the STRING mode and emits necessary characters to
  911. the output buffer.
  912. Arguments:
  913. pBuf: the output buffer
  914. pIndex: pBuf[*pIndex] is where the next character should be written.
  915. The index should be updated if any character is emitted.
  916. pwCMode: pointer to the current mode value. It's updated per request.
  917. Return Value:
  918. None
  919. --*/
  920. {
  921. if (!(*pwCMode & MODE_STRING))
  922. {
  923. pBuf[(*pIndex)++] = '"';
  924. *pwCMode |= MODE_STRING;
  925. }
  926. //
  927. // if we are also in HEX mode, exit HEX mode.
  928. //
  929. else if (*pwCMode & MODE_HEX)
  930. {
  931. pBuf[(*pIndex)++] = '>';
  932. *pwCMode &= ~MODE_HEX;
  933. }
  934. }
  935. void
  936. ExitStringMode(
  937. OUT PBYTE pBuf,
  938. IN OUT PINT pIndex,
  939. IN OUT PWORD pwCMode)
  940. /*++
  941. Routine Description:
  942. This function exits the STRING mode and emits necessary characters to
  943. the output buffer. Check to see if we need to exit HEX mode first.
  944. Arguments:
  945. pBuf: the output buffer
  946. pIndex: pBuf[*pIndex] is where the next character should be written.
  947. The index should be updated if any character is emitted.
  948. pwCMode: pointer to the current mode value. It's updated per request.
  949. Return Value:
  950. None
  951. --*/
  952. {
  953. if (*pwCMode & MODE_HEX)
  954. {
  955. pBuf[(*pIndex)++] = '>';
  956. *pwCMode &= ~MODE_HEX;
  957. }
  958. if (*pwCMode & MODE_STRING)
  959. {
  960. pBuf[(*pIndex)++] = '"';
  961. *pwCMode &= ~MODE_STRING;
  962. }
  963. }
  964. void
  965. EnterHexMode(
  966. OUT PBYTE pBuf,
  967. IN OUT PINT pIndex,
  968. IN OUT PWORD pwCMode)
  969. /*++
  970. Routine Description:
  971. This function enters the HEX mode and emits necessary characters to
  972. the output buffer.
  973. Arguments:
  974. pBuf: the output buffer
  975. pIndex: pBuf[*pIndex] is where the next character should be written.
  976. The index should be updated if any character is emitted.
  977. pwCMode: pointer to the current mode value. It's updated per request.
  978. Return Value:
  979. None
  980. --*/
  981. {
  982. //
  983. // if we are not in STRING mode, enter STRING mode first.
  984. //
  985. if (!(*pwCMode & MODE_STRING))
  986. {
  987. pBuf[(*pIndex)++] = '"';
  988. *pwCMode |= MODE_STRING;
  989. }
  990. if (!(*pwCMode & MODE_HEX))
  991. {
  992. pBuf[(*pIndex)++] = '<';
  993. *pwCMode |= MODE_HEX;
  994. }
  995. }
  996. BOOL
  997. BBuildCmdStr(
  998. IN OUT PCONVINFO pci,
  999. IN WORD wCmdID,
  1000. IN WORD ocd)
  1001. /*++
  1002. Routine Description:
  1003. This function builds the null-terminated GPD command string, including
  1004. double quotes, stadard variable references, parameter format, newlines
  1005. (except the ending newline), and continuation character "+" if
  1006. applicable. If the GPC command contains a callback id, fill the id in
  1007. pci->wCmdCallbackID. Otherwise, fill it with 0 and fill pci->wCmdLen with
  1008. the command length. If there is no command (NOOCD), fill both with 0.
  1009. This function handles the special case where CM_YM_RES_DEPENDENT bit
  1010. is set. In that case, the parameter expression needs to add
  1011. (ValueIn / ptTextScale.y) as the first thing before considering other
  1012. fields in EXTCD structure. All values passed in by Unidrv5 are in the
  1013. master units, no exception. For this case, pci->pcm is set to the model's
  1014. CURSORMOVE structure, and pci->pres is set to the current resolution
  1015. being considered.
  1016. This function handles the special case where RES_DM_GDI is not set (i.e.
  1017. V_BYTE style output) and wCmdID is CMD_RES_SENDBLOCK. In that case, we need
  1018. to add artifical divider equal to (pci->pres->sPinsPerPass / 8).
  1019. This is to match the hard-coded conversion from NumOfDataBytes to the number
  1020. of columns (in both Win95 Unidrv and NT4 RASDD).
  1021. This function handles the special case for compression commands --- it would
  1022. generate the "" command string (length == 2) even if it's NOOCD because the
  1023. driver relies on its existence to enable compression code.
  1024. Arguments:
  1025. pci: the conversion related info
  1026. wCmdID: GPC command id. It's unique for each command in GPC.
  1027. ocd: offset to the GPC CD structure on the GPC heap. The offset is
  1028. relative to the beginning of the heap (instead of beginning of
  1029. GPC data).
  1030. Return Value:
  1031. TRUE if there is a real command. Otherwise, return FALSE (i.e. NOOCD).
  1032. --*/
  1033. {
  1034. PCD pcd; // pointer to GPC's CD structure
  1035. PBYTE pBuf; // buffer to hold the composed GPD cmd
  1036. INT i = 0; // the next byte to write in the buffer
  1037. INT iPrevLines = 0; // the total # of bytes written for previous lines
  1038. pci->wCmdCallbackID = 0;
  1039. pBuf = pci->aubCmdBuf;
  1040. if (ocd != (WORD)NOOCD)
  1041. {
  1042. pcd = (PCD)((PBYTE)(pci->pdh) + (pci->pdh)->loHeap + ocd);
  1043. if (pcd->bCmdCbId > 0)
  1044. {
  1045. //
  1046. // Command callback case. For simplicity, we do not write out
  1047. // any parameters since each command takes different parameters.
  1048. // Instead, we give a warning and ask the minidriver developer
  1049. // to fill in *Param entry. After all, he may need different
  1050. // parameters than what GPC dictates.
  1051. //
  1052. pci->wCmdCallbackID = (WORD)pcd->bCmdCbId;
  1053. pci->dwErrorCode |= ERR_NO_CMD_CALLBACK_PARAMS;
  1054. }
  1055. else
  1056. {
  1057. WORD wCMode = 0; // bit flags indicating the conversion mode
  1058. WORD wFmtLen; // size of command string remaining
  1059. PSTR pFmt; // pointer into command string
  1060. PEXTCD pextcd; // points at next parameter's EXTCD
  1061. WORD wCount; // number of parameters
  1062. WORD wNextParam=0; // index of the next actual param
  1063. PDWORD pdwSVList;
  1064. pFmt = (PSTR)(pcd + 1);
  1065. wFmtLen = pcd->wLength;
  1066. pextcd = GETEXTCD(pci->pdh, pcd);
  1067. wCount = pcd->wCount;
  1068. pdwSVList = &(gdwSVLists[gawCmdtoSVOffset[wCmdID]]);
  1069. while (wFmtLen > 0)
  1070. {
  1071. if (*pFmt != CMD_MARKER)
  1072. {
  1073. if (IS_CHAR_READABLE(*pFmt))
  1074. {
  1075. EnterStringMode(pBuf, &i, &wCMode);
  1076. //
  1077. // check if it's the special character: ", <.
  1078. // If so, add the escape letter '%'
  1079. //
  1080. if (*pFmt == '"' || *pFmt == '<' )
  1081. pBuf[i++] = '%';
  1082. pBuf[i++] = *(pFmt++);
  1083. }
  1084. else // non-readable ASCII: write out hex strings.
  1085. {
  1086. EnterHexMode(pBuf, &i, &wCMode);
  1087. pBuf[i++] = gbHexChar[(*pFmt & 0xF0) >> 4];
  1088. pBuf[i++] = gbHexChar[*pFmt & 0x0F];
  1089. *(pFmt++);
  1090. }
  1091. wFmtLen --;
  1092. }
  1093. else if (wFmtLen > 1 && *(++pFmt) == CMD_MARKER)
  1094. {
  1095. //
  1096. // We have 2 '%' character to write out.
  1097. //
  1098. EnterStringMode(pBuf, &i, &wCMode);
  1099. pBuf[i++] = *pFmt;
  1100. pBuf[i++] = *(pFmt++);
  1101. wFmtLen -= 2;
  1102. }
  1103. else if (wFmtLen > 1) // we have a parameter format string
  1104. {
  1105. INT iParam; // index of the actual param used
  1106. DWORD dwSV; // GPD standard variable id
  1107. wFmtLen--; // to account for already eaten '%'
  1108. ExitStringMode(pBuf, &i, &wCMode);
  1109. //
  1110. // insert a white space before the param segment
  1111. //
  1112. pBuf[i++] = ' ';
  1113. pBuf[i++] = '%';
  1114. //
  1115. // first, the format string
  1116. //
  1117. while (wFmtLen > 0 && *pFmt >= '0' && *pFmt <= '9')
  1118. {
  1119. pBuf[i++] = *(pFmt++);
  1120. wFmtLen--;
  1121. }
  1122. if (wFmtLen > 0)
  1123. {
  1124. pBuf[i++] = *(pFmt++); // copy the format letter d,D,...
  1125. wFmtLen--;
  1126. }
  1127. else
  1128. {
  1129. pci->dwErrorCode |= ERR_BAD_GPC_CMD_STRING;
  1130. pBuf[i++] = '!';
  1131. pBuf[i++] = 'E';
  1132. pBuf[i++] = 'R';
  1133. pBuf[i++] = 'R';
  1134. pBuf[i++] = '!';
  1135. break; // exit the while (wFmtLen > 0) loop
  1136. }
  1137. //
  1138. // second, the limits if applicable.
  1139. //
  1140. // 12/19/97 zhanw
  1141. // Note: Win95 Unidrv uses !XCD_GEN_NO_MAX and
  1142. // pextcd->sMax if it's greater than 0 (for the cases of
  1143. // CMD_XM_LINESPACING and CMD_GEN_MAY_REPEAT), and it
  1144. // does NOT use pextcd->sMin at all. NT4 RASDD uses
  1145. // !XCD_GEN_NO_MIN and pextcd->sMin (any value, no
  1146. // particular purpose), and it uses pextcd->sMax without
  1147. // checking !XCD_GEN_NO_MAX (hacky way to handle
  1148. // max-repeat for CMD_RES_SENDBLOCK). Also, Unitool
  1149. // defaults pextcd->sMin to 0.
  1150. // Given that NT4 and Win95 share the same GPC source,
  1151. // the following code should suit both drivers' behavior.
  1152. //
  1153. //
  1154. if (pcd->wCount > 0)
  1155. {
  1156. //
  1157. // in this case, a valid EXTCD may specify limits
  1158. //
  1159. if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
  1160. pextcd->sMax > 0)
  1161. {
  1162. StringCchPrintfA((PSTR)&(pBuf[i]),
  1163. CCHOF(pci->aubCmdBuf) - i,
  1164. "[%d,%d]",
  1165. (pextcd->fGeneral & XCD_GEN_NO_MIN) ?
  1166. 0 : (WORD)pextcd->sMin,
  1167. (WORD)pextcd->sMax);
  1168. i += strlen(&(pBuf[i]));
  1169. }
  1170. }
  1171. // PatRyan - add limits for CmdCopies
  1172. if (wCmdID == CMD_PC_MULT_COPIES)
  1173. StringCchPrintfA((PSTR)&(pBuf[i]),
  1174. CCHOF(pci->aubCmdBuf) - i,
  1175. "[1,%d]",
  1176. pci->ppc->sMaxCopyCount);
  1177. i += strlen(&(pBuf[i]));
  1178. //
  1179. // third, the value.
  1180. //
  1181. if (pcd->wCount == 0)
  1182. {
  1183. //
  1184. // For this case, each format string wants
  1185. // the next parameter without modification
  1186. //
  1187. dwSV = pdwSVList[wNextParam++];
  1188. if (wCmdID == CMD_RES_SENDBLOCK &&
  1189. !(pci->pres->fDump & RES_DM_GDI) &&
  1190. dwSV == SV_NUMDATABYTES &&
  1191. pci->pres->sPinsPerPass != 8)
  1192. {
  1193. StringCchPrintfA((PSTR)&(pBuf[i]),
  1194. CCHOF(pci->aubCmdBuf) - i,
  1195. "{%s / %d}",
  1196. gpstrSVNames[dwSV],
  1197. pci->pres->sPinsPerPass / 8);
  1198. i += strlen(&(pBuf[i]));
  1199. }
  1200. else
  1201. {
  1202. StringCchPrintfA((PSTR)&(pBuf[i]),
  1203. CCHOF(pci->aubCmdBuf) - i,
  1204. "{%s}",
  1205. gpstrSVNames[dwSV]);
  1206. i += strlen(&(pBuf[i]));
  1207. }
  1208. }
  1209. else
  1210. {
  1211. short sSBDDiv = 1; // special case for CmdSendBlockData
  1212. if (pci->pdh->wVersion < GPC_VERSION3)
  1213. // For this case, each EXTCD wants the next parameter
  1214. iParam = wNextParam++;
  1215. else
  1216. // For this case, each EXTCD specifies the parameter
  1217. iParam = pextcd->wParam;
  1218. dwSV = pdwSVList[iParam];
  1219. if (wCmdID == CMD_RES_SENDBLOCK &&
  1220. !(pci->pres->fDump & RES_DM_GDI) &&
  1221. dwSV == SV_NUMDATABYTES)
  1222. {
  1223. //
  1224. // sPinsPerPass is always a multiplier of 8.
  1225. //
  1226. sSBDDiv = pci->pres->sPinsPerPass / 8;
  1227. }
  1228. pBuf[i++] = '{';
  1229. //
  1230. // check if max_repeat is needed.
  1231. // Special case for CMD_CM_YM_LINESPACING: never use
  1232. // "max_repeat" by definition.
  1233. //
  1234. if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
  1235. pextcd->sMax > 0 &&
  1236. (pcd->fGeneral & CMD_GEN_MAY_REPEAT) &&
  1237. wCmdID != CMD_CM_YM_LINESPACING)
  1238. {
  1239. StringCchPrintfA((PSTR)&(pBuf[i]),
  1240. CCHOF(pci->aubCmdBuf) - i,
  1241. "max_repeat(");
  1242. i += strlen(&(pBuf[i]));
  1243. }
  1244. //
  1245. // compose the expression.
  1246. // Optimize for special cases.
  1247. //
  1248. if (pextcd->sPreAdd != 0)
  1249. pBuf[i++] = '(';
  1250. if (pextcd->sUnitMult > 1)
  1251. pBuf[i++] = '(';
  1252. if (pextcd->sUnitDiv > 1 || sSBDDiv > 1)
  1253. pBuf[i++] = '(';
  1254. StringCchPrintfA((PSTR)&(pBuf[i]),
  1255. CCHOF(pci->aubCmdBuf) - i,
  1256. "%s ", gpstrSVNames[dwSV]);
  1257. i += strlen(&(pBuf[i]));
  1258. //
  1259. // special check for CM_YM_RES_DEPENDENT flag
  1260. //
  1261. if ((wCmdID == CMD_CM_YM_ABS ||
  1262. wCmdID == CMD_CM_YM_REL ||
  1263. wCmdID == CMD_CM_YM_RELUP ||
  1264. wCmdID == CMD_CM_YM_LINESPACING) &&
  1265. (pci->pcm->fYMove & CM_YM_RES_DEPENDENT) &&
  1266. pci->pres->ptTextScale.y != 1)
  1267. {
  1268. StringCchPrintfA((PSTR)&(pBuf[i]),
  1269. CCHOF(pci->aubCmdBuf) - i,
  1270. "/ %d ",
  1271. pci->pres->ptTextScale.y);
  1272. i += strlen(&(pBuf[i]));
  1273. }
  1274. //
  1275. // continue with normal processing
  1276. //
  1277. if (pextcd->sPreAdd > 0)
  1278. {
  1279. StringCchPrintfA((PSTR)&(pBuf[i]),
  1280. CCHOF(pci->aubCmdBuf) - i,
  1281. "+ %d) ",
  1282. pextcd->sPreAdd);
  1283. i += strlen(&(pBuf[i]));
  1284. }
  1285. else if (pextcd->sPreAdd < 0)
  1286. {
  1287. StringCchPrintfA((PSTR)&(pBuf[i]),
  1288. CCHOF(pci->aubCmdBuf) - i,
  1289. "- %d) ",
  1290. -pextcd->sPreAdd);
  1291. i += strlen(&(pBuf[i]));
  1292. }
  1293. if (pextcd->sUnitMult > 1)
  1294. {
  1295. i += StringCchPrintfA((PSTR)&(pBuf[i]),
  1296. CCHOF(pci->aubCmdBuf) - i,
  1297. "* %d) ",
  1298. pextcd->sUnitMult);
  1299. i += strlen(&(pBuf[i]));
  1300. }
  1301. if (pextcd->sUnitDiv > 1 || sSBDDiv > 1)
  1302. {
  1303. i += StringCchPrintfA((PSTR)&(pBuf[i]),
  1304. CCHOF(pci->aubCmdBuf) - i,
  1305. ((pextcd->fGeneral & XCD_GEN_MODULO) ?
  1306. "MOD %d) " : "/ %d) "),
  1307. ((pextcd->sUnitDiv) ? pextcd->sUnitDiv : 1) * sSBDDiv);
  1308. i += strlen(&(pBuf[i]));
  1309. }
  1310. if (pextcd->sUnitAdd > 0)
  1311. {
  1312. i += StringCchPrintfA((PSTR)&(pBuf[i]),
  1313. CCHOF(pci->aubCmdBuf) - i,
  1314. "+ %d",
  1315. pextcd->sUnitAdd);
  1316. i += strlen(&(pBuf[i]));
  1317. }
  1318. else if (pextcd->sUnitAdd < 0)
  1319. {
  1320. i += StringCchPrintfA((PSTR)&(pBuf[i]),
  1321. CCHOF(pci->aubCmdBuf) - i,
  1322. "- %d",
  1323. pextcd->sUnitAdd);
  1324. i += strlen(&(pBuf[i]));
  1325. }
  1326. //
  1327. // check if need to close max_repeat
  1328. //
  1329. if (!(pextcd->fGeneral & XCD_GEN_NO_MAX) &&
  1330. pextcd->sMax > 0 &&
  1331. (pcd->fGeneral & CMD_GEN_MAY_REPEAT) &&
  1332. wCmdID != CMD_CM_YM_LINESPACING)
  1333. pBuf[i++] = ')';
  1334. pBuf[i++] = '}'; // close the value portion
  1335. }
  1336. pextcd++; // advance to next EXTCD
  1337. } // end param case
  1338. else
  1339. {
  1340. pci->dwErrorCode |= ERR_BAD_GPC_CMD_STRING;
  1341. pBuf[i++] = '!';
  1342. pBuf[i++] = 'E';
  1343. pBuf[i++] = 'R';
  1344. pBuf[i++] = 'R';
  1345. pBuf[i++] = '!';
  1346. break; // exit the while (wFmtLen > 0) loop
  1347. }
  1348. //
  1349. // check if the string is already quite long. If so,
  1350. // start a new line.
  1351. //
  1352. if ((i - iPrevLines) >= MAX_GPD_CMD_LINE_LENGTH)
  1353. {
  1354. ExitStringMode(pBuf, &i, &wCMode);
  1355. pBuf[i++] = '\r';
  1356. pBuf[i++] = '\n';
  1357. iPrevLines = i;
  1358. pBuf[i++] = '+';
  1359. pBuf[i++] = ' ';
  1360. }
  1361. } // while (wFmtLen > 0)
  1362. //
  1363. // finished processing the format string. Exit properly
  1364. //
  1365. ExitStringMode(pBuf, &i, &wCMode);
  1366. }
  1367. } // !NOOCD case
  1368. else if (wCmdID == CMD_CMP_TIFF || wCmdID == CMD_CMP_DELTAROW ||
  1369. wCmdID == CMD_CMP_FE_RLE)
  1370. {
  1371. pBuf[i++] = '"'; // generate "" command string
  1372. pBuf[i++] = '"';
  1373. }
  1374. pBuf[i] = 0;
  1375. pci->wCmdLen = (WORD)i;
  1376. return (i != 0 || pci->wCmdCallbackID != 0);
  1377. }
  1378. void
  1379. VOutputOrderedCmd(
  1380. IN OUT PCONVINFO pci,// contain info about the cmd to output
  1381. PSTR pstrCmdName, // cmd name such as "CmdSelect"
  1382. SEQSECTION ss, // sequence section id (ENUM type defined in GPD.H)
  1383. WORD wOrder, // order number within the section
  1384. BOOL bIndent) // whether to use 2-level indentation or not
  1385. {
  1386. //
  1387. // check for no-cmd case
  1388. //
  1389. if (wOrder > 0 && (pci->wCmdLen > 0 || pci->wCmdCallbackID > 0))
  1390. {
  1391. VOut(pci, "%s*Command: %s\r\n%s{\r\n",
  1392. bIndent? " " : "",
  1393. pstrCmdName,
  1394. bIndent? " " : "");
  1395. VOut(pci, "%s*Order: %s.%d\r\n",
  1396. bIndent? " " : " ",
  1397. gpstrSectionName[ss],
  1398. wOrder);
  1399. if (pci->wCmdCallbackID > 0)
  1400. {
  1401. VOut(pci, "%s*CallbackID: %d\r\n",
  1402. bIndent? " " : " ",
  1403. pci->wCmdCallbackID);
  1404. VOut(pci, "*%% Error: you must check if this command callback requires any parameters!\r\n");
  1405. }
  1406. else
  1407. VOut(pci, "%s*Cmd: %s\r\n",
  1408. bIndent? " " : " ",
  1409. pci->aubCmdBuf);
  1410. VOut(pci, "%s}\r\n", bIndent? " " : "");
  1411. }
  1412. }
  1413. void
  1414. VOutputSelectionCmd(
  1415. IN OUT PCONVINFO pci,// contain info about the cmd to output
  1416. IN BOOL bDocSetup, // whether in DOC_SETUP or PAGE_SETUP section
  1417. IN WORD wOrder) // order number within the section
  1418. //
  1419. // This function outputs an option selection command which uses level 2
  1420. // indentation.
  1421. //
  1422. {
  1423. VOutputOrderedCmd(pci, "CmdSelect",
  1424. bDocSetup? SS_DOCSETUP : SS_PAGESETUP,
  1425. wOrder, TRUE);
  1426. }
  1427. void
  1428. VOutputConfigCmd(
  1429. IN OUT PCONVINFO pci,// contain info about the cmd to output
  1430. IN PSTR pstrCmdName, // command name
  1431. IN SEQSECTION ss, // sequence section id
  1432. IN WORD wOrder) // order number within the section
  1433. //
  1434. // This function outputs a printer configuration command at the root level.
  1435. //
  1436. {
  1437. VOutputOrderedCmd(pci, pstrCmdName, ss, wOrder, FALSE);
  1438. }
  1439. void
  1440. VOutputCmdBase(
  1441. IN OUT PCONVINFO pci, // contain info about the cmd to output
  1442. PSTR pstrCmdName, // cmd name such as "CmdXMoveAbsolute"
  1443. BOOL bExtern, // whether to add EXTERN_GLOBAL prefix
  1444. BOOL bIndent) // whter to use level 2 indentation
  1445. {
  1446. if (pci->wCmdLen > 0)
  1447. VOut(pci, "%s%s*Command: %s { *Cmd : %s }\r\n",
  1448. bIndent? " " : "",
  1449. bExtern ? "EXTERN_GLOBAL: " : "",
  1450. pstrCmdName, pci->aubCmdBuf);
  1451. else if (pci->wCmdCallbackID > 0)
  1452. VOut(pci, "%s%s*Command: %s { *CallbackID: %d }\r\n",
  1453. bIndent? " " : "",
  1454. bExtern ? "EXTERN_GLOBAL: " : "",
  1455. pstrCmdName,
  1456. pci->wCmdCallbackID);
  1457. }
  1458. void
  1459. VOutputCmd(
  1460. IN OUT PCONVINFO pci, // contain info about the cmd to output
  1461. IN PSTR pstrCmdName)
  1462. //
  1463. // This function outputs printing commands at the root level (i.e. no
  1464. // indentation). It uses the shortcut format: *Command: <name> : <cmd>
  1465. // unless the callback is used.
  1466. //
  1467. {
  1468. VOutputCmdBase(pci, pstrCmdName, FALSE, FALSE);
  1469. }
  1470. void
  1471. VOutputExternCmd(
  1472. IN OUT PCONVINFO pci,
  1473. IN PSTR pstrCmdName)
  1474. //
  1475. // This function outputs the printing commands inside feature option
  1476. // construct, i.e. they should be prefixed with "EXTERN_GLOBAL" and use
  1477. // level 2 indentation.
  1478. //
  1479. {
  1480. //
  1481. // 1/7/97 ZhanW
  1482. // According to PeterWo, constructs don't need EXTERN_GLOBAL prefix
  1483. //
  1484. VOutputCmdBase(pci, pstrCmdName, FALSE, TRUE);
  1485. }
  1486. void
  1487. VOutputCmd2(
  1488. IN OUT PCONVINFO pci,
  1489. IN PSTR pstrCmdName)
  1490. //
  1491. // This function outputs printing commands with one level dependency,
  1492. // i.e. they should use level 2 indentation.
  1493. //
  1494. {
  1495. VOutputCmdBase(pci, pstrCmdName, FALSE, TRUE);
  1496. }
  1497. WORD gwDefaultCmdOrder[] = {
  1498. PC_ORD_PAPER_SOURCE,
  1499. PC_ORD_PAPER_DEST,
  1500. PC_ORD_PAPER_SIZE,
  1501. PC_ORD_RESOLUTION,
  1502. PC_ORD_TEXTQUALITY,
  1503. 0,
  1504. };
  1505. BOOL
  1506. BInDocSetup(
  1507. IN PCONVINFO pci,
  1508. IN WORD ord,
  1509. OUT PWORD pwOrder)
  1510. /*++
  1511. Routine Description:
  1512. This function determines the section and the order number of the given
  1513. command.
  1514. Arguments:
  1515. pci: pointer to CONVINFO
  1516. ord: PC_ORD_xxx id identifying the command.
  1517. pwOrder: to store the order number as in GPC
  1518. Return:
  1519. TRUE if the command should be in DOC_SETUP section.
  1520. Note that for both NT RASDD and Win95 Unidrv:
  1521. 1. All commands before PC_ORD_BEGINPAGE (exclusive) are sent per
  1522. job and per ResetDC. So they should be in DOC_SETUP section.
  1523. 2. All commands after PC_ORD_BEGINPAGE (inclusive) is sent at the
  1524. beginning of each page. So they should be in PAGE_SETUP section.
  1525. --*/
  1526. {
  1527. PWORD pOrds;
  1528. BOOL bDocSetup = TRUE;
  1529. WORD count;
  1530. if (pci->ppc->orgwOrder == (WORD)NOT_USED)
  1531. pOrds = gwDefaultCmdOrder;
  1532. else
  1533. pOrds = (PWORD)((PBYTE)pci->pdh + pci->pdh->loHeap +
  1534. pci->ppc->orgwOrder);
  1535. for (count = 1; *pOrds != 0 && *pOrds != ord; count++, pOrds++)
  1536. {
  1537. if (bDocSetup && *pOrds == PC_ORD_BEGINPAGE)
  1538. bDocSetup = FALSE;
  1539. }
  1540. if (*pOrds == 0)
  1541. *pwOrder = 0; // didn't find the cmd in the sequence
  1542. else // *pOrds == ord
  1543. {
  1544. *pwOrder = count;
  1545. if (ord == PC_ORD_BEGINPAGE)
  1546. bDocSetup = FALSE;
  1547. }
  1548. return bDocSetup;
  1549. }