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.

2315 lines
65 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. raster.c
  5. Abstract:
  6. Implementation of the interface between Control module and Raster module
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 12/15/96 -alvins-
  11. Created
  12. --*/
  13. #include "raster.h"
  14. #include "rastproc.h"
  15. #include "rmrender.h"
  16. #include "unirc.h"
  17. #include "xlraster.h"
  18. // internal function declarations
  19. void vSetHTData(PDEV *, GDIINFO *);
  20. BOOL bInitColorOrder(PDEV *);
  21. DWORD PickDefaultHTPatSize(DWORD,DWORD);
  22. VOID v8BPPLoadPal(PDEV *);
  23. BOOL bEnoughDRCMemory(PDEV *);
  24. #ifdef TIMING
  25. #include <stdio.h>
  26. void DrvDbgPrint(
  27. char *,
  28. ...);
  29. #endif
  30. // parameter definitions
  31. static RMPROCS RasterProcs =
  32. {
  33. RMStartDoc,
  34. RMStartPage,
  35. RMSendPage,
  36. RMEndDoc,
  37. RMNextBand,
  38. RMStartBanding,
  39. RMResetPDEV,
  40. RMEnableSurface,
  41. RMDisableSurface,
  42. RMDisablePDEV,
  43. RMCopyBits,
  44. RMBitBlt,
  45. RMStretchBlt,
  46. RMDitherColor,
  47. RMStretchBltROP,
  48. RMPaint,
  49. RMPlgBlt
  50. };
  51. CONST BYTE cxcyHTPatSize[HT_PATSIZE_MAX_INDEX+1] = {
  52. 2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16
  53. #ifndef WINNT_40
  54. ,84,91
  55. #endif
  56. };
  57. #define VALID_YC 0xFFFE
  58. #define GAMMA_LINEAR 10000
  59. #define GAMMA_DEVICE_HT 8000
  60. #define GAMMA_SUPERCELL GAMMA_LINEAR
  61. #define GAMMA_DITHER 9250
  62. #define GAMMA_GEN_PROFILE 0xFFFF
  63. CONST COLORINFO DefColorInfoLinear =
  64. {
  65. { 6400, 3300, 0 }, // xr, yr, Yr
  66. { 3000, 6000, 0 }, // xg, yg, Yg
  67. { 1500, 600, 0 }, // xb, yb, Yb
  68. { 0, 0,VALID_YC }, // xc, yc, Yc Y=0=HT default
  69. { 0, 0, 0 }, // xm, ym, Ym
  70. { 0, 0, 0 }, // xy, yy, Yy
  71. { 3127, 3290, 10000 }, // xw, yw, Yw
  72. 10000, // R gamma
  73. 10000, // G gamma
  74. 10000, // B gamma
  75. 712, 121, // M/C, Y/C
  76. 86, 468, // C/M, Y/M
  77. 21, 35 // C/Y, M/Y
  78. };
  79. //*******************************************************
  80. BOOL
  81. RMInit (
  82. PDEV *pPDev,
  83. DEVINFO *pDevInfo,
  84. GDIINFO *pGDIInfo
  85. )
  86. /*++
  87. Routine Description:
  88. This function is called to initialize raster related information in
  89. pPDev, pDevInfo and pGDIInfo
  90. Arguments:
  91. pPDev Pointer to PDEV structure
  92. pDevInfo Pointer to DEVINFO structure
  93. pGDIInfo Pointer to GDIINFO structure
  94. Return Value:
  95. TRUE for success and FALSE for failure
  96. --*/
  97. {
  98. BOOL bRet = FALSE;
  99. PRASTERPDEV pRPDev;
  100. // Validate Input Parameters and ASSERT.
  101. ASSERT(pPDev);
  102. ASSERT(pDevInfo);
  103. ASSERT(pGDIInfo);
  104. // initialize the hook flag
  105. pPDev->fHooks |= HOOK_BITBLT | HOOK_STRETCHBLT | HOOK_COPYBITS;
  106. // initialize Proc jump table
  107. pPDev->pRasterProcs = &RasterProcs;
  108. // initialize Raster Pdev
  109. if (!bInitRasterPDev(pPDev))
  110. return FALSE;
  111. pRPDev = (PRASTERPDEV)pPDev->pRasterPDEV;
  112. //
  113. // Set up the default HALFTONE and colour calibration data.
  114. //
  115. vSetHTData( pPDev, pGDIInfo );
  116. //
  117. // initialize graphic capabilities
  118. //
  119. pDevInfo->flGraphicsCaps |= (GCAPS_ARBRUSHOPAQUE | GCAPS_HALFTONE | GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER);
  120. // initialize DevInfo parameters for rendering
  121. // test whether standard dither or custom pattern
  122. #ifndef WINNT_40
  123. if (pGDIInfo->ulHTPatternSize == HT_PATSIZE_USER) {
  124. pDevInfo->cxDither = (USHORT)pPDev->pHalftone->HalftonePatternSize.x;
  125. pDevInfo->cyDither = (USHORT)pPDev->pHalftone->HalftonePatternSize.y;
  126. }
  127. else
  128. #endif
  129. {
  130. pDevInfo->cxDither =
  131. pDevInfo->cyDither = cxcyHTPatSize[pGDIInfo->ulHTPatternSize];
  132. }
  133. pPDev->dwHTPatSize = pDevInfo->cyDither;
  134. // if no quality macro setting, overwrite with halftone type
  135. //
  136. if ((pPDev->pdmPrivate->dwFlags & DXF_CUSTOM_QUALITY) ||
  137. (pPDev->pdmPrivate->iQuality != QS_BEST &&
  138. pPDev->pdmPrivate->iQuality != QS_BETTER &&
  139. pPDev->pdmPrivate->iQuality != QS_DRAFT))
  140. pPDev->pdm->dmDitherType = pGDIInfo->ulHTPatternSize;
  141. return TRUE;
  142. }
  143. //*******************************************************
  144. BOOL
  145. bInitRasterPDev(
  146. PDEV *pPDev
  147. )
  148. /*++
  149. Routine Description:
  150. This routine allocates the RASTERPDEV and initializes various fields.
  151. Arguments:
  152. pPDev - Pointer to PDEV.
  153. Return Value:
  154. TRUE - for success
  155. FALSE - for failure
  156. --*/
  157. {
  158. PRASTERPDEV pRPDev;
  159. GLOBALS *pGlobals = pPDev->pGlobals;
  160. PLISTNODE pListNode;
  161. if ( !(pRPDev = MemAllocZ(sizeof(RASTERPDEV))) )
  162. {
  163. ERR(("Unidrv!RMInit: Can't Allocate RASTERPDEV\n"));
  164. return FALSE;
  165. }
  166. pPDev->pRasterPDEV = pRPDev;
  167. // map all callback functions
  168. //
  169. if (pPDev->pOemHookInfo)
  170. {
  171. pRPDev->pfnOEMCompression =
  172. (PFN_OEMCompression)pPDev->pOemHookInfo[EP_OEMCompression].pfnHook;
  173. pRPDev->pfnOEMHalftonePattern =
  174. (PFN_OEMHalftonePattern)pPDev->pOemHookInfo[EP_OEMHalftonePattern].pfnHook;
  175. if (pPDev->pColorModeEx && pPDev->pColorModeEx->dwIPCallbackID > 0)
  176. {
  177. pRPDev->pfnOEMImageProcessing = (PFN_OEMImageProcessing)
  178. pPDev->pOemHookInfo[EP_OEMImageProcessing].pfnHook;
  179. }
  180. pRPDev->pfnOEMFilterGraphics =
  181. (PFN_OEMFilterGraphics)pPDev->pOemHookInfo[EP_OEMFilterGraphics].pfnHook;
  182. }
  183. // Determine the pixel depth, # planes and color order
  184. //
  185. if (!(bInitColorOrder(pPDev)))
  186. {
  187. ERR(("Invalid Color Order"));
  188. pPDev->pRasterPDEV = NULL;
  189. MemFree(pRPDev);
  190. return FALSE;
  191. }
  192. //* Determine whether to set DC_EXPLICIT_COLOR flag
  193. if (pGlobals->bUseCmdSendBlockDataForColor)
  194. pRPDev->fColorFormat |= DC_EXPLICIT_COLOR;
  195. //* Determine DC_CF_SEND_CR flag
  196. if (pGlobals->bMoveToX0BeforeColor)
  197. pRPDev->fColorFormat |= DC_CF_SEND_CR;
  198. //* Determine DC_SEND_ALL_PLANES flag
  199. if (pGlobals->bRasterSendAllData)
  200. pRPDev->fColorFormat |= DC_SEND_ALL_PLANES;
  201. /*TBD: if there is a filter callback, set BLOCK_IS_BAND
  202. //
  203. if (I've got a filter callback?)
  204. pRPDev->fRMode |= PFR_BLOCK_IS_BAND;
  205. */
  206. // Initialize whether there are SRCBMPWIDTH / SRCBMPHEIGHT commands
  207. if (COMMANDPTR(pPDev->pDriverInfo,CMD_SETSRCBMPWIDTH))
  208. pRPDev->fRMode |= PFR_SENDSRCWIDTH;
  209. if (COMMANDPTR(pPDev->pDriverInfo,CMD_SETSRCBMPHEIGHT))
  210. pRPDev->fRMode |= PFR_SENDSRCHEIGHT;
  211. // Initialize whether there is a BEGINRASTER command
  212. if (COMMANDPTR(pPDev->pDriverInfo,CMD_BEGINRASTER))
  213. pRPDev->fRMode |= PFR_SENDBEGINRASTER;
  214. // Initialize rules testing
  215. // If Rectangle width and height commands exist assume we have black or
  216. // gray rectangles unless only white rect command exist. This is because
  217. // some devices have no explicit rectangle commands while others only have
  218. // white rectangles.
  219. //
  220. if (pPDev->fMode & PF_RECT_FILL)
  221. {
  222. pRPDev->fRMode |= PFR_RECT_FILL | PFR_RECT_HORIZFILL;
  223. if (COMMANDPTR(pPDev->pDriverInfo,CMD_RECTBLACKFILL))
  224. pRPDev->dwRectFillCommand = CMD_RECTBLACKFILL;
  225. else if (COMMANDPTR(pPDev->pDriverInfo,CMD_RECTGRAYFILL))
  226. pRPDev->dwRectFillCommand = CMD_RECTGRAYFILL;
  227. else if (COMMANDPTR(pPDev->pDriverInfo,CMD_RECTWHITEFILL))
  228. pRPDev->fRMode &= ~(PFR_RECT_FILL | PFR_RECT_HORIZFILL);
  229. }
  230. // Initialize whether to send ENDBLOCK commands
  231. if (COMMANDPTR(pPDev->pDriverInfo,CMD_ENDBLOCKDATA))
  232. pRPDev->fRMode |= PFR_ENDBLOCK;
  233. //* Initialize resolution fields
  234. //
  235. pRPDev->sMinBlankSkip = (short)pPDev->pResolutionEx->dwMinStripBlankPixels;
  236. pRPDev->sNPins = (WORD)pPDev->pResolutionEx->dwPinsPerLogPass;
  237. pRPDev->sPinsPerPass = (WORD)pPDev->pResolutionEx->dwPinsPerPhysPass;
  238. //* initialize fDump flags
  239. //
  240. if (pGlobals->bOptimizeLeftBound)
  241. pRPDev->fDump |= RES_DM_LEFT_BOUND;
  242. if (pGlobals->outputdataformat == ODF_H_BYTE)
  243. pRPDev->fDump |= RES_DM_GDI;
  244. //* initialize fBlockOut flags
  245. //
  246. //* first map the GPD blanks parameters to GPC
  247. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pPDev->pGlobals->liStripBlanks);
  248. while (pListNode)
  249. {
  250. if (pListNode->dwData == SB_LEADING)
  251. pRPDev->fBlockOut |= RES_BO_LEADING_BLNKS;
  252. else if (pListNode->dwData == SB_ENCLOSED)
  253. pRPDev->fBlockOut |= RES_BO_ENCLOSED_BLNKS;
  254. else if (pListNode->dwData == SB_TRAILING)
  255. pRPDev->fBlockOut |= RES_BO_TRAILING_BLNKS;
  256. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pListNode->dwNextItem);
  257. }
  258. // Do we need to set to uni directional printing?
  259. //
  260. if (pPDev->pResolutionEx->bRequireUniDir)
  261. pRPDev->fBlockOut |= RES_BO_UNIDIR;
  262. // Can we output multiple rows at a time?
  263. //
  264. if (pPDev->pGlobals->bSendMultipleRows)
  265. pRPDev->fBlockOut |= RES_BO_MULTIPLE_ROWS;
  266. // Set flag if we need to mirror the individual raster bytes
  267. //
  268. if (pPDev->pGlobals->bMirrorRasterByte)
  269. pRPDev->fBlockOut |= RES_BO_MIRROR;
  270. // initialize fCursor flags
  271. //
  272. pRPDev->fCursor = 0;
  273. if (pGlobals->cyafterblock == CYSBD_AUTO_INCREMENT)
  274. pRPDev->fCursor |= RES_CUR_Y_POS_AUTO;
  275. if (pGlobals->cxafterblock == CXSBD_AT_GRXDATA_ORIGIN)
  276. pRPDev->fCursor |= RES_CUR_X_POS_ORG;
  277. else if (pGlobals->cxafterblock == CXSBD_AT_CURSOR_X_ORIGIN)
  278. pRPDev->fCursor |= RES_CUR_X_POS_AT_0;
  279. //
  280. // check for compression modes
  281. //
  282. if (!pRPDev->pfnOEMFilterGraphics)
  283. {
  284. if (COMMANDPTR(pPDev->pDriverInfo,CMD_ENABLETIFF4))
  285. {
  286. pRPDev->fRMode |= PFR_COMP_TIFF;
  287. }
  288. if (COMMANDPTR(pPDev->pDriverInfo,CMD_ENABLEFERLE))
  289. {
  290. pRPDev->fRMode |= PFR_COMP_FERLE;
  291. }
  292. if (COMMANDPTR(pPDev->pDriverInfo,CMD_ENABLEDRC) &&
  293. !pPDev->pGlobals->bSendMultipleRows &&
  294. pRPDev->sDevPlanes == 1 && bEnoughDRCMemory(pPDev))
  295. {
  296. // For DRC we disable moving the left boundary
  297. //
  298. pRPDev->fBlockOut &= ~RES_BO_LEADING_BLNKS;
  299. pRPDev->fDump &= ~RES_DM_LEFT_BOUND;
  300. //
  301. // If there is a source width command we also disable
  302. // TRAILING blanks
  303. //
  304. if (pRPDev->fRMode & PFR_SENDSRCWIDTH)
  305. pRPDev->fBlockOut &= ~RES_BO_TRAILING_BLNKS;
  306. //
  307. // For DRC we disable all rules
  308. pRPDev->fRMode &= ~PFR_RECT_FILL;
  309. pRPDev->fRMode |= PFR_COMP_DRC;
  310. }
  311. if (COMMANDPTR(pPDev->pDriverInfo,CMD_ENABLEOEMCOMP))
  312. {
  313. if (pRPDev->pfnOEMCompression)
  314. pRPDev->fRMode |= PFR_COMP_OEM;
  315. }
  316. // for these compression modes it is more efficient to
  317. // disable horizontal rules code and enclosed blanks
  318. //
  319. if (pRPDev->fRMode & (PFR_COMP_TIFF | PFR_COMP_DRC | PFR_COMP_FERLE))
  320. {
  321. pRPDev->fRMode &= ~PFR_RECT_HORIZFILL;
  322. pRPDev->fBlockOut &= ~RES_BO_ENCLOSED_BLNKS;
  323. }
  324. }
  325. return TRUE;
  326. }
  327. //**************************************************************
  328. BOOL
  329. bInitColorOrder(
  330. PDEV *pPDev
  331. )
  332. /*++
  333. Routine Description:
  334. This routine initializes the order to print the color planes
  335. for those devices that specify multiple plane output. It also
  336. maps the appropriate color command for each color.
  337. Arguments:
  338. pPDev - Pointer to PDEV.
  339. Return Value:
  340. TRUE - for success
  341. FALSE - for failure
  342. --*/
  343. {
  344. PCOLORMODEEX pColorModeEx;
  345. PLISTNODE pListNode;
  346. DWORD dwIndex;
  347. DWORD dwColorCmd;
  348. BYTE ColorIndex;
  349. INT dwPlanes = 0;
  350. INT iDevNumPlanes;
  351. PRASTERPDEV pRPDev = (PRASTERPDEV)pPDev->pRasterPDEV;
  352. // check if structure exists
  353. if (pPDev->pColorModeEx)
  354. {
  355. short sDrvBPP;
  356. sDrvBPP = (short)pPDev->pColorModeEx->dwDrvBPP;
  357. pRPDev->sDevBPP = (short)pPDev->pColorModeEx->dwPrinterBPP;
  358. pRPDev->sDevPlanes = (short)pPDev->pColorModeEx->dwPrinterNumOfPlanes;
  359. pRPDev->dwIPCallbackID = pPDev->pColorModeEx->dwIPCallbackID;
  360. //
  361. // calculate equivalent output pixel depth and
  362. // test for valid formats
  363. //
  364. if (pRPDev->sDevPlanes == 1)
  365. {
  366. if (pRPDev->sDevBPP != 1 &&
  367. pRPDev->sDevBPP != 8 &&
  368. pRPDev->sDevBPP != 24)
  369. {
  370. ERR (("Unidrv: Invalid DevBPP\n"));
  371. return FALSE;
  372. }
  373. pRPDev->sDrvBPP = pRPDev->sDevBPP;
  374. }
  375. else if ((pRPDev->sDevBPP == 1) &&
  376. (pRPDev->sDevPlanes == 3 || pRPDev->sDevPlanes == 4))
  377. {
  378. pRPDev->sDrvBPP = 4;
  379. }
  380. #ifdef MULTIPLANE
  381. else if ((pRPDev->sDevBPP == 2) &&
  382. (pRPDev->sDevPlanes == 3 || pRPDev->sDevPlanes == 4))
  383. {
  384. pRPDev->CyanLevels = 2;
  385. pRPDev->MagentaLevels = 2;
  386. pRPDev->YellowLevels = 2;
  387. pRPDev->BlackLevels = 1;
  388. pRPDev->sDevBitsPerPlane = 2;
  389. pRPDev->sDrvBPP = 8;
  390. }
  391. else if (pRPDev->sDevPlanes > 4 && pRPDev->sDevPlanes <= 8)
  392. {
  393. pRPDev->CyanLevels = 3;
  394. pRPDev->MagentaLevels = 3;
  395. pRPDev->YellowLevels = 3;
  396. pRPDev->BlackLevels = 3;
  397. pRPDev->sDevBitsPerPlane = 1;
  398. pRPDev->sDrvBPP = 8;
  399. }
  400. #endif
  401. else
  402. pRPDev->sDrvBPP = 0;
  403. // test for valid input, input must match render depth
  404. // or there must be a callback function
  405. //
  406. if (pRPDev->sDrvBPP != sDrvBPP &&
  407. (pRPDev->dwIPCallbackID == 0 ||
  408. pRPDev->pfnOEMImageProcessing == NULL) &&
  409. pPDev->ePersonality != kPCLXL &&
  410. pPDev->ePersonality != kPCLXL_RASTER)
  411. {
  412. ERR (("Unidrv: OEMImageProcessing callback required\n"))
  413. return FALSE;
  414. }
  415. //
  416. // if color mode we need to determine the color order to
  417. // send the different color planes
  418. //
  419. if (pPDev->pColorModeEx->bColor && pRPDev->sDrvBPP > 1)
  420. {
  421. //* Initialize 8BPP and 24BPP flags
  422. pRPDev->sDevPlanes = (short)pPDev->pColorModeEx->dwPrinterNumOfPlanes;
  423. if (pRPDev->sDevPlanes > 1)
  424. {
  425. iDevNumPlanes = pRPDev->sDevPlanes;
  426. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pPDev->pColorModeEx->liColorPlaneOrder);
  427. while (pListNode && dwPlanes < iDevNumPlanes)
  428. {
  429. switch (pListNode->dwData)
  430. {
  431. case COLOR_CYAN:
  432. ColorIndex = DC_PLANE_CYAN;
  433. dwColorCmd = CMD_SENDCYANDATA;
  434. break;
  435. case COLOR_MAGENTA:
  436. ColorIndex = DC_PLANE_MAGENTA;
  437. dwColorCmd = CMD_SENDMAGENTADATA;
  438. break;
  439. case COLOR_YELLOW:
  440. ColorIndex = DC_PLANE_YELLOW;
  441. dwColorCmd = CMD_SENDYELLOWDATA;
  442. break;
  443. case COLOR_RED:
  444. ColorIndex = DC_PLANE_RED;
  445. dwColorCmd = CMD_SENDREDDATA;
  446. pRPDev->fColorFormat |= DC_PRIMARY_RGB;
  447. break;
  448. case COLOR_GREEN:
  449. ColorIndex = DC_PLANE_GREEN;
  450. dwColorCmd = CMD_SENDGREENDATA;
  451. pRPDev->fColorFormat |= DC_PRIMARY_RGB;
  452. break;
  453. case COLOR_BLUE:
  454. ColorIndex = DC_PLANE_BLUE;
  455. dwColorCmd = CMD_SENDBLUEDATA;
  456. pRPDev->fColorFormat |= DC_PRIMARY_RGB;
  457. break;
  458. case COLOR_BLACK:
  459. ColorIndex = DC_PLANE_BLACK;
  460. dwColorCmd = CMD_SENDBLACKDATA;
  461. break;
  462. #ifdef MULTIPLANE
  463. // TBD
  464. #endif
  465. default:
  466. ERR (("Invalid ColorPlaneOrder value"));
  467. return FALSE;
  468. break;
  469. }
  470. // verify the command exists
  471. if (COMMANDPTR(pPDev->pDriverInfo,dwColorCmd) == NULL)
  472. return FALSE;
  473. #ifdef MULTIPLANE
  474. if (iDevNumPlanes >= 6)
  475. {
  476. pRPDev->rgbOrder[dwPlanes] = ColorIndex+4;
  477. pRPDev->rgbCmdOrder[dwPlanes] = CMD_SENDBLACKDATA;
  478. dwPlanes++;
  479. }
  480. #endif
  481. pRPDev->rgbOrder[dwPlanes] = ColorIndex;
  482. pRPDev->rgbCmdOrder[dwPlanes] = dwColorCmd;
  483. dwPlanes++;
  484. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pListNode->dwNextItem);
  485. }
  486. // GPD must define all planes
  487. if (dwPlanes < iDevNumPlanes)
  488. return FALSE;
  489. //* Determine DC_EXTRACT_BLK flag
  490. if (iDevNumPlanes == 4)
  491. pRPDev->fColorFormat |= DC_EXTRACT_BLK;
  492. }
  493. else if (pRPDev->sDevPlanes != 1)
  494. return FALSE;
  495. // if we have an OEM callback then it is
  496. // responsible for black generation and data inversion
  497. //
  498. if (pRPDev->pfnOEMImageProcessing)
  499. pRPDev->fColorFormat |= DC_OEM_BLACK;
  500. pRPDev->fDump |= RES_DM_COLOR;
  501. }
  502. // monochrome but could have pixel depth
  503. else {
  504. pRPDev->sDevPlanes = 1;
  505. pRPDev->rgbOrder[0] = DC_PLANE_BLACK;
  506. pRPDev->rgbCmdOrder[0] = CMD_SENDBLOCKDATA;
  507. }
  508. }
  509. // no ColorMode so use default: monochrome mode
  510. else {
  511. pRPDev->sDrvBPP = 1;
  512. pRPDev->sDevBPP = 1;
  513. pRPDev->sDevPlanes = 1;
  514. pRPDev->rgbOrder[0] = DC_PLANE_BLACK;
  515. pRPDev->rgbCmdOrder[0] = CMD_SENDBLOCKDATA;
  516. }
  517. return TRUE;
  518. }
  519. //*************************************************
  520. void
  521. vSetHTData(
  522. PDEV *pPDev,
  523. GDIINFO *pGDIInfo
  524. )
  525. /*++
  526. Routine Description:
  527. Fill in the halftone information required by GDI. These are filled
  528. in from the GPD data or from default values.
  529. Arguments:
  530. pPDev Pointer to PDEV structure
  531. pGDIInfo Pointer to GDIINFO structure
  532. Return Value:
  533. --*/
  534. {
  535. INT iPatID;
  536. PRASTERPDEV pRPDev = pPDev->pRasterPDEV;
  537. PHALFTONING pHalftone = pPDev->pHalftone;
  538. DWORD dwType = REG_DWORD;
  539. DWORD ul;
  540. int iGenProfile;
  541. // set to spotdiameter, if zero, GDI calculates its own value
  542. // Set MS bit designating a percentage value * 10.
  543. //
  544. if (pPDev->pResolutionEx->dwSpotDiameter >= 10000)
  545. {
  546. pPDev->fMode |= PF_SINGLEDOT_FILTER;
  547. pGDIInfo->ulDevicePelsDPI = ((pPDev->pResolutionEx->dwSpotDiameter - 10000) * 10) | 0x8000;
  548. }
  549. else
  550. pGDIInfo->ulDevicePelsDPI = (pPDev->pResolutionEx->dwSpotDiameter * 10) | 0x8000;
  551. // RASDD always sets this to BLACK_DYE only
  552. // HT_FLAG_: SQUARE_DEVICE_PEL/HAS_BLACK_DYE/ADDITIVE_PRIMS/OUTPUT_CMY
  553. //
  554. pGDIInfo->flHTFlags = HT_FLAG_HAS_BLACK_DYE;
  555. #ifdef MULTIPLANE
  556. if (pRPDev->sDevBitsPerPlane)
  557. {
  558. pGDIInfo->flHTFlags |= MAKE_CMY332_MASK(pRPDev->CyanLevels,
  559. pRPDev->MagentaLevels,
  560. pRPDev->YellowLevels);
  561. }
  562. #endif
  563. //
  564. // For 16 and 24bpp devices GDI will not do device color
  565. // mapping unless this flag is set in the GPD
  566. //
  567. #ifndef WINNT_40
  568. if (pPDev->pGlobals->bEnableGDIColorMapping)
  569. pGDIInfo->flHTFlags |= HT_FLAG_DO_DEVCLR_XFORM;
  570. if (pPDev->pdmPrivate->iQuality != QS_BEST &&
  571. !(pPDev->pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS))
  572. {
  573. pGDIInfo->flHTFlags |= HT_FLAG_PRINT_DRAFT_MODE;
  574. }
  575. #endif
  576. // At this point we need to determine the halftoning pattern
  577. // to be utilized depending on whether this is a standard halftone
  578. // custom halftone or oem supplied dither method
  579. //
  580. // if standard halftone ID map to standard pattern size values
  581. //
  582. #ifndef WINNT_40
  583. if (!pHalftone || pHalftone->dwHTID == HT_PATSIZE_AUTO)
  584. {
  585. if (pPDev->sBitsPixel == 1)
  586. iPatID = PickDefaultHTPatSize((DWORD)pGDIInfo->ulLogPixelsX,
  587. (DWORD)pGDIInfo->ulLogPixelsY);
  588. else if (pPDev->sBitsPixel == 8)
  589. iPatID = HT_PATSIZE_4x4_M;
  590. else if (pPDev->sBitsPixel >= 24)
  591. iPatID = HT_PATSIZE_8x8_M;
  592. else
  593. iPatID = HT_PATSIZE_SUPERCELL_M;
  594. }
  595. else if (pHalftone->dwHTID <= HT_PATSIZE_MAX_INDEX)
  596. {
  597. iPatID = pHalftone->dwHTID;
  598. }
  599. else
  600. {
  601. iPatID = HT_PATSIZE_USER;
  602. }
  603. #else
  604. if (!pHalftone || pHalftone->dwHTID == HT_PATSIZE_AUTO || pHalftone->dwHTID > HT_PATSIZE_MAX_INDEX)
  605. {
  606. if (pPDev->sBitsPixel == 8)
  607. iPatID = HT_PATSIZE_4x4_M;
  608. else if (pPDev->sBitsPixel == 4 && pGDIInfo->ulLogPixelsX < 400)
  609. iPatID = HT_PATSIZE_6x6_M;
  610. else
  611. iPatID = PickDefaultHTPatSize((DWORD)pGDIInfo->ulLogPixelsX,
  612. (DWORD)pGDIInfo->ulLogPixelsY);
  613. }
  614. else
  615. iPatID = pHalftone->dwHTID;
  616. #endif
  617. //
  618. // setup ciDevice to point to default color space based
  619. // on halftone method and render depth
  620. //
  621. // 22-Jan-1998 Thu 01:17:54 updated -by- Daniel Chou (danielc)
  622. // for saving the data, we will assume gamma 1.0 and has dye correction to
  623. // start with then modify as necessary
  624. //
  625. pGDIInfo->ciDevice = DefColorInfoLinear;
  626. if (pPDev->sBitsPixel >= 24 && pRPDev->pfnOEMImageProcessing)
  627. {
  628. //
  629. // No dye correction and the gamma is linear 1.0
  630. //
  631. ZeroMemory(&(pGDIInfo->ciDevice.MagentaInCyanDye),
  632. sizeof(LDECI4) * 6);
  633. }
  634. else
  635. {
  636. LDECI4 Gamma;
  637. if (pPDev->sBitsPixel >= 8) {
  638. Gamma = GAMMA_DEVICE_HT;
  639. }
  640. #ifndef WINNT_40
  641. else if ((iPatID == HT_PATSIZE_SUPERCELL) ||
  642. (iPatID == HT_PATSIZE_SUPERCELL_M))
  643. {
  644. Gamma = GAMMA_SUPERCELL;
  645. }
  646. #endif
  647. else
  648. {
  649. Gamma = GAMMA_DITHER;
  650. }
  651. pGDIInfo->ciDevice.RedGamma =
  652. pGDIInfo->ciDevice.GreenGamma =
  653. pGDIInfo->ciDevice.BlueGamma = Gamma;
  654. }
  655. //
  656. // If this flag is set in the registry we inform GDI halftoning
  657. // to ignore all color settings and pass data through raw
  658. // for calibration purposes
  659. //
  660. if( !EngGetPrinterData( pPDev->devobj.hPrinter, L"ICMGenProfile", &dwType,
  661. (BYTE *)&iGenProfile, sizeof(iGenProfile), &ul ) &&
  662. ul == sizeof(iGenProfile) && iGenProfile == 1 )
  663. {
  664. pGDIInfo->ciDevice.RedGamma =
  665. pGDIInfo->ciDevice.GreenGamma =
  666. pGDIInfo->ciDevice.BlueGamma = GAMMA_GEN_PROFILE;
  667. }
  668. else
  669. {
  670. //
  671. // now modify with any GPD parameters
  672. //
  673. if ((int)pPDev->pResolutionEx->dwRedDeviceGamma >= 0)
  674. pGDIInfo->ciDevice.RedGamma = pPDev->pResolutionEx->dwRedDeviceGamma;
  675. if ((int)pPDev->pResolutionEx->dwGreenDeviceGamma >= 0)
  676. pGDIInfo->ciDevice.GreenGamma = pPDev->pResolutionEx->dwGreenDeviceGamma;
  677. if ((int)pPDev->pResolutionEx->dwBlueDeviceGamma >= 0)
  678. pGDIInfo->ciDevice.BlueGamma = pPDev->pResolutionEx->dwBlueDeviceGamma;
  679. if ((int)pPDev->pGlobals->dwMagentaInCyanDye >= 0)
  680. pGDIInfo->ciDevice.MagentaInCyanDye = pPDev->pGlobals->dwMagentaInCyanDye;
  681. if ((int)pPDev->pGlobals->dwYellowInCyanDye >= 0)
  682. pGDIInfo->ciDevice.YellowInCyanDye = pPDev->pGlobals->dwYellowInCyanDye;
  683. if ((int)pPDev->pGlobals->dwCyanInMagentaDye >= 0)
  684. pGDIInfo->ciDevice.CyanInMagentaDye = pPDev->pGlobals->dwCyanInMagentaDye;
  685. if ((int)pPDev->pGlobals->dwYellowInMagentaDye >= 0)
  686. pGDIInfo->ciDevice.YellowInMagentaDye = pPDev->pGlobals->dwYellowInMagentaDye;
  687. if ((int)pPDev->pGlobals->dwCyanInYellowDye >= 0)
  688. pGDIInfo->ciDevice.CyanInYellowDye = pPDev->pGlobals->dwCyanInYellowDye;
  689. if ((int)pPDev->pGlobals->dwMagentaInYellowDye >= 0)
  690. pGDIInfo->ciDevice.MagentaInYellowDye = pPDev->pGlobals->dwMagentaInYellowDye;
  691. }
  692. //
  693. // test for a custom pattern
  694. //
  695. #ifndef WINNT_40
  696. if (iPatID == HT_PATSIZE_USER)
  697. {
  698. DWORD dwX,dwY,dwPats,dwRC,dwCallbackID,dwPatSize,dwOnePatSize;
  699. int iSize = 0;
  700. PBYTE pRes = NULL;
  701. dwX = pHalftone->HalftonePatternSize.x;
  702. dwY = pHalftone->HalftonePatternSize.y;
  703. dwRC = pHalftone->dwRCpatternID;
  704. pGDIInfo->ulHTPatternSize = HT_PATSIZE_DEFAULT;
  705. if (dwX < HT_USERPAT_CX_MIN || dwX > HT_USERPAT_CX_MAX ||
  706. dwY < HT_USERPAT_CY_MIN || dwY > HT_USERPAT_CY_MAX)
  707. {
  708. ERR (("Unidrv!RMInit: Missing or invalid custom HT size\n"));
  709. return;
  710. }
  711. dwPats = pHalftone->dwHTNumPatterns;
  712. dwCallbackID = pHalftone->dwHTCallbackID;
  713. // calculate the size of the halftone pattern
  714. //
  715. dwOnePatSize = ((dwX * dwY) + 3) & ~3;
  716. dwPatSize = dwOnePatSize * dwPats;
  717. // test for resource ID which means the pattern is
  718. // in the resource dll.
  719. //
  720. if (dwRC > 0)
  721. {
  722. RES_ELEM ResInfo;
  723. if (!BGetWinRes(&pPDev->WinResData,(PQUALNAMEEX)&dwRC,RC_HTPATTERN,&ResInfo))
  724. {
  725. ERR (("Unidrv!RMInit: Can't find halftone resource\n"));
  726. return;
  727. }
  728. else if ((DWORD)ResInfo.iResLen < dwPatSize && dwCallbackID <= 0)
  729. {
  730. ERR (("Unidrv!RMInit: Invalid resource size\n"));
  731. return;
  732. }
  733. pRes = ResInfo.pvResData;
  734. iSize = ResInfo.iResLen;
  735. }
  736. else if (dwCallbackID <= 0)
  737. {
  738. ERR (("Unidrv!RMInit: no OEMHalftonePattern callback ID\n"));
  739. return;
  740. }
  741. //
  742. // test whether we need to make the OEMHalftonePattern callback
  743. // this will either unencrypt the resource pattern or it will
  744. // generate a halftone pattern on the fly.
  745. //
  746. if (dwCallbackID > 0)
  747. {
  748. PBYTE pPattern;
  749. // allocate memory for the callback
  750. //
  751. if ((pPattern = MemAllocZ(dwPatSize)) != NULL)
  752. {
  753. BOOL bStatus = FALSE;
  754. FIX_DEVOBJ(pPDev,EP_OEMHalftonePattern);
  755. if (pRPDev->pfnOEMHalftonePattern)
  756. {
  757. if(pPDev->pOemEntry)
  758. {
  759. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  760. {
  761. HRESULT hr ;
  762. hr = HComHalftonePattern((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  763. (PDEVOBJ)pPDev,pPattern,dwX,dwY,dwPats,dwCallbackID,pRes,iSize) ;
  764. if(SUCCEEDED(hr))
  765. bStatus = TRUE ; // cool !
  766. }
  767. else
  768. {
  769. bStatus = pRPDev->pfnOEMHalftonePattern((PDEVOBJ)pPDev,pPattern,dwX,dwY,dwPats,dwCallbackID,pRes,iSize) ;
  770. }
  771. }
  772. }
  773. if(!bStatus)
  774. {
  775. MemFree (pPattern);
  776. ERR (("\nUnidrv!RMInit: Failed OEMHalftonePattern call\n"));
  777. return;
  778. }
  779. else
  780. {
  781. pRes = pPattern;
  782. pRPDev->pHalftonePattern = pPattern;
  783. }
  784. }
  785. else
  786. {
  787. ERR (("\nUnidrv!RMInit: Failed Custom Halftone MemAlloc\n"));
  788. return;
  789. }
  790. }
  791. //
  792. // if we still have a valid custom pattern we will now
  793. // update the GDIINFO structure
  794. //
  795. pGDIInfo->cxHTPat = dwX;
  796. pGDIInfo->cyHTPat = dwY;
  797. pGDIInfo->pHTPatA = pRes;
  798. if (dwPats == 3)
  799. {
  800. pGDIInfo->pHTPatB = &pRes[dwOnePatSize];
  801. pGDIInfo->pHTPatC = &pRes[dwOnePatSize*2];
  802. }
  803. else {
  804. pGDIInfo->pHTPatB = pRes;
  805. pGDIInfo->pHTPatC = pRes;
  806. }
  807. }
  808. #endif
  809. pGDIInfo->ulHTPatternSize = iPatID;
  810. return;
  811. }
  812. //*************************************************************
  813. DWORD
  814. PickDefaultHTPatSize(
  815. DWORD xDPI,
  816. DWORD yDPI
  817. )
  818. /*++
  819. Routine Description:
  820. This function return default halftone pattern size used for
  821. a particular device resolution
  822. Arguments:
  823. xDPI - Device LOGPIXELS X
  824. yDPI - Device LOGPIXELS Y
  825. Return Value:
  826. DWORD HT_PATSIZE_xxxx
  827. --*/
  828. {
  829. DWORD HTPatSize;
  830. //
  831. // use the smaller resolution as the pattern guide
  832. //
  833. if (xDPI > yDPI)
  834. xDPI = yDPI;
  835. if (xDPI >= 2400)
  836. HTPatSize = HT_PATSIZE_16x16_M;
  837. else if (xDPI >= 1800)
  838. HTPatSize = HT_PATSIZE_14x14_M;
  839. else if (xDPI >= 1200)
  840. HTPatSize = HT_PATSIZE_12x12_M;
  841. else if (xDPI >= 800)
  842. HTPatSize = HT_PATSIZE_10x10_M;
  843. else if (xDPI >= 300)
  844. HTPatSize = HT_PATSIZE_8x8_M;
  845. else
  846. HTPatSize = HT_PATSIZE_6x6_M;
  847. return(HTPatSize);
  848. }
  849. //*************************************************************
  850. BOOL
  851. bEnoughDRCMemory(
  852. PDEV *pPDev
  853. )
  854. /*++
  855. Routine Description:
  856. This function determines whether the device has sufficient
  857. memory to enable DRC compression.
  858. Arguments:
  859. pPDev - pointer to PDEV structure
  860. Return Value:
  861. TRUE if sufficient memory, else FALSE
  862. --*/
  863. {
  864. //
  865. // if this is a page printer then we will require that there be enough
  866. // free memory to store the entire raster page at 1bpp
  867. //
  868. if (pPDev->pGlobals->printertype != PT_PAGE ||
  869. !(COMMANDPTR(pPDev->pDriverInfo,CMD_DISABLECOMPRESSION)) ||
  870. (pPDev->pMemOption && (int)pPDev->pMemOption->dwInstalledMem >
  871. (pPDev->sf.szImageAreaG.cx * pPDev->sf.szImageAreaG.cy >> 3)))
  872. {
  873. return TRUE;
  874. }
  875. VERBOSE (("Unidrv: Insufficient memory for DRC\n"));
  876. return FALSE;
  877. }
  878. #ifndef DISABLE_NEWRULES
  879. //*************************************************************
  880. VOID
  881. OutputRules(
  882. PDEV *pPDev
  883. )
  884. /*++
  885. Routine Description:
  886. This function outputs any rules that still remain after rendering
  887. the current band or page.
  888. Arguments:
  889. pPDev - pointer to PDEV structure
  890. Return Value:
  891. none
  892. --*/
  893. {
  894. if (pPDev->pbRulesArray && pPDev->dwRulesCount)
  895. {
  896. PRECTL pRect;
  897. DWORD i;
  898. DRAWPATRECT PatRect;
  899. PatRect.wStyle = 0; // black rectangle
  900. PatRect.wPattern = 0; // pattern not used
  901. // DbgPrint("Black rules = %u\n",pPDev->dwRulesCount);
  902. for (i = 0;i < pPDev->dwRulesCount;i++)
  903. {
  904. pRect = &pPDev->pbRulesArray[i];
  905. PatRect.ptPosition.x = pRect->left;
  906. PatRect.ptPosition.y = pRect->top;
  907. PatRect.ptSize.x = pRect->right - pRect->left;
  908. PatRect.ptSize.y = pRect->bottom - pRect->top;
  909. if (pPDev->fMode & PF_SINGLEDOT_FILTER)
  910. {
  911. if (PatRect.ptSize.y < 2)
  912. PatRect.ptSize.y = 2;
  913. if (PatRect.ptSize.x < 2)
  914. PatRect.ptSize.x = 2;
  915. }
  916. DrawPatternRect(pPDev,&PatRect);
  917. }
  918. pPDev->dwRulesCount = 0;
  919. }
  920. }
  921. #endif
  922. //*************************************************************
  923. VOID
  924. EnableMirroring(
  925. PDEV *pPDev,
  926. SURFOBJ *pso
  927. )
  928. /*++
  929. Routine Description:
  930. This function mirrors the data in the current band or page.
  931. Arguments:
  932. pPDev - pointer to PDEV structure
  933. pso - pointer to SURFOBJ structure containing the bitmap
  934. Return Value:
  935. none
  936. --*/
  937. {
  938. INT iScanLine;
  939. INT iLastY;
  940. INT i;
  941. // if the surface hasn't been used then no point in mirroring it
  942. //
  943. if (!(pPDev->fMode & PF_SURFACE_USED))
  944. return;
  945. // precalculate necessary shared loop parameters
  946. //
  947. iScanLine = (((pso->sizlBitmap.cx * pPDev->sBitsPixel) + 31) & ~31) / BBITS;
  948. iLastY = pPDev->rcClipRgn.bottom - pPDev->rcClipRgn.top;
  949. // First test whether we need to do landscape mirroring
  950. // If so we will mirror the data top to bottom by swapping scan lines
  951. //
  952. if (pPDev->pOrientation && pPDev->pOrientation->dwRotationAngle != ROTATE_NONE)
  953. {
  954. BYTE ubWhite;
  955. INT iTmpLastY = iLastY;
  956. // determined erase byte
  957. //
  958. if (pPDev->sBitsPixel == 4)
  959. ubWhite = 0x77;
  960. else if (pPDev->sBitsPixel == 8)
  961. ubWhite = (BYTE)((PAL_DATA*)(pPDev->pPalData))->iWhiteIndex;
  962. else
  963. ubWhite = 0xff;
  964. // loop once per scan line swapping the rows
  965. //
  966. iLastY--;
  967. for (i = 0;i < iLastY;i++,iLastY--)
  968. {
  969. BYTE *pBits1,*pBits2;
  970. pBits1 = (PBYTE)pso->pvBits + (iScanLine * i);
  971. pBits2 = (PBYTE)pso->pvBits + (iScanLine * iLastY);
  972. // test if bottom line has data
  973. //
  974. if (pPDev->pbRasterScanBuf[iLastY / LINESPERBLOCK] & 1)
  975. {
  976. // test if top line has data, if so swap data
  977. //
  978. if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK] & 1)
  979. {
  980. INT j = iScanLine >> 2;
  981. do {
  982. DWORD dwTmp = ((DWORD *)pBits1)[j];
  983. ((DWORD *)pBits1)[j] = ((DWORD *)pBits2)[j];
  984. ((DWORD *)pBits2)[j] = dwTmp;
  985. } while (--j > 0);
  986. }
  987. else
  988. {
  989. CopyMemory(pBits1,pBits2,iScanLine);
  990. FillMemory(pBits2,iScanLine,ubWhite);
  991. }
  992. }
  993. // test if top line has data
  994. //
  995. else if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK] & 1)
  996. {
  997. CopyMemory(pBits2,pBits1,iScanLine);
  998. FillMemory(pBits1,iScanLine,ubWhite);
  999. }
  1000. // neither scan line has data but we need to erase both anyway
  1001. //
  1002. else
  1003. {
  1004. FillMemory(pBits1,iScanLine,ubWhite);
  1005. FillMemory(pBits2,iScanLine,ubWhite);
  1006. }
  1007. }
  1008. // set all bits since everything has been erased
  1009. for (i = 0;i < iTmpLastY;i += LINESPERBLOCK)
  1010. {
  1011. pPDev->pbRasterScanBuf[i / LINESPERBLOCK] = 1;
  1012. }
  1013. }
  1014. //
  1015. // We are doing portrait mirroring, test for 1bpp
  1016. //
  1017. else if (pPDev->sBitsPixel == 1)
  1018. {
  1019. BYTE ubMirror[256];
  1020. INT iLastX;
  1021. INT iShift;
  1022. // create byte mirroring table
  1023. //
  1024. for (i = 0;i < 256;i++)
  1025. {
  1026. BYTE bOut = 0;
  1027. if (i & 0x01) bOut |= 0x80;
  1028. if (i & 0x02) bOut |= 0x40;
  1029. if (i & 0x04) bOut |= 0x20;
  1030. if (i & 0x08) bOut |= 0x10;
  1031. if (i & 0x10) bOut |= 0x08;
  1032. if (i & 0x20) bOut |= 0x04;
  1033. if (i & 0x40) bOut |= 0x02;
  1034. if (i & 0x80) bOut |= 0x01;
  1035. ubMirror[i] = bOut;
  1036. }
  1037. // create shift value to re-align data
  1038. //
  1039. iShift = (8 - (pso->sizlBitmap.cx & 0x7)) & 0x7;
  1040. // loop once per scan line and mirror left to right
  1041. //
  1042. for (i = 0;i < iLastY;i++)
  1043. {
  1044. BYTE *pBits = (PBYTE)pso->pvBits + (iScanLine * i);
  1045. if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK])
  1046. {
  1047. INT j;
  1048. INT iLastX;
  1049. // test whether we need to pre-shift the data
  1050. //
  1051. if (iShift)
  1052. {
  1053. iLastX = (pso->sizlBitmap.cx + 7) / 8;
  1054. iLastX--;
  1055. while (iLastX > 0)
  1056. {
  1057. pBits[iLastX] = (pBits[iLastX-1] << (8-iShift)) | (pBits[iLastX] >> iShift);
  1058. iLastX--;
  1059. }
  1060. pBits[0] = (BYTE)(pBits[0] >> iShift);
  1061. }
  1062. // Now we are ready to mirror the bytes
  1063. //
  1064. j = 0;
  1065. iLastX = (pso->sizlBitmap.cx + 7) / 8;
  1066. while (j < iLastX)
  1067. {
  1068. BYTE ubTmp;
  1069. iLastX--;
  1070. ubTmp = ubMirror[pBits[iLastX]];
  1071. pBits[iLastX] = ubMirror[pBits[j]];
  1072. pBits[j] = ubTmp;
  1073. j++;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. //
  1079. // We are doing portrait mirroring, test for 4bpp
  1080. //
  1081. else if (pPDev->sBitsPixel == 4)
  1082. {
  1083. BYTE ubMirror[256];
  1084. // create byte mirroring table
  1085. //
  1086. for (i = 0;i < 256;i++)
  1087. {
  1088. ubMirror[i] = ((BYTE)i << 4) | ((BYTE)i >> 4);
  1089. }
  1090. // loop once per scan line and mirror left to right
  1091. //
  1092. for (i = 0;i < iLastY;i++)
  1093. {
  1094. BYTE *pBits = (PBYTE)pso->pvBits + (iScanLine * i);
  1095. if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK])
  1096. {
  1097. INT j = 0;
  1098. INT iLastX = (pso->sizlBitmap.cx + 1) / 2;
  1099. while (j < iLastX)
  1100. {
  1101. BYTE ubTmp;
  1102. iLastX--;
  1103. ubTmp = ubMirror[pBits[iLastX]];
  1104. pBits[iLastX] = ubMirror[pBits[j]];
  1105. pBits[j] = ubTmp;
  1106. j++;
  1107. }
  1108. }
  1109. }
  1110. }
  1111. //
  1112. // We are doing portrait mirroring, test for 8bpp
  1113. //
  1114. else if (pPDev->sBitsPixel == 8)
  1115. {
  1116. // loop once per scan line and mirror left to right
  1117. //
  1118. for (i = 0;i < iLastY;i++)
  1119. {
  1120. BYTE *pBits = (PBYTE)pso->pvBits + (iScanLine * i);
  1121. if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK])
  1122. {
  1123. INT j = 0;
  1124. INT iLastX = pso->sizlBitmap.cx - 1;
  1125. while (j < iLastX)
  1126. {
  1127. BYTE ubTmp = pBits[iLastX];
  1128. pBits[iLastX] = pBits[j];
  1129. pBits[j] = ubTmp;
  1130. iLastX--;
  1131. j++;
  1132. }
  1133. }
  1134. }
  1135. }
  1136. //
  1137. // We are doing portrait mirroring, 24bpp
  1138. //
  1139. else
  1140. {
  1141. // loop once per scan line and mirror left to right
  1142. //
  1143. for (i = 0;i < iLastY;i++)
  1144. {
  1145. BYTE *pBits = (PBYTE)pso->pvBits + (iScanLine * i);
  1146. if (pPDev->pbRasterScanBuf[i / LINESPERBLOCK])
  1147. {
  1148. INT j = 0;
  1149. INT iLastX = (pso->sizlBitmap.cx * 3) - 3;
  1150. while (j < iLastX)
  1151. {
  1152. BYTE ubTmp[3];
  1153. memcpy(&ubTmp[0],&pBits[iLastX],3);
  1154. memcpy(&pBits[iLastX],&pBits[j],3);
  1155. memcpy(&pBits[j],&ubTmp,3);
  1156. iLastX -= 3;
  1157. j += 3;
  1158. }
  1159. }
  1160. }
  1161. }
  1162. }
  1163. //*************************************************************
  1164. PDWORD
  1165. pSetupOEMImageProcessing(
  1166. PDEV *pPDev,
  1167. SURFOBJ *pso
  1168. )
  1169. /*++
  1170. Routine Description:
  1171. This function initializes all the relevant parameters and then
  1172. calls the OEMImageProcessing function.
  1173. Arguments:
  1174. pPDev - pointer to PDEV structure
  1175. pso - pointer to SURFOBJ structure
  1176. pptl - pointer to current position of band
  1177. Return Value:
  1178. Pointer to modified bitmap if any
  1179. --*/
  1180. {
  1181. #ifndef DISABLE_SUBBANDS
  1182. BITMAPINFOHEADER bmi;
  1183. IPPARAMS State;
  1184. RASTERPDEV *pRPDev;
  1185. PBYTE pbResult = NULL ;
  1186. INT iStart, iEnd ,iScanLine, iLastY;
  1187. pRPDev = pPDev->pRasterPDEV;
  1188. //
  1189. // initialize the state structure
  1190. //
  1191. State.dwSize = sizeof (IPPARAMS);
  1192. State.bBanding = pPDev->bBanding;
  1193. //
  1194. // Determine the pointer to the halftone option name
  1195. //
  1196. if (pPDev->pHalftone)
  1197. {
  1198. State.pHalftoneOption =
  1199. OFFSET_TO_POINTER(pPDev->pDriverInfo->pubResourceData,
  1200. pPDev->pHalftone->GenericOption.loKeywordName);
  1201. }
  1202. else
  1203. State.pHalftoneOption = NULL;
  1204. //
  1205. // Set blank band flag if this band hasn't been erased or
  1206. // drawn on.
  1207. if ((pPDev->fMode & PF_SURFACE_USED) &&
  1208. ((pPDev->fMode & PF_ROTATE) ||
  1209. (pRPDev->sDrvBPP != 0) ||
  1210. ((LINESPERBLOCK % pRPDev->sNPins) != 0)))
  1211. {
  1212. CheckBitmapSurface(pso, NULL);
  1213. }
  1214. //
  1215. // loop once per strip
  1216. //
  1217. iScanLine = (((pso->sizlBitmap.cx * pPDev->sBitsPixel) + 31) & ~31) / BBITS;
  1218. iLastY = pPDev->rcClipRgn.bottom - pPDev->rcClipRgn.top;
  1219. if(pPDev->iBandDirection == SW_UP)
  1220. {
  1221. iStart = iLastY;
  1222. do
  1223. {
  1224. // search for contiguous sub-bands of white or non-white
  1225. //
  1226. PBYTE pBits;
  1227. BYTE Mode;
  1228. iEnd = iStart ;
  1229. iStart = ((iEnd - 1)/ LINESPERBLOCK) * LINESPERBLOCK ;
  1230. // first band (end of bitmap) may be partial.
  1231. Mode = pPDev->pbRasterScanBuf[iStart / LINESPERBLOCK];
  1232. while (iStart) // not yet at start of bitmap
  1233. {
  1234. int iPreview = iStart - LINESPERBLOCK;
  1235. if (Mode != pPDev->pbRasterScanBuf[iPreview / LINESPERBLOCK])
  1236. break;
  1237. iStart = iPreview ;
  1238. }
  1239. // initialize starting position of the sub-band
  1240. //
  1241. State.ptOffset.x = pPDev->rcClipRgn.left;
  1242. State.ptOffset.y = pPDev->rcClipRgn.top + iStart;
  1243. // test whether to set blank flag
  1244. //
  1245. if (Mode)
  1246. State.bBlankBand = FALSE;
  1247. else
  1248. State.bBlankBand = TRUE;
  1249. //
  1250. // initialize the bitmapinfo structure
  1251. //
  1252. bmi.biSize = sizeof (BITMAPINFOHEADER);
  1253. bmi.biWidth = pso->sizlBitmap.cx;
  1254. bmi.biHeight = iEnd - iStart;
  1255. bmi.biPlanes = 1;
  1256. bmi.biBitCount = pPDev->sBitsPixel;
  1257. bmi.biSizeImage = iScanLine * bmi.biHeight;
  1258. bmi.biCompression = BI_RGB;
  1259. bmi.biXPelsPerMeter = pPDev->ptGrxRes.x;
  1260. bmi.biYPelsPerMeter = pPDev->ptGrxRes.y;
  1261. bmi.biClrUsed = 0;
  1262. bmi.biClrImportant = 0;
  1263. // update the bitmap pointer
  1264. //
  1265. pBits = (PBYTE)pso->pvBits + (iScanLine * iStart);
  1266. // update the pPDev pointer for this callback
  1267. //
  1268. FIX_DEVOBJ(pPDev,EP_OEMImageProcessing);
  1269. if(pPDev->pOemEntry)
  1270. {
  1271. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1272. {
  1273. HRESULT hr ;
  1274. hr = HComImageProcessing((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1275. (PDEVOBJ)pPDev,
  1276. pBits,
  1277. &bmi,
  1278. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1279. pRPDev->dwIPCallbackID,
  1280. &State, &pbResult);
  1281. if(SUCCEEDED(hr))
  1282. ; // cool !
  1283. }
  1284. else
  1285. {
  1286. pbResult = pRPDev->pfnOEMImageProcessing(
  1287. (PDEVOBJ)pPDev,
  1288. pBits,
  1289. &bmi,
  1290. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1291. pRPDev->dwIPCallbackID,
  1292. &State);
  1293. }
  1294. if (pbResult == NULL)
  1295. {
  1296. #if DBG
  1297. DbgPrint ("unidrv!ImageProcessing: OEMImageProcessing returned error\n");
  1298. #endif
  1299. break;
  1300. }
  1301. }
  1302. } while (iStart /* iEnd < iLastY */);
  1303. }
  1304. else
  1305. {
  1306. iEnd = 0;
  1307. do
  1308. {
  1309. // search for contiguous sub-bands of white or non-white
  1310. //
  1311. PBYTE pBits;
  1312. BYTE Mode;
  1313. iStart = iEnd;
  1314. Mode = pPDev->pbRasterScanBuf[iEnd / LINESPERBLOCK];
  1315. while (1)
  1316. {
  1317. iEnd += LINESPERBLOCK;
  1318. if (iEnd >= iLastY)
  1319. break;
  1320. if (Mode != pPDev->pbRasterScanBuf[iEnd / LINESPERBLOCK])
  1321. break;
  1322. }
  1323. //
  1324. // limit this section to the end of the band
  1325. //
  1326. if (iEnd > iLastY)
  1327. iEnd = iLastY;
  1328. // initialize starting position of the sub-band
  1329. //
  1330. State.ptOffset.x = pPDev->rcClipRgn.left;
  1331. State.ptOffset.y = pPDev->rcClipRgn.top + iStart;
  1332. // test whether to set blank flag
  1333. //
  1334. if (Mode)
  1335. State.bBlankBand = FALSE;
  1336. else
  1337. State.bBlankBand = TRUE;
  1338. //
  1339. // initialize the bitmapinfo structure
  1340. //
  1341. bmi.biSize = sizeof (BITMAPINFOHEADER);
  1342. bmi.biWidth = pso->sizlBitmap.cx;
  1343. bmi.biHeight = iEnd - iStart;
  1344. bmi.biPlanes = 1;
  1345. bmi.biBitCount = pPDev->sBitsPixel;
  1346. bmi.biSizeImage = iScanLine * bmi.biHeight;
  1347. bmi.biCompression = BI_RGB;
  1348. bmi.biXPelsPerMeter = pPDev->ptGrxRes.x;
  1349. bmi.biYPelsPerMeter = pPDev->ptGrxRes.y;
  1350. bmi.biClrUsed = 0;
  1351. bmi.biClrImportant = 0;
  1352. // update the bitmap pointer
  1353. //
  1354. pBits = (PBYTE)pso->pvBits + (iScanLine * iStart);
  1355. // update the pPDev pointer for this callback
  1356. //
  1357. FIX_DEVOBJ(pPDev,EP_OEMImageProcessing);
  1358. if(pPDev->pOemEntry)
  1359. {
  1360. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1361. {
  1362. HRESULT hr ;
  1363. hr = HComImageProcessing((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1364. (PDEVOBJ)pPDev,
  1365. pBits,
  1366. &bmi,
  1367. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1368. pRPDev->dwIPCallbackID,
  1369. &State, &pbResult);
  1370. if(SUCCEEDED(hr))
  1371. ; // cool !
  1372. }
  1373. else
  1374. {
  1375. pbResult = pRPDev->pfnOEMImageProcessing(
  1376. (PDEVOBJ)pPDev,
  1377. pBits,
  1378. &bmi,
  1379. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1380. pRPDev->dwIPCallbackID,
  1381. &State);
  1382. }
  1383. if (pbResult == NULL)
  1384. {
  1385. #if DBG
  1386. DbgPrint ("unidrv!ImageProcessing: OEMImageProcessing returned error\n");
  1387. #endif
  1388. break;
  1389. }
  1390. }
  1391. } while (iEnd < iLastY);
  1392. }
  1393. #else
  1394. BITMAPINFOHEADER bmi;
  1395. IPPARAMS State;
  1396. RASTERPDEV *pRPDev;
  1397. PBYTE pbResult = NULL ;
  1398. pRPDev = pPDev->pRasterPDEV;
  1399. //
  1400. // initialize the state structure
  1401. //
  1402. State.dwSize = sizeof (IPPARAMS);
  1403. State.bBanding = pPDev->bBanding;
  1404. //
  1405. // Determine the pointer to the halftone option name
  1406. //
  1407. if (pPDev->pHalftone)
  1408. {
  1409. State.pHalftoneOption =
  1410. OFFSET_TO_POINTER(pPDev->pDriverInfo->pubResourceData,
  1411. pPDev->pHalftone->GenericOption.loKeywordName);
  1412. }
  1413. else
  1414. State.pHalftoneOption = NULL;
  1415. //
  1416. // Set blank band flag if this band hasn't been erased or
  1417. // drawn on.
  1418. if (pPDev->fMode & PF_SURFACE_USED)
  1419. {
  1420. CheckBitmapSurface(pso, NULL);
  1421. State.bBlankBand = FALSE;
  1422. }
  1423. else
  1424. State.bBlankBand = TRUE;
  1425. // initialize starting position of the band
  1426. //
  1427. State.ptOffset.x = pPDev->rcClipRgn.left;
  1428. State.ptOffset.y = pPDev->rcClipRgn.top;
  1429. //
  1430. // initialize the bitmapinfo structure
  1431. //
  1432. bmi.biSize = sizeof (BITMAPINFOHEADER);
  1433. bmi.biWidth = pso->sizlBitmap.cx;
  1434. bmi.biHeight = pso->sizlBitmap.cy;
  1435. bmi.biPlanes = 1;
  1436. bmi.biBitCount = pPDev->sBitsPixel;
  1437. bmi.biCompression = BI_RGB;
  1438. bmi.biSizeImage = (((bmi.biWidth * bmi.biBitCount) + 31) & ~31) *
  1439. bmi.biHeight;
  1440. bmi.biXPelsPerMeter = pPDev->ptGrxRes.x;
  1441. bmi.biYPelsPerMeter = pPDev->ptGrxRes.y;
  1442. bmi.biClrUsed = 0;
  1443. bmi.biClrImportant = 0;
  1444. // update the pPDev pointer for this callback
  1445. //
  1446. FIX_DEVOBJ(pPDev,EP_OEMImageProcessing);
  1447. if(pPDev->pOemEntry)
  1448. {
  1449. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1450. {
  1451. HRESULT hr ;
  1452. hr = HComImageProcessing((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1453. (PDEVOBJ)pPDev,
  1454. pso->pvBits,
  1455. &bmi,
  1456. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1457. pRPDev->dwIPCallbackID,
  1458. &State, &pbResult);
  1459. if(SUCCEEDED(hr))
  1460. ; // cool !
  1461. }
  1462. else
  1463. {
  1464. pbResult = pRPDev->pfnOEMImageProcessing(
  1465. (PDEVOBJ)pPDev,
  1466. pso->pvBits,
  1467. &bmi,
  1468. (PBYTE)&((PAL_DATA *)(pPDev->pPalData))->ulPalCol[0],
  1469. pRPDev->dwIPCallbackID,
  1470. &State);
  1471. }
  1472. }
  1473. #endif
  1474. return (PDWORD)pbResult ;
  1475. }
  1476. //******************************************************************
  1477. BOOL
  1478. RMStartDoc(
  1479. SURFOBJ *pso,
  1480. PWSTR pDocName,
  1481. DWORD jobId
  1482. )
  1483. /*++
  1484. Routine Description:
  1485. This function is called to allow any raster module initialization
  1486. at DrvStartDoc time.
  1487. Arguments:
  1488. pso Pointer to SURFOBJ
  1489. pDocName Pointer to document name
  1490. jobId Job ID
  1491. Return Value:
  1492. TRUE for success and FALSE for failure
  1493. --*/
  1494. {
  1495. #ifdef TIMING
  1496. ENG_TIME_FIELDS TimeTab;
  1497. PDEV *pPDev = (PDEV *) pso->dhpdev;
  1498. RASTERPDEV *pRPDev = pPDev->pRasterPDEV;
  1499. EngQueryLocalTime(&TimeTab);
  1500. pRPDev->dwDocTiming = (((TimeTab.usMinute*60)+TimeTab.usSecond)*1000)+
  1501. TimeTab.usMilliseconds;
  1502. DrvDbgPrint("Unidrv!StartDoc\n");
  1503. #endif
  1504. return TRUE;
  1505. }
  1506. //************************ Function Header ***********************************
  1507. BOOL
  1508. RMEndDoc (
  1509. SURFOBJ *pso,
  1510. FLONG flags
  1511. )
  1512. /*++
  1513. Routine Description:
  1514. This function is called at DrvEndDoc to allow the raster module
  1515. to clean up any raster related initializations
  1516. Arguments:
  1517. pso Pointer to SURFOBJ
  1518. FLONG flags
  1519. Return Value:
  1520. TRUE for success and FALSE for failure
  1521. --*/
  1522. {
  1523. #ifdef TIMING
  1524. DWORD eTime;
  1525. char buf[80];
  1526. ENG_TIME_FIELDS TimeTab;
  1527. PDEV *pPDev = (PDEV *) pso->dhpdev;
  1528. RASTERPDEV *pRPDev = pPDev->pRasterPDEV;
  1529. EngQueryLocalTime(&TimeTab);
  1530. eTime = (((TimeTab.usMinute*60)+TimeTab.usSecond)*1000)+
  1531. TimeTab.usMilliseconds;
  1532. sprintf (buf,"Unidrv!EndDoc: %ld\n",eTime - pRPDev->dwDocTiming);
  1533. DrvDbgPrint(buf);
  1534. #endif
  1535. return TRUE;
  1536. }
  1537. //******************************************************************
  1538. BOOL
  1539. RMStartPage (
  1540. SURFOBJ *pso
  1541. )
  1542. /*++
  1543. Routine Description:
  1544. This function is called to allow any raster module initialization
  1545. at DrvStartPage time.
  1546. Arguments:
  1547. pso Pointer to SURFOBJ
  1548. Return Value:
  1549. TRUE for success and FALSE for failure
  1550. --*/
  1551. {
  1552. return TRUE;
  1553. }
  1554. //************************ Function Header ***********************************
  1555. BOOL
  1556. RMSendPage (
  1557. SURFOBJ *pso
  1558. )
  1559. /*++
  1560. Routine Description:
  1561. This function is called at DrvSendPage to allow the raster module
  1562. to output any raster data to the printer.
  1563. Arguments:
  1564. pso Pointer to SURFOBJ
  1565. Return Value:
  1566. TRUE for success and FALSE for failure
  1567. --*/
  1568. {
  1569. PDEV *pPDev; /* Access to all that is important */
  1570. RENDER RenderData; /* Rendering data passed to bRender() */
  1571. PRASTERPDEV pRPDev; /* raster module PDEV */
  1572. // all we need to do now is render the bitmap (output it to the printer)
  1573. // we must be careful however since the control module also calls this
  1574. // function after the last band has been output in banding mode. In this
  1575. // case we don't want to output any data
  1576. //
  1577. pPDev = (PDEV *) pso->dhpdev;
  1578. pRPDev = pPDev->pRasterPDEV;
  1579. //
  1580. // Reset palette data
  1581. //
  1582. if (pPDev->ePersonality == kPCLXL_RASTER && pPDev->pVectorPDEV)
  1583. {
  1584. PCLXLResetPalette((PDEVOBJ)pPDev);
  1585. }
  1586. if (pso->iType == STYPE_BITMAP)
  1587. {
  1588. PDWORD pBits;
  1589. //
  1590. // test whether mirroring should be enabled
  1591. //
  1592. if (pPDev->fMode2 & PF2_MIRRORING_ENABLED)
  1593. EnableMirroring(pPDev,pso);
  1594. //
  1595. // Decide whether to make OEM callback function
  1596. //
  1597. if (pRPDev->pfnOEMImageProcessing && !pPDev->bBanding)
  1598. {
  1599. if ((pBits = pSetupOEMImageProcessing(pPDev,pso)) == NULL)
  1600. return FALSE;
  1601. }
  1602. else
  1603. pBits = pso->pvBits;
  1604. //
  1605. // test whether unidrv is doing the dump
  1606. //
  1607. if (pRPDev->sDrvBPP)
  1608. {
  1609. if( pRPDev->pvRenderData != NULL )
  1610. {
  1611. // if we are not in banding mode we need to
  1612. // render the data for the entire page.
  1613. //
  1614. if (!pPDev->bBanding)
  1615. {
  1616. RenderData = *(RENDER *)(pRPDev->pvRenderData);
  1617. if( bRenderStartPage( pPDev ) )
  1618. {
  1619. #ifndef DISABLE_NEWRULES
  1620. OutputRules(pPDev);
  1621. #endif
  1622. bRender( pso, pPDev, &RenderData, pso->sizlBitmap, pBits );
  1623. ((RENDER *)(pRPDev->pvRenderData))->plrWhite = RenderData.plrWhite;
  1624. }
  1625. }
  1626. // now we clean up our structures in
  1627. // both banding and non-banding cases
  1628. //
  1629. bRenderPageEnd( pPDev );
  1630. }
  1631. }
  1632. return TRUE;
  1633. }
  1634. return FALSE;
  1635. }
  1636. //************************ Function Header ***********************************
  1637. BOOL
  1638. RMNextBand (
  1639. SURFOBJ *pso,
  1640. POINTL *pptl
  1641. )
  1642. /*++
  1643. Routine Description:
  1644. This function is called at DrvSendPage to allow the raster module
  1645. to output any raster data to the printer.
  1646. Arguments:
  1647. pso Pointer to SURFOBJ
  1648. Return Value:
  1649. TRUE for success and FALSE for failure
  1650. --*/
  1651. {
  1652. RASTERPDEV *pRPDev;
  1653. PDEV *pPDev; /* Access to all that is important */
  1654. pPDev = (PDEV *) pso->dhpdev;
  1655. pRPDev = pPDev->pRasterPDEV;
  1656. // only output if raster band or surface is dirty
  1657. // if not just return true
  1658. if (pPDev->fMode & PF_ENUM_GRXTXT)
  1659. {
  1660. PDWORD pBits;
  1661. //
  1662. // test whether mirroring should be enabled
  1663. //
  1664. if (pPDev->fMode2 & PF2_MIRRORING_ENABLED)
  1665. EnableMirroring(pPDev,pso);
  1666. //
  1667. // Decide whether to make OEM callback function
  1668. //
  1669. if (pRPDev->pfnOEMImageProcessing)
  1670. {
  1671. if ((pBits = pSetupOEMImageProcessing(pPDev,pso)) == NULL)
  1672. return FALSE;
  1673. }
  1674. else
  1675. pBits = pso->pvBits;
  1676. //
  1677. // test whether unidrv is doing the dump
  1678. //
  1679. if (pRPDev->sDrvBPP)
  1680. {
  1681. if( pRPDev->pvRenderData == NULL )
  1682. return FALSE;
  1683. //
  1684. // Reset palette data
  1685. //
  1686. if (pPDev->ePersonality == kPCLXL_RASTER && pPDev->pVectorPDEV)
  1687. {
  1688. PCLXLResetPalette((PDEVOBJ)pPDev);
  1689. }
  1690. #ifndef DISABLE_NEWRULES
  1691. OutputRules(pPDev);
  1692. #endif
  1693. if( !bRender( pso, pPDev, pRPDev->pvRenderDataTmp, pso->sizlBitmap, pBits ) )
  1694. {
  1695. if ( ((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite )
  1696. MemFree(((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite);
  1697. ((RENDER *)(pRPDev->pvRenderData))->plrWhite =
  1698. ((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite = NULL;
  1699. return(FALSE);
  1700. }
  1701. if ( ((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite )
  1702. MemFree(((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite);
  1703. ((RENDER *)(pRPDev->pvRenderData))->plrWhite =
  1704. ((RENDER *)(pRPDev->pvRenderDataTmp))->plrWhite = NULL;
  1705. }
  1706. }
  1707. return(TRUE);
  1708. }
  1709. //************************ Function Header ***********************************
  1710. BOOL
  1711. RMStartBanding (
  1712. SURFOBJ *pso,
  1713. POINTL *pptl
  1714. )
  1715. /*++
  1716. Routine Description:
  1717. Called to tell the driver to prepare for banding and return the
  1718. origin of the first band.
  1719. Arguments:
  1720. pso Pointer to SURFOBJ
  1721. Return Value:
  1722. TRUE for success and FALSE for failure
  1723. --*/
  1724. {
  1725. PDEV *pPDev; /* Access to all that is important */
  1726. RASTERPDEV *pRPDev; /* raster module PDEV */
  1727. pPDev = (PDEV *) pso->dhpdev;
  1728. pRPDev = pPDev->pRasterPDEV; /* For our convenience */
  1729. //
  1730. if (pRPDev->sDrvBPP)
  1731. {
  1732. if( pRPDev->pvRenderData == NULL )
  1733. return FALSE; /* Should not happen, nasty if it does */
  1734. if( !bRenderStartPage( pPDev ) )
  1735. return FALSE;
  1736. /* reset the render data for this band */
  1737. *(RENDER *)(pRPDev->pvRenderDataTmp) = *(RENDER *)(pRPDev->pvRenderData);
  1738. }
  1739. return(TRUE);
  1740. }
  1741. //************************ Function Header ***********************************
  1742. BOOL
  1743. RMResetPDEV (
  1744. PDEV *pPDevOld,
  1745. PDEV *pPDevNew
  1746. )
  1747. /*++
  1748. Routine Description:
  1749. Called when an application wishes to change the output style in the
  1750. midst of a job. Typically this would be to change from portrait to
  1751. landscape or vice versa. Any other sensible change is permitted.
  1752. Arguments:
  1753. pso Pointer to SURFOBJ
  1754. Return Value:
  1755. TRUE - device successfully reorganised
  1756. FALSE - unable to change - e.g. change of device name.
  1757. Note:
  1758. --*/
  1759. {
  1760. // as near as I can tell I don't need to do anything
  1761. // for the raster module.
  1762. return TRUE;
  1763. }
  1764. //************************ Function Header ***********************************
  1765. BOOL
  1766. RMEnableSurface (
  1767. PDEV *pPDev
  1768. )
  1769. /*++
  1770. Routine Description:
  1771. Arguments:
  1772. pso Pointer to SURFOBJ
  1773. Return Value:
  1774. TRUE for success and FALSE for failure
  1775. Note:
  1776. --*/
  1777. {
  1778. RASTERPDEV *pRPDev = pPDev->pRasterPDEV;
  1779. if (DRIVER_DEVICEMANAGED (pPDev)) // device surface
  1780. return TRUE;
  1781. //Initialize the RPDev Paldata.
  1782. ASSERT(pPDev->pPalData);
  1783. pRPDev->pPalData = pPDev->pPalData; /* For all the others! */
  1784. //
  1785. // initialize render parameters if we are doing
  1786. // the dump function
  1787. //
  1788. if (pRPDev->sDrvBPP)
  1789. {
  1790. ULONG iFormat;
  1791. // determine the bitmap format
  1792. switch (pRPDev->sDrvBPP)
  1793. {
  1794. case 1:
  1795. iFormat = BMF_1BPP;
  1796. break;
  1797. case 4:
  1798. iFormat = BMF_4BPP;
  1799. break;
  1800. case 8:
  1801. iFormat = BMF_8BPP;
  1802. break;
  1803. case 24:
  1804. iFormat = BMF_24BPP;
  1805. break;
  1806. default:
  1807. ERR(("Unknown sBitsPixel in RMEnableSurface"));
  1808. return FALSE;
  1809. }
  1810. // if these calls fail, control will call RMDisableSurface
  1811. //
  1812. if( !bSkipInit( pPDev ) || !bInitTrans( pPDev ) )
  1813. {
  1814. return FALSE;
  1815. }
  1816. /*
  1817. * Also initialise the rendering structures.
  1818. */
  1819. if( !bRenderInit( pPDev, pPDev->szBand, iFormat ) )
  1820. {
  1821. return FALSE;
  1822. }
  1823. }
  1824. return TRUE;
  1825. }
  1826. //************************ Function Header ***********************************
  1827. VOID
  1828. RMDisableSurface (
  1829. PDEV *pPDev
  1830. )
  1831. /*++
  1832. Routine Description:
  1833. This function is called at DrvDisableSurface to allow the raster module
  1834. to cleanup any required stuff usually generated at EnableSurface time.
  1835. Arguments:
  1836. pso Pointer to SURFOBJ
  1837. Return Value:
  1838. void
  1839. --*/
  1840. {
  1841. RASTERPDEV *pRPDev; /* Unidrive stuff */
  1842. pRPDev = pPDev->pRasterPDEV;
  1843. /*
  1844. * Free the rendering storage.
  1845. */
  1846. if (pRPDev->sDrvBPP)
  1847. {
  1848. vRenderFree( pPDev );
  1849. if( pRPDev->pdwTrans )
  1850. {
  1851. MemFree( pRPDev->pdwTrans );
  1852. pRPDev->pdwTrans = NULL;
  1853. }
  1854. if( pRPDev->pdwColrSep )
  1855. {
  1856. MemFree( pRPDev->pdwColrSep );
  1857. pRPDev->pdwColrSep = NULL;
  1858. }
  1859. if( pRPDev->pdwBitMask )
  1860. {
  1861. MemFree( pRPDev->pdwBitMask );
  1862. pRPDev->pdwBitMask = NULL;
  1863. }
  1864. }
  1865. }
  1866. //************************ Function Header ***********************************
  1867. VOID
  1868. RMDisablePDEV (
  1869. PDEV *pPDev
  1870. )
  1871. /*++
  1872. Routine Description:
  1873. Called when the engine has finished with this PDEV. Basically
  1874. we throw away all connections etc. then free the heap.
  1875. Arguments:
  1876. pPDev Pointer to PDEV
  1877. Return Value:
  1878. TRUE for success and FALSE for failure
  1879. --*/
  1880. {
  1881. RASTERPDEV *pRPDev = pPDev->pRasterPDEV;
  1882. /*
  1883. * Undo all that has been done with the PDEV. Basically this means
  1884. * freeing the memory we consumed.
  1885. */
  1886. // test for valid raster PDEV
  1887. if (pRPDev)
  1888. {
  1889. // Delete custom halftone pattern
  1890. if (pRPDev->pHalftonePattern)
  1891. MemFree(pRPDev->pHalftonePattern);
  1892. // Delete the raster module PDEV
  1893. MemFree(pRPDev);
  1894. }
  1895. //
  1896. // PCLXL raster mode
  1897. // Free XLRASTER
  1898. //
  1899. if (pPDev->ePersonality == kPCLXL_RASTER && pPDev->pVectorPDEV)
  1900. {
  1901. PCLXLFreeRaster((PDEVOBJ)pPDev);
  1902. }
  1903. return;
  1904. }
  1905. BOOL
  1906. RMInitDevicePal(
  1907. PDEV *pPDev,
  1908. PAL_DATA *pPal
  1909. )
  1910. /*++
  1911. Routine Description:
  1912. This function calculates a device palette to be download
  1913. to the printer for planar mode devices
  1914. Arguments:
  1915. pPDev - pointer to PDEV structure
  1916. pPal - pointer to PAL_DATA structure
  1917. Return Value:
  1918. --*/
  1919. {
  1920. int i,j;
  1921. int RMask,GMask,BMask;
  1922. ULONG *pPalette;
  1923. RASTERPDEV *pRPDev;
  1924. pRPDev = pPDev->pRasterPDEV;
  1925. if (pPal == NULL || pRPDev == NULL || pRPDev->sDevPlanes != 3
  1926. || pPal->wPalDev < 8 || (!(pPalette = pPal->pulDevPalCol)) )
  1927. {
  1928. ERR (("Unidrv!RMInitDevicePal: Invalid Parameters, pPal = %p, \
  1929. pRPDev = %p, pRPDev->sDevPlanes = %d,pPal->wPalDev = %d,\
  1930. pPalette = %p\n",pPal,pRPDev,pRPDev->sDevPlanes,pPal->wPalDev,\
  1931. pPalette));
  1932. return FALSE;
  1933. }
  1934. //
  1935. // Determine which bits map to which color
  1936. //
  1937. for (i = 0;i < 3;i++)
  1938. {
  1939. switch (pRPDev->rgbOrder[i])
  1940. {
  1941. case DC_PLANE_CYAN:
  1942. case DC_PLANE_RED:
  1943. RMask = 1 << i;
  1944. break;
  1945. case DC_PLANE_MAGENTA:
  1946. case DC_PLANE_GREEN:
  1947. GMask = 1 << i;
  1948. break;
  1949. case DC_PLANE_YELLOW:
  1950. case DC_PLANE_BLUE:
  1951. BMask = 1 << i;
  1952. break;
  1953. }
  1954. }
  1955. //
  1956. // create the palette entries
  1957. //
  1958. for (i = 0;i < 8;i++)
  1959. {
  1960. //
  1961. // if CMY mode complement index
  1962. //
  1963. if (pRPDev->fColorFormat & DC_PRIMARY_RGB)
  1964. j = i;
  1965. else
  1966. j = ~i;
  1967. pPalette[i] = RGB((j & RMask) ? 255 : 0,
  1968. (j & GMask) ? 255 : 0,
  1969. (j & BMask) ? 255 : 0);
  1970. }
  1971. return TRUE;
  1972. }