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.

716 lines
16 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. xlraster.cpp
  5. Abstract:
  6. Implementation of PCLXL raster mode
  7. Functions:
  8. PCLXLSetCursor
  9. PCLXLSendBitmap
  10. PCLXLFreeRaster
  11. PCLXLResetPalette
  12. Environment:
  13. Windows Whistler
  14. Revision History:
  15. 09/22/00
  16. Created it.
  17. --*/
  18. #include "lib.h"
  19. #include "gpd.h"
  20. #include "winres.h"
  21. #include "pdev.h"
  22. #include "common.h"
  23. #include "xlpdev.h"
  24. #include "pclxle.h"
  25. #include "pclxlcmd.h"
  26. #include "xldebug.h"
  27. #include "xlgstate.h"
  28. #include "xloutput.h"
  29. #include "xlbmpcvt.h"
  30. #include "pclxlcmn.h"
  31. #include "xlraster.h"
  32. //
  33. // XLRASTER data structure
  34. // The pointer is stored in pPDev->pVectorPDEV in case of kPCLXL_RASTER.
  35. //
  36. typedef struct _XLRASTER {
  37. XLOutput *pOutput;
  38. PBYTE pubDstBuff;
  39. DWORD dwDstBuffSize;
  40. PBYTE pubRLEBuff;
  41. DWORD dwRLEBuffSize;
  42. BOOL bSentPalette;
  43. } XLRASTER, *PXLRASTER;
  44. //
  45. // Local function prototypes
  46. //
  47. extern BOOL BFindWhetherColor(
  48. IN PDEV *pPDev);
  49. //
  50. // Functions
  51. //
  52. extern "C" HRESULT
  53. PCLXLSendBitmap(
  54. PDEVOBJ pdevobj,
  55. ULONG ulInputBPP,
  56. LONG lHeight,
  57. LONG lcbScanlineWidth,
  58. INT iLeft,
  59. INT iRight,
  60. PBYTE pbData,
  61. PDWORD pdwcbOut)
  62. /*++
  63. Routine Description:
  64. Send bitmap
  65. Arguments:
  66. pdevobj - a pointer to DEVOBJ
  67. ulInputBPP - input bits per pixel
  68. lHeight - height in pixel
  69. lcbScanlineWidth - scanline with in byte
  70. iLeft - left edge of scaline to print
  71. iRight - right edge of scanline to print
  72. pbData - a pointer to bitmap data
  73. pdwcbOut - a pointer to a DWORD buffer to store the size of written data
  74. Return Value:
  75. S_OK if succeeded. Otherwise S_FALSE or E_UNEXPECTED.
  76. Note:
  77. --*/
  78. {
  79. LONG lScanline, lWidth;
  80. ULONG ulOutputBPP;
  81. DWORD dwI, dwBufSize, dwLenNormal, dwLenRLE, dwcbLineSize, dwcbBmpSize;
  82. PDWORD pdwLen;
  83. PBYTE pubSrc, pBufNormal, pBufRLE, pBuf, pBmpSize;
  84. ColorMapping CMapping;
  85. XLOutput *pOutput;
  86. INT iBitmapFormat;
  87. OutputFormat OutputF;
  88. HRESULT hRet;
  89. //
  90. // Parameter varidation
  91. //
  92. if (NULL == pdevobj || NULL == pdwcbOut)
  93. {
  94. ERR(("PCLXLSendBitmap: Invalid parameters.\n"));
  95. return E_UNEXPECTED;
  96. }
  97. PXLRASTER pXLRaster = (PXLRASTER)(((PPDEV)pdevobj)->pVectorPDEV);
  98. //
  99. // Allocate XLRASTER
  100. // Will be freed in RMDisablePDEV.
  101. //
  102. if (NULL == pXLRaster)
  103. {
  104. pXLRaster = (PXLRASTER)MemAllocZ(sizeof(XLRASTER));
  105. ((PPDEV)pdevobj)->pVectorPDEV = (PVOID) pXLRaster;
  106. if (NULL == pXLRaster)
  107. {
  108. ERR(("PCLXLSendBitmap: Memory allocation failed.\n"));
  109. return E_UNEXPECTED;
  110. }
  111. pXLRaster->pOutput = new XLOutput;
  112. if (NULL == pXLRaster->pOutput)
  113. {
  114. ERR(("PCLXLSendBitmap: XLOutput initialization failed.\n"));
  115. return E_UNEXPECTED;
  116. }
  117. pOutput = pXLRaster->pOutput;
  118. pOutput->SetResolutionForBrush(((PPDEV)pdevobj)->ptGrxRes.x);
  119. ColorDepth CD;
  120. if (BFindWhetherColor((PDEV*)pdevobj))
  121. {
  122. if (((PDEV*)pdevobj)->pColorModeEx &&
  123. ((PDEV*)pdevobj)->pColorModeEx->dwPrinterBPP == 24)
  124. {
  125. CD = e24Bit;
  126. }
  127. else
  128. {
  129. CD = e8Bit;
  130. }
  131. }
  132. else
  133. {
  134. CD = e8Bit;
  135. }
  136. pOutput->SetDeviceColorDepth(CD);
  137. }
  138. else
  139. {
  140. pOutput = pXLRaster->pOutput;
  141. }
  142. //
  143. // Set source transparent mode
  144. //
  145. pOutput->SetPaintTxMode(eOpaque);
  146. pOutput->SetSourceTxMode(eOpaque);
  147. //
  148. // Get Output format and input format
  149. //
  150. iBitmapFormat = (INT)NumToBPP(ulInputBPP);
  151. DetermineOutputFormat(NULL, pOutput->GetDeviceColorDepth(), iBitmapFormat, &OutputF, &ulOutputBPP);
  152. //
  153. // DetermineOutputFormat check if pxlo is available. In this raster case,
  154. // pxlo is always NULL and it needs to use 1bpp output.
  155. //
  156. if (iBitmapFormat == e1bpp)
  157. {
  158. OutputF = eOutputPal;
  159. ulOutputBPP = 1;
  160. }
  161. //
  162. // Set CMapping.
  163. // Send palette for 1BPP halftone image for B&W printers.
  164. // Palette is sent per page for XL Raster mode.
  165. //
  166. if (ulOutputBPP == 1)
  167. {
  168. if (!pXLRaster->bSentPalette)
  169. {
  170. ColorDepth CDepth = e8Bit;
  171. //
  172. // Hardcoded black and white palette for XL RASTER.
  173. //
  174. DWORD adwColorTable[2] = {0x00ffffff, 0x0};
  175. pOutput->SetColorSpace(eGray);
  176. pOutput->SetPaletteDepth(CDepth);
  177. pOutput->SetPaletteData(CDepth, 2, adwColorTable);
  178. pOutput->Send_cmd(eSetColorSpace);
  179. pXLRaster->bSentPalette = TRUE;
  180. }
  181. //
  182. // Set index pixel (palette) for black and white printer
  183. //
  184. CMapping = eIndexedPixel;
  185. }
  186. else
  187. {
  188. //
  189. // Initialize pixel mapping.
  190. //
  191. CMapping = eDirectPixel;
  192. }
  193. //
  194. // Get height, width, and scanline size.
  195. //
  196. // The number of bytes in a scaline.
  197. //
  198. dwcbLineSize = lcbScanlineWidth;
  199. //
  200. // The number of pixel in a scanline
  201. // lWidth = lcbScanlineWidth / (ulInputBPP / 8);
  202. //
  203. lWidth = lcbScanlineWidth * 8 / ulInputBPP;
  204. //
  205. // Buffer size
  206. // The size of scaline has to be DWORD align.
  207. //
  208. // height x width + header + endimage
  209. // width has to be DWORD-aligned.
  210. //
  211. dwBufSize = lHeight * (((lWidth * ulOutputBPP + 31) >> 5 ) << 2) +
  212. DATALENGTH_HEADER_SIZE + sizeof(PCLXL_EndImage);
  213. //
  214. // BeginImage
  215. //
  216. pOutput->BeginImage(
  217. CMapping,
  218. ulOutputBPP,
  219. lWidth,
  220. lHeight,
  221. lWidth,
  222. lHeight);
  223. //
  224. // Normal and RLE destination bitmap buffer allocation.
  225. //
  226. // Check if the normal and RLE destination buffer is available and the size
  227. // is larger than required size. Otherwise, we can reused the buffer.
  228. //
  229. if (NULL == pXLRaster->pubDstBuff ||
  230. NULL == pXLRaster->pubRLEBuff ||
  231. pXLRaster->dwDstBuffSize < dwBufSize)
  232. {
  233. if (NULL != pXLRaster->pubDstBuff &&
  234. pXLRaster->dwDstBuffSize < dwBufSize)
  235. {
  236. MemFree(pXLRaster->pubDstBuff);
  237. pXLRaster->pubDstBuff = NULL;
  238. pXLRaster->dwDstBuffSize = 0;
  239. }
  240. if (NULL != pXLRaster->pubRLEBuff &&
  241. pXLRaster->dwRLEBuffSize < dwBufSize)
  242. {
  243. MemFree(pXLRaster->pubRLEBuff);
  244. pXLRaster->pubRLEBuff = NULL;
  245. pXLRaster->dwRLEBuffSize = 0;
  246. }
  247. if (NULL == (pBufNormal = (PBYTE)MemAllocZ(dwBufSize)))
  248. {
  249. ERR(("PCLXLSendBitmap: Memory allocation failed.\n"));
  250. pOutput->Delete();
  251. pXLRaster->dwDstBuffSize = 0;
  252. return E_UNEXPECTED;
  253. }
  254. else
  255. {
  256. pXLRaster->pubDstBuff = pBufNormal;
  257. pXLRaster->dwDstBuffSize = dwBufSize;
  258. }
  259. if (NULL == (pBufRLE = (PBYTE)MemAllocZ(dwBufSize)))
  260. {
  261. ERR(("PCLXLSendBitmap: Memory allocation failed.\n"));
  262. if (NULL != pBufNormal)
  263. {
  264. MemFree(pXLRaster->pubDstBuff);
  265. pXLRaster->pubDstBuff = NULL;
  266. }
  267. pOutput->Delete();
  268. pXLRaster->dwRLEBuffSize = 0;
  269. return E_UNEXPECTED;
  270. }
  271. else
  272. {
  273. pXLRaster->pubRLEBuff = pBufRLE;
  274. pXLRaster->dwRLEBuffSize = dwBufSize;
  275. }
  276. }
  277. else
  278. {
  279. pBufNormal = pXLRaster->pubDstBuff;
  280. pBufRLE = pXLRaster->pubRLEBuff;
  281. }
  282. //
  283. // Convert src bitmap to dst bitmap
  284. //
  285. CompressMode CMode;
  286. BMPConv BMPC;
  287. PBYTE pubDst;
  288. DWORD dwSize;
  289. //
  290. // Setup BMPConv
  291. //
  292. BMPC.BSetInputBPP((BPP)iBitmapFormat);
  293. BMPC.BSetOutputBPP(NumToBPP(ulOutputBPP));
  294. BMPC.BSetOutputBMPFormat(OutputF);
  295. //
  296. // Conversion.
  297. // Take two steps. No compression and RLE compression. At the end, compare
  298. // the size of buffers and decide which one we take.
  299. //
  300. #define NO_COMPRESSION 0
  301. #define RLE_COMPRESSION 1
  302. for (dwI = 0; dwI < 2; dwI ++)
  303. {
  304. if (NO_COMPRESSION == dwI)
  305. {
  306. VERBOSE(("PCLXLSendBitmap(): No-compres\n"));
  307. pBuf = pBufNormal;
  308. pdwLen = &dwLenNormal;
  309. CMode = eNoCompression;
  310. }
  311. else
  312. if (RLE_COMPRESSION == dwI)
  313. {
  314. VERBOSE(("PCLXLSendBitmap(): RLE-compres\n"));
  315. pBuf = pBufRLE;
  316. pdwLen = &dwLenRLE;
  317. CMode = eRLECompression;
  318. }
  319. lScanline = lHeight;
  320. hRet = S_OK;
  321. //
  322. // Set pubSrc
  323. //
  324. pubSrc = pbData;
  325. //
  326. // Set dataLength tag
  327. //
  328. *pBuf = PCLXL_dataLength;
  329. //
  330. // Get the pointer to the buffer where we store the size of data.
  331. //
  332. pBmpSize = pBuf + 1;
  333. pBuf += DATALENGTH_HEADER_SIZE;
  334. *pdwLen = DATALENGTH_HEADER_SIZE;
  335. //
  336. // Set compression flag in BMPConv
  337. //
  338. BMPC.BSetCompressionType(CMode);
  339. dwcbBmpSize = 0;
  340. //
  341. // Scaline base conversion
  342. //
  343. while (lScanline-- > 0 && dwcbBmpSize + *pdwLen < dwBufSize)
  344. {
  345. pubDst = BMPC.PubConvertBMP(pubSrc , dwcbLineSize);
  346. dwSize = BMPC.DwGetDstSize();
  347. VERBOSE(("PCLXLSendBitmap[0x%x]: dwDstSize=0x%x\n", lScanline, dwSize));
  348. if ( dwcbBmpSize +
  349. dwSize +
  350. DATALENGTH_HEADER_SIZE +
  351. sizeof(PCLXL_EndImage) > dwBufSize || NULL == pubDst)
  352. {
  353. VERBOSE(("PCLXLSendBitmap: Mode(%d) buffer size is too small.\n", dwI));
  354. hRet = E_UNEXPECTED;
  355. break;
  356. }
  357. memcpy(pBuf, pubDst, dwSize);
  358. dwcbBmpSize += dwSize;
  359. pBuf += dwSize;
  360. pubSrc += lcbScanlineWidth;
  361. }
  362. if (hRet == S_OK && lScanline > 0 || hRet != S_OK)
  363. {
  364. hRet = S_FALSE;
  365. VERBOSE(("ComonRopBlt: Mode(%d) conversion failed.\n", dwI));
  366. }
  367. if (hRet == S_OK)
  368. {
  369. if (dwI == NO_COMPRESSION)
  370. {
  371. //
  372. // Scanline on PCL-XL has to be DWORD align.
  373. //
  374. // count byte of scanline = lWidth * ulOutputBPP / 8
  375. //
  376. dwcbBmpSize = lHeight * (((lWidth * ulOutputBPP + 31) >> 5 ) << 2);
  377. }
  378. //
  379. // Set the size of bitmap
  380. //
  381. CopyMemory(pBmpSize, &dwcbBmpSize, sizeof(dwcbBmpSize));
  382. *pdwLen += dwcbBmpSize;
  383. //
  384. // Set endimage command
  385. //
  386. *pBuf = PCLXL_EndImage;
  387. (*pdwLen) ++;
  388. }
  389. else
  390. {
  391. //
  392. // Conversion failed!
  393. //
  394. *pdwLen = 0;
  395. }
  396. }
  397. #undef NO_COMPRESSION
  398. #undef RLE_COMPRESSION
  399. //
  400. // Compare which mode is smaller, RLE or non-compression.
  401. // Take smaller one.
  402. //
  403. DWORD dwBitmapSize;
  404. if (dwLenRLE != 0 && dwLenRLE < dwLenNormal)
  405. {
  406. VERBOSE(("PCLXLSendBitmap RLE: dwSize=0x%x\n", dwLenRLE));
  407. pBuf = pBufRLE;
  408. pdwLen = &dwLenRLE;
  409. CMode = eRLECompression;
  410. hRet = S_OK;
  411. }
  412. else if (dwLenNormal != 0)
  413. {
  414. VERBOSE(("PCLXLSendBitmap Normal: dwSize=0x%x\n", dwLenNormal));
  415. pBuf = pBufNormal;
  416. pdwLen = &dwLenNormal;
  417. CMode = eNoCompression;
  418. hRet = S_OK;
  419. }
  420. else
  421. {
  422. pBuf = NULL;
  423. pdwLen = NULL;
  424. CMode = eInvalidValue;
  425. hRet = E_FAIL;
  426. }
  427. if (pBuf)
  428. {
  429. //
  430. // ReadImage and send the bitmap.
  431. //
  432. pOutput->ReadImage(lHeight, CMode);
  433. pOutput->Flush(pdevobj);
  434. CopyMemory(&dwBitmapSize, pBuf + 1, sizeof(DWORD));
  435. if (dwBitmapSize > 0xff)
  436. {
  437. //
  438. // dataLength
  439. // size (uin32) (bitmap size)
  440. // DATA
  441. // EndImage
  442. //
  443. WriteSpoolBuf((PPDEV)pdevobj, pBuf, *pdwLen);
  444. }
  445. else
  446. {
  447. //
  448. // dataLength
  449. // size (byte) (bitmap size)
  450. // DATA
  451. // EndImage
  452. //
  453. pBuf += 3;
  454. *pBuf = PCLXL_dataLengthByte;
  455. *(pBuf + 1) = (BYTE)dwBitmapSize;
  456. WriteSpoolBuf((PPDEV)pdevobj, pBuf, (*pdwLen) - 3);
  457. }
  458. *pdwcbOut = *pdwLen;
  459. }
  460. else
  461. {
  462. pOutput->Delete();
  463. }
  464. return hRet;
  465. }
  466. extern "C" HRESULT
  467. PCLXLSetCursor(
  468. PDEVOBJ pdevobj,
  469. ULONG ulX,
  470. ULONG ulY)
  471. /*++
  472. Routine Description:
  473. Send cursor move command
  474. Arguments:
  475. pdevobj - a pointer to DEVOBJ
  476. ulX - X position
  477. ulY - Y position
  478. Return Value:
  479. S_OK if succeeded. Otherwise S_FALSE or E_UNEXPECTED.
  480. Note:
  481. --*/
  482. {
  483. //
  484. // Parameter varidation
  485. //
  486. if (NULL == pdevobj)
  487. {
  488. return E_UNEXPECTED;
  489. }
  490. PXLRASTER pXLRaster = (PXLRASTER)(((PPDEV)pdevobj)->pVectorPDEV);
  491. //
  492. // Allocate XLRASTER
  493. // Will be freed in RMDisablePDEV.
  494. //
  495. if (NULL == pXLRaster)
  496. {
  497. pXLRaster = (PXLRASTER)MemAllocZ(sizeof(XLRASTER));
  498. ((PPDEV)pdevobj)->pVectorPDEV = (PVOID) pXLRaster;
  499. if (NULL == pXLRaster)
  500. {
  501. return E_UNEXPECTED;
  502. }
  503. pXLRaster->pOutput = new XLOutput;
  504. if (NULL == pXLRaster->pOutput)
  505. {
  506. ERR(("PCLXLSendBitmap: XLOutput initialization failed.\n"));
  507. return E_UNEXPECTED;
  508. }
  509. pXLRaster->pOutput->SetResolutionForBrush(((PPDEV)pdevobj)->ptGrxRes.x);
  510. ColorDepth CD;
  511. if (BFindWhetherColor((PDEV*)pdevobj))
  512. {
  513. if (((PDEV*)pdevobj)->pColorModeEx &&
  514. ((PDEV*)pdevobj)->pColorModeEx->dwPrinterBPP == 24)
  515. {
  516. CD = e24Bit;
  517. }
  518. else
  519. {
  520. CD = e8Bit;
  521. }
  522. }
  523. else
  524. {
  525. CD = e8Bit;
  526. }
  527. pXLRaster->pOutput->SetDeviceColorDepth(CD);
  528. }
  529. //
  530. // Send cusor move command
  531. //
  532. return pXLRaster->pOutput->SetCursor(ulX, ulY);
  533. }
  534. extern "C" HRESULT
  535. PCLXLFreeRaster(
  536. PDEVOBJ pdevobj)
  537. /*++
  538. Routine Description:
  539. Free XLRASTER
  540. Arguments:
  541. pdevobj - a pointer to DEVOBJ
  542. Return Value:
  543. S_OK if succeeded. Otherwise S_FALSE or E_UNEXPECTED.
  544. Note:
  545. --*/
  546. {
  547. //
  548. // Parameter varidation
  549. //
  550. if (NULL == pdevobj)
  551. {
  552. return E_UNEXPECTED;
  553. }
  554. PXLRASTER pXLRaster = (PXLRASTER)(((PPDEV)pdevobj)->pVectorPDEV);
  555. if (pXLRaster->pubRLEBuff)
  556. {
  557. MemFree(pXLRaster->pubRLEBuff);
  558. pXLRaster->pubRLEBuff = NULL;
  559. }
  560. if (pXLRaster->pubDstBuff)
  561. {
  562. MemFree(pXLRaster->pubDstBuff);
  563. pXLRaster->pubDstBuff = NULL;
  564. }
  565. delete pXLRaster->pOutput;
  566. MemFree(pXLRaster);
  567. ((PPDEV)pdevobj)->pVectorPDEV = NULL;
  568. return S_OK;
  569. }
  570. extern "C" HRESULT
  571. PCLXLResetPalette(
  572. PDEVOBJ pdevobj)
  573. /*++
  574. Routine Description:
  575. Reset palette flag in XLRASTER
  576. Palette has to be set per page.
  577. Arguments:
  578. pdevobj - a pointer to DEVOBJ
  579. Return Value:
  580. S_OK if succeeded. Otherwise S_FALSE or E_UNEXPECTED.
  581. Note:
  582. --*/
  583. {
  584. //
  585. // Parameter varidation
  586. //
  587. if (NULL == pdevobj)
  588. {
  589. return E_UNEXPECTED;
  590. }
  591. PXLRASTER pXLRaster = (PXLRASTER)(((PPDEV)pdevobj)->pVectorPDEV);
  592. if (pXLRaster)
  593. {
  594. pXLRaster->bSentPalette = FALSE;
  595. return S_OK;
  596. }
  597. else
  598. {
  599. return S_FALSE;
  600. }
  601. }