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.

2995 lines
77 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. xlddi.cpp
  5. Abstract:
  6. Implementation of PCLXL drawing DDI entry points
  7. Functions:
  8. PCLXLBitBlt
  9. PCLXLStretchBlt
  10. PCLXLStretchBltROP
  11. PCLXLCopyBits
  12. PCLXLPlgBlt
  13. PCLXLAlphaBlend
  14. PCLXLGradientFill
  15. PCLXLTextOut
  16. PCLXLStrokePath
  17. PCLXLFillPath
  18. PCLXLStrokeAndFillPath
  19. PCLXLRealizeBrush
  20. PCLXLStartPage
  21. PCLXLSendPage
  22. PCLXLEscape
  23. PCLXLStartDcc
  24. PCLXLEndDoc
  25. Environment:
  26. Windows XP/Windows Server 2003 family.
  27. Revision History:
  28. 08/23/99
  29. Created it.
  30. --*/
  31. #include "lib.h"
  32. #include "gpd.h"
  33. #include "winres.h"
  34. #include "pdev.h"
  35. #include "common.h"
  36. #include "xlpdev.h"
  37. #include "pclxle.h"
  38. #include "pclxlcmd.h"
  39. #include "xldebug.h"
  40. #include "xlbmpcvt.h"
  41. #include "xlgstate.h"
  42. #include "xloutput.h"
  43. #include "pclxlcmd.h"
  44. #include "pclxlcmn.h"
  45. #include "xltt.h"
  46. ////////////////////////////////////////////////////////////////////////////////
  47. //
  48. // Globals
  49. //
  50. extern const LINEATTRS *pgLineAttrs;
  51. ////////////////////////////////////////////////////////////////////////////////
  52. //
  53. // Local function prototypes
  54. //
  55. HRESULT
  56. CommonRopBlt(
  57. IN PDEVOBJ pdevobj,
  58. IN SURFOBJ *psoSrc,
  59. IN CLIPOBJ *pco,
  60. IN XLATEOBJ *pxlo,
  61. IN BRUSHOBJ *pbo,
  62. IN RECTL *prclSrc,
  63. IN RECTL *prclDst,
  64. IN POINTL *pptlBrush,
  65. IN ROP4 rop4);
  66. BOOL
  67. BSendReadImageData(
  68. IN PDEVOBJ pdevobj,
  69. IN CompressMode CMode,
  70. IN PBYTE pBuf,
  71. IN LONG lStart,
  72. IN LONG lHeight,
  73. IN DWORD dwcbSize);
  74. PDWORD
  75. PdwChangeTransparentPalette(
  76. ULONG iTransColor,
  77. PDWORD pdwColorTable,
  78. DWORD dwEntries);
  79. HRESULT hrChangePixelColorInScanLine(
  80. IN PBYTE pubSrc,
  81. IN ULONG ulBPP,
  82. IN ULONG ulNumPixels,
  83. IN ULONG ulTransColor,
  84. IN OUT PBYTE pubChanged,
  85. IN ULONG ulNumBytes);
  86. extern "C" BOOL
  87. CreateMaskSurface(
  88. SURFOBJ *psoSrc,
  89. SURFOBJ *psoMsk,
  90. ULONG iTransColor);
  91. extern "C" SURFOBJ *
  92. CreateBitmapSURFOBJ(
  93. PDEV *pPDev,
  94. HBITMAP *phBmp,
  95. LONG cxSize,
  96. LONG cySize,
  97. DWORD Format);
  98. ////////////////////////////////////////////////////////////////////////////////
  99. //
  100. // Drawing DDI entries
  101. //
  102. extern "C" BOOL APIENTRY
  103. PCLXLBitBlt(
  104. SURFOBJ *psoTrg,
  105. SURFOBJ *psoSrc,
  106. SURFOBJ *psoMask,
  107. CLIPOBJ *pco,
  108. XLATEOBJ *pxlo,
  109. RECTL *prclTrg,
  110. POINTL *pptlSrc,
  111. POINTL *pptlMask,
  112. BRUSHOBJ *pbo,
  113. POINTL *pptlBrush,
  114. ROP4 rop4)
  115. /*++
  116. Routine Description:
  117. Implementation of DDI entry point DrvBitBlt.
  118. Please refer to DDK documentation for more details.
  119. Arguments:
  120. psoTrg - Describes the target surface
  121. psoSrc - Describes the source surface
  122. psoMask - Describes the mask for rop4
  123. pco - Limits the area to be modified
  124. pxlo - Specifies how color indices are translated between the source
  125. and target surfaces
  126. prclTrg - Defines the area to be modified
  127. pptlSrc - Defines the upper left corner of the source rectangle
  128. pptlMask - Defines which pixel in the mask corresponds
  129. to the upper left corner of the source rectangle
  130. pbo - Defines the pattern for bitblt
  131. pptlBrush - Defines the origin of the brush in the Dstination surface
  132. rop4 - ROP code that defines how the mask, pattern, source, and
  133. Dstination pixels are combined to write to the Dstination surface
  134. Return Value:
  135. TRUE if successful, FALSE if there is an error
  136. --*/
  137. {
  138. PDEVOBJ pdevobj = (PDEVOBJ)psoTrg->dhpdev;
  139. PXLPDEV pxlpdev;
  140. VERBOSE(("PCLXLBitBlt() entry.\n"));
  141. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  142. {
  143. RECTL rclSrc;
  144. //
  145. // create prclSrc (source rectangle)
  146. //
  147. if (pptlSrc)
  148. {
  149. rclSrc.left = pptlSrc->x;
  150. rclSrc.top = pptlSrc->y;
  151. rclSrc.right = pptlSrc->x + RECT_WIDTH(prclTrg);
  152. rclSrc.bottom = pptlSrc->y + RECT_HEIGHT(prclTrg);
  153. }
  154. else
  155. {
  156. rclSrc.left = 0;
  157. rclSrc.top = 0;
  158. rclSrc.right = RECT_WIDTH(prclTrg);
  159. rclSrc.bottom = RECT_HEIGHT(prclTrg);
  160. }
  161. if (S_OK == CommonRopBlt(pdevobj, psoSrc, pco, pxlo, pbo, &rclSrc, prclTrg, pptlBrush, rop4))
  162. return TRUE;
  163. else
  164. return FALSE;
  165. }
  166. }
  167. extern "C" BOOL APIENTRY
  168. PCLXLStretchBlt(
  169. SURFOBJ *psoDst,
  170. SURFOBJ *psoSrc,
  171. SURFOBJ *psoMask,
  172. CLIPOBJ *pco,
  173. XLATEOBJ *pxlo,
  174. COLORADJUSTMENT *pca,
  175. POINTL *pptlHTOrg,
  176. RECTL *prclDst,
  177. RECTL *prclSrc,
  178. POINTL *pptlMask,
  179. ULONG iMode)
  180. /*++
  181. Routine Description:
  182. Implementation of DDI entry point DrvStretchBlt.
  183. Please refer to DDK documentation for more details.
  184. Arguments:
  185. psoDst - Defines the surface on which to draw
  186. psoSrc - Defines the source for blt operation
  187. psoMask - Defines a surface that provides a mask for the source
  188. pco - Limits the area to be modified on the Dstination
  189. pxlo - Specifies how color dwIndexes are to be translated
  190. between the source and target surfaces
  191. pca - Defines color adjustment values to be applied to the source bitmap
  192. pptlHTOrg - Specifies the origin of the halftone brush
  193. prclDst - Defines the area to be modified on the Dstination surface
  194. prclSrc - Defines the area to be copied from the source surface
  195. pptlMask - Specifies which pixel in the given mask corresponds to
  196. the upper left pixel in the source rectangle
  197. iMode - Specifies how source pixels are combined to get output pixels
  198. Return Value:
  199. TRUE if successful, FALSE if there is an error
  200. --*/
  201. {
  202. PDEVOBJ pdevobj = (PDEVOBJ)psoDst->dhpdev;
  203. PXLPDEV pxlpdev;
  204. VERBOSE(("PCLXLStretchBlt() entry.\n"));
  205. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  206. if (S_OK == CommonRopBlt(pdevobj, psoSrc, pco, pxlo, NULL, prclSrc, prclDst, NULL, 0xCC))
  207. return TRUE;
  208. else
  209. return FALSE;
  210. }
  211. extern "C" BOOL APIENTRY
  212. PCLXLStretchBltROP(
  213. SURFOBJ *psoDst,
  214. SURFOBJ *psoSrc,
  215. SURFOBJ *psoMask,
  216. CLIPOBJ *pco,
  217. XLATEOBJ *pxlo,
  218. COLORADJUSTMENT *pca,
  219. POINTL *pptlHTOrg,
  220. RECTL *prclDst,
  221. RECTL *prclSrc,
  222. POINTL *pptlMask,
  223. ULONG iMode,
  224. BRUSHOBJ *pbo,
  225. ROP4 rop4)
  226. /*++
  227. Routine Description:
  228. Implementation of DDI entry point DrvStretchBltROP.
  229. Please refer to DDK documentation for more details.
  230. Arguments:
  231. psoDst - Specifies the target surface
  232. psoSrc - Specifies the source surface
  233. psoMask - Specifies the mask surface
  234. pco - Limits the area to be modified
  235. pxlo - Specifies how color indices are translated
  236. between the source and target surfaces
  237. pca - Defines color adjustment values to be applied to the source bitmap
  238. prclHTOrg - Specifies the halftone origin
  239. prclDst - Area to be modified on the destination surface
  240. prclSrc - Rectangle area on the source surface
  241. prclMask - Rectangle area on the mask surface
  242. pptlMask - Defines which pixel in the mask corresponds to
  243. the upper left corner of the source rectangle
  244. iMode - Specifies how source pixels are combined to get output pixels
  245. pbo - Defines the pattern for bitblt
  246. rop4 - ROP code that defines how the mask, pattern, source, and
  247. destination pixels are combined on the destination surface
  248. Return Value:
  249. TRUE if successful, FALSE if there is an error
  250. --*/
  251. {
  252. PDEVOBJ pdevobj = (PDEVOBJ)psoDst->dhpdev;
  253. PXLPDEV pxlpdev;
  254. VERBOSE(("PCLXLStretchBltROP() entry.\n"));
  255. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  256. if (S_OK == CommonRopBlt(pdevobj, psoSrc, pco, pxlo, pbo, prclSrc, prclDst, NULL, rop4))
  257. return TRUE;
  258. else
  259. return FALSE;
  260. }
  261. extern "C" BOOL APIENTRY
  262. PCLXLCopyBits(
  263. SURFOBJ *psoDst,
  264. SURFOBJ *psoSrc,
  265. CLIPOBJ *pco,
  266. XLATEOBJ *pxlo,
  267. RECTL *prclDst,
  268. POINTL *pptlSrc)
  269. /*++
  270. Routine Description:
  271. Implementation of DDI entry point DrvCopyBits.
  272. Please refer to DDK documentation for more details.
  273. Arguments:
  274. psoDst - Points to the Dstination surface
  275. psoSrc - Points to the source surface
  276. pxlo - XLATEOBJ provided by the engine
  277. pco - Defines a clipping region on the Dstination surface
  278. pxlo - Defines the translation of color indices
  279. between the source and target surfaces
  280. prclDst - Defines the area to be modified
  281. pptlSrc - Defines the upper-left corner of the source rectangle
  282. Return Value:
  283. TRUE if successful, FALSE if there is an error
  284. --*/
  285. {
  286. PDEVOBJ pdevobj = (PDEVOBJ)psoDst->dhpdev;
  287. PXLPDEV pxlpdev;
  288. RECTL rclSrc;
  289. VERBOSE(("PCLXLCopyBits() entry.\n"));
  290. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  291. //
  292. // create prclSrc (source rectangle)
  293. //
  294. rclSrc.top = pptlSrc->y;
  295. rclSrc.left = pptlSrc->x;
  296. rclSrc.bottom = pptlSrc->y + RECT_HEIGHT(prclDst);
  297. rclSrc.right = pptlSrc->x + RECT_WIDTH(prclDst);
  298. if (S_OK == CommonRopBlt(pdevobj, psoSrc, pco, pxlo, NULL, &rclSrc, prclDst, NULL, 0xCC))
  299. return TRUE;
  300. else
  301. return FALSE;
  302. }
  303. extern "C" BOOL APIENTRY
  304. PCLXLPlgBlt(
  305. SURFOBJ *psoDst,
  306. SURFOBJ *psoSrc,
  307. SURFOBJ *psoMask,
  308. CLIPOBJ *pco,
  309. XLATEOBJ *pxlo,
  310. COLORADJUSTMENT *pca,
  311. POINTL *pptlBrushOrg,
  312. POINTFIX *pptfixDst,
  313. RECTL *prclSrc,
  314. POINTL *pptlMask,
  315. ULONG iMode)
  316. /*++
  317. Routine Description:
  318. Implementation of DDI entry point DrvPlgBlt.
  319. Please refer to DDK documentation for more details.
  320. Arguments:
  321. psoDst - Defines the surface on which to draw
  322. psoSrc - Defines the source for blt operation
  323. psoMask - Defines a surface that provides a mask for the source
  324. pco - Limits the area to be modified on the Dstination
  325. pxlo - Specifies how color dwIndexes are to be translated
  326. between the source and target surfaces
  327. pca - Defines color adjustment values to be applied to the source bitmap
  328. pptlBrushOrg - Specifies the origin of the halftone brush
  329. ppfixDest - Defines the area to be modified on the Dstination surface
  330. prclSrc - Defines the area to be copied from the source surface
  331. pptlMask - Specifies which pixel in the given mask corresponds to
  332. the upper left pixel in the source rectangle
  333. iMode - Specifies how source pixels are combined to get output pixels
  334. Return Value:
  335. TRUE if successful, FALSE if there is an error
  336. --*/
  337. {
  338. VERBOSE(("PCLXLBltBlt() entry.\n"));
  339. return EngPlgBlt(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlBrushOrg,
  340. pptfixDst, prclSrc, pptlMask, iMode);
  341. }
  342. extern "C" BOOL APIENTRY
  343. PCLXLAlphaBlend(
  344. SURFOBJ *psoDst,
  345. SURFOBJ *psoSrc,
  346. CLIPOBJ *pco,
  347. XLATEOBJ *pxlo,
  348. RECTL *prclDst,
  349. RECTL *prclSrc,
  350. BLENDOBJ *pBlendObj)
  351. /*++
  352. Routine Description:
  353. Arguments:
  354. Return Value:
  355. Note:
  356. --*/
  357. {
  358. VERBOSE(("PCLXLAlphaBlend() entry.\n"));
  359. PDEV *pPDev = (PDEV*)psoDst->dhpdev;
  360. BOOL bRet;
  361. if (NULL == pPDev)
  362. {
  363. return FALSE;
  364. }
  365. pPDev->fMode2 |= PF2_WHITEN_SURFACE;
  366. bRet = EngAlphaBlend(psoDst,
  367. psoSrc,
  368. pco,
  369. pxlo,
  370. prclDst,
  371. prclSrc,
  372. pBlendObj);
  373. pPDev->fMode2 &= ~(PF2_WHITEN_SURFACE|PF2_SURFACE_WHITENED);
  374. return bRet;
  375. }
  376. extern "C" BOOL APIENTRY
  377. PCLXLGradientFill(
  378. SURFOBJ *psoDst,
  379. CLIPOBJ *pco,
  380. XLATEOBJ *pxlo,
  381. TRIVERTEX *pVertex,
  382. ULONG nVertex,
  383. PVOID pMesh,
  384. ULONG nMesh,
  385. RECTL *prclExtents,
  386. POINTL *pptlDitherOrg,
  387. ULONG ulMode)
  388. /*++
  389. Routine Description:
  390. Arguments:
  391. Return Value:
  392. Note:
  393. --*/
  394. {
  395. VERBOSE(("PCLXLGradientFill() entry.\n"));
  396. PDEV *pPDev = (PDEV*) psoDst->dhpdev;
  397. BOOL bRet;
  398. if (NULL == pPDev)
  399. {
  400. return FALSE;
  401. }
  402. if (ulMode == GRADIENT_FILL_TRIANGLE)
  403. {
  404. pPDev->fMode2 |= PF2_WHITEN_SURFACE;
  405. }
  406. bRet = EngGradientFill(psoDst,
  407. pco,
  408. pxlo,
  409. pVertex,
  410. nVertex,
  411. pMesh,
  412. nMesh,
  413. prclExtents,
  414. pptlDitherOrg,
  415. ulMode);
  416. pPDev->fMode2 &= ~(PF2_WHITEN_SURFACE|PF2_SURFACE_WHITENED);
  417. return bRet;
  418. }
  419. extern "C" BOOL APIENTRY
  420. PCLXLTransparentBlt(
  421. SURFOBJ *psoDst,
  422. SURFOBJ *psoSrc,
  423. CLIPOBJ *pco,
  424. XLATEOBJ *pxlo,
  425. RECTL *prclDst,
  426. RECTL *prclSrc,
  427. ULONG iTransColor,
  428. ULONG ulReserved)
  429. {
  430. PDEVOBJ pdevobj = (PDEVOBJ) psoDst->dhpdev;
  431. PDEV *pPDev = (PDEV*) psoDst->dhpdev;
  432. PXLPDEV pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  433. HRESULT hr = E_FAIL;
  434. ULONG ulXlate[2] = {0x0, RGB_WHITE}; //2 colors in psoMsk. Black and White.
  435. XLATEOBJ xlo;
  436. ZeroMemory ( &xlo, sizeof (XLATEOBJ) );
  437. xlo.cEntries = 2;
  438. xlo.pulXlate = (PULONG)ulXlate;
  439. xlo.flXlate = XO_TABLE; // use the entries in pulXlate table.
  440. if ( NULL == pxlpdev ||
  441. NULL == psoSrc )
  442. {
  443. return FALSE;
  444. }
  445. //
  446. // Step 1. Create a mask and download it to printer using ROP DSO (238 = 0xEE).
  447. // The mask is a 1bpp image created out of the image in psoSrc. Wherever
  448. // the TransColor is present
  449. // in the image, the corresponding pixel in the mask gets value 0. At all other places
  450. // the pixel will get value of 1.
  451. // if we copy the mask to a color printer (using ROP of SRC_COPY),
  452. // you will notice that the image is black and white,
  453. // and black is present on the same place where the Transparent Color should be there.
  454. // Instead of SRC_COPY if we use rop=238 which is (SOURCE | DESTINATION), the white color
  455. // of the mask will get OR'ed with destinaion and the region becomes white. The black
  456. // color
  457. // of the mask will not be printed and instead whatever is there already on the sheet
  458. // (if something is present) will be visible
  459. // Assuming x is the pixel already present on the sheet.
  460. // 0 | x = x (ORing anything with 0 is anything)
  461. // 1 | x = 1
  462. // 1 represents white color (RGB_WHITE = 0xFFFFFF = all 1s).
  463. //
  464. // Step 2.
  465. // In the image, wherever the TransColor is present, change it to white.
  466. // Now the image has 2 kinds of white colors. Those that
  467. // are originally present in the image, and those that we just put in there.
  468. // Step 3.
  469. // Download the image with rop DSAnd (=136 = 0x88).
  470. // Assuming x is the pixel already present on the sheet
  471. // and y be the pixel in the image and 1 represents white color
  472. // (RGB_WHITE = 0xFFFFFF = all 1s).
  473. // 1 & y = y Image falling on the area that we whited in step 1.
  474. // 1 & x = x The white parts of the image (that was earlier TransColor) falling in
  475. // the area.
  476. // that is supposed to be visible from under the image.
  477. //
  478. //
  479. //
  480. // Step 1 Create appropriate mask.
  481. // For images that are greater than 1bpp
  482. // Use unidrv's CreateMaskSurface to create mask. The logic of a mask surface
  483. // is explained above.
  484. // For images that are 1bpp
  485. // CreateMaskSurface does not create mask for 1bpp image. So for that we'll
  486. // create mask ourselves. Since mask is 1bpp and so is the image, we can simply
  487. // use the image as the mask, except that we might need to manipulate the palette.
  488. // The benefit here is that we are using the same image as mask, instead of
  489. // creating a new image and using memory.
  490. //
  491. if ( BMF_1BPP == psoSrc->iBitmapFormat )
  492. {
  493. //
  494. // For paletted images (1bpp images have palette), iTransColor is actually the index into
  495. // the palette, and not the actual RGB color itself.
  496. // As explained above, the transparent color should be black in the mask, while the
  497. // non-transparent color should be white. Black is
  498. // index 0 in xlo.pulXlate = (PULONG)ulXlate. So if TransColor is 0, then
  499. // we can simply use the xlo that we created above.
  500. // If not, we need to switch black and white in the palette.
  501. // (To repeat. While sending the mask, iTransColor should be sent as black and
  502. // the color that is to be printed should be sent as white).
  503. //
  504. if ( 0 != iTransColor )
  505. {
  506. //
  507. // Reverse Colors.
  508. //
  509. ulXlate[0] = RGB_WHITE;
  510. ulXlate[1] = RGB_BLACK;
  511. }
  512. hr = CommonRopBlt(pdevobj, psoSrc, pco, &xlo, NULL, prclSrc, prclDst, NULL, 0xEE);
  513. }
  514. else
  515. {
  516. SURFOBJ *psoMsk = NULL;
  517. HBITMAP hBmpMsk = NULL;
  518. if (psoMsk = CreateBitmapSURFOBJ(pPDev,
  519. &hBmpMsk,
  520. psoSrc->sizlBitmap.cx,
  521. psoSrc->sizlBitmap.cy,
  522. BMF_1BPP) )
  523. {
  524. if ( CreateMaskSurface(psoSrc,psoMsk,iTransColor) )
  525. {
  526. hr = CommonRopBlt(pdevobj, psoMsk, pco, &xlo, NULL, prclSrc, prclDst, NULL, 0xEE);
  527. }
  528. }
  529. //
  530. // Release allocated objects.
  531. //
  532. if ( psoMsk )
  533. {
  534. EngUnlockSurface(psoMsk);
  535. psoMsk = NULL;
  536. }
  537. if (hBmpMsk)
  538. {
  539. EngDeleteSurface((HSURF)hBmpMsk);
  540. hBmpMsk = NULL;
  541. }
  542. }
  543. if ( FAILED (hr) )
  544. {
  545. ERR(("PCLXLTransparentBlt: Mask could not be created or rendered.\n"));
  546. goto Cleanup;
  547. }
  548. //
  549. // Step 2 and 3.
  550. // Set the flags and call CommonRopBlt. CommonRopBlt is the function that
  551. // dumps images to printer. CommonRopBlt will look at the
  552. // flags and know that for this image, it has to replace
  553. // the colored pixels with White
  554. //
  555. pxlpdev->dwFlags |= XLPDEV_FLAGS_SUBST_TRNCOLOR_WITH_WHITE;
  556. pxlpdev->ulTransColor = iTransColor;
  557. //
  558. // ROP is DSAnd = 136 = 0x88.
  559. //
  560. hr = CommonRopBlt(pdevobj, psoSrc, pco, pxlo, NULL, prclSrc, prclDst, NULL, 136);
  561. pxlpdev->ulTransColor = 0;
  562. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_SUBST_TRNCOLOR_WITH_WHITE;
  563. Cleanup:
  564. if ( SUCCEEDED (hr) )
  565. {
  566. return TRUE;
  567. }
  568. return FALSE;
  569. }
  570. extern "C" BOOL APIENTRY
  571. PCLXLTextOut(
  572. SURFOBJ *pso,
  573. STROBJ *pstro,
  574. FONTOBJ *pfo,
  575. CLIPOBJ *pco,
  576. RECTL *prclExtra,
  577. RECTL *prclOpaque,
  578. BRUSHOBJ *pboFore,
  579. BRUSHOBJ *pboOpaque,
  580. POINTL *pptlOrg,
  581. MIX mix)
  582. /*++
  583. Routine Description:
  584. Arguments:
  585. Return Value:
  586. Note:
  587. --*/
  588. {
  589. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  590. VERBOSE(("PCLXLTextOut() entry.\n"));
  591. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  592. XLOutput *pOutput = pxlpdev->pOutput;
  593. //
  594. // Clip
  595. //
  596. if (!SUCCEEDED(pOutput->SetClip(pco)))
  597. return FALSE;
  598. ROP4 rop = GET_FOREGROUND_ROP3(UlVectMixToRop4(mix));
  599. if (!ROP3_NEED_SOURCE(rop))
  600. rop = 0x00fc;
  601. //
  602. // Set ROP and TxMode.
  603. // Send NewPath to flush memory.
  604. //
  605. pOutput->SetROP3(rop);
  606. pOutput->Send_cmd(eNewPath);
  607. pOutput->SetPaintTxMode(eOpaque);
  608. pOutput->SetSourceTxMode(eOpaque);
  609. //
  610. // Opaque Rectangle
  611. //
  612. if (prclOpaque)
  613. {
  614. pOutput->SetPenColor(NULL, NULL);
  615. pOutput->SetBrush(pboOpaque, pptlOrg);
  616. pOutput->Send_cmd(eNewPath);
  617. pOutput->RectanglePath(prclOpaque);
  618. pOutput->Paint();
  619. }
  620. //
  621. // Draw underline, strikeout, etc.
  622. //
  623. if (prclExtra)
  624. {
  625. pOutput->SetPenColor(NULL, NULL);
  626. pOutput->SetBrush(pboFore, pptlOrg);
  627. pOutput->Send_cmd(eNewPath);
  628. while(NULL != prclExtra)
  629. {
  630. pOutput->RectanglePath(prclExtra++);
  631. }
  632. pOutput->Paint();
  633. }
  634. //
  635. // Text Color
  636. //
  637. pOutput->SetBrush(pboFore, pptlOrg);
  638. pOutput->Flush(pdevobj);
  639. //
  640. // Device font/TrueType download
  641. //
  642. DrvTextOut(
  643. pso,
  644. pstro,
  645. pfo,
  646. pco,
  647. prclExtra,
  648. prclOpaque,
  649. pboFore,
  650. pboOpaque,
  651. pptlOrg,
  652. mix);
  653. //
  654. // Bug reported by HP.
  655. // Plug-in could have command callback and DrvStartPage sets plug-in's
  656. // pdev in pdevOEM.
  657. // Need to reset it.
  658. //
  659. ((PPDEV)pdevobj)->devobj.pdevOEM = ((PPDEV)pdevobj)->pVectorPDEV;
  660. //
  661. // Flush cached text before changing font
  662. //
  663. FlushCachedText(pdevobj);
  664. //
  665. // Reset text angle
  666. //
  667. pxlpdev->dwTextAngle = 0;
  668. //
  669. // Close TrueType font
  670. //
  671. pxlpdev->pTTFile->CloseTTFile();
  672. return TRUE;
  673. }
  674. extern "C" BOOL APIENTRY
  675. PCLXLLineTo(
  676. SURFOBJ *pso,
  677. CLIPOBJ *pco,
  678. BRUSHOBJ *pbo,
  679. LONG x1,
  680. LONG y1,
  681. LONG x2,
  682. LONG y2,
  683. RECTL *prclBounds,
  684. MIX mix)
  685. /*++
  686. Routine Description:
  687. Arguments:
  688. Return Value:
  689. Note:
  690. --*/
  691. {
  692. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  693. PXLPDEV pxlpdev;
  694. POINTFIX Pointfix;
  695. LINEATTRS lineattrs;
  696. VERBOSE(("PCLXLLineTo() entry.\n"));
  697. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  698. Pointfix.x = x2 << 4;
  699. Pointfix.y = y2 << 4;
  700. lineattrs = *pgLineAttrs;
  701. lineattrs.elWidth.e = FLOATL_IEEE_1_0F;
  702. ROP4 rop = GET_FOREGROUND_ROP3(UlVectMixToRop4(mix));
  703. TxMode TxModeValue;
  704. //
  705. // Quick return in the case of AA (destination).
  706. //
  707. if (rop == 0xAA)
  708. {
  709. return TRUE;
  710. }
  711. //
  712. // If there is any Pattern involved, set TxMode to Opaque.
  713. //
  714. if (ROP3_NEED_PATTERN(rop))
  715. {
  716. TxModeValue = eOpaque;
  717. }
  718. else
  719. {
  720. TxModeValue = eTransparent;
  721. }
  722. BOOL bRet;
  723. XLOutput *pOutput = pxlpdev->pOutput;
  724. if (S_OK == pOutput->SetClip(pco) &&
  725. S_OK == pOutput->SetROP3(rop) &&
  726. S_OK == pOutput->SetPaintTxMode(TxModeValue) &&
  727. S_OK == pOutput->SetSourceTxMode(TxModeValue) &&
  728. S_OK == pOutput->SetPen(&lineattrs, NULL) &&
  729. S_OK == pOutput->SetPenColor(pbo, NULL) &&
  730. S_OK == pOutput->SetBrush(NULL, NULL) &&
  731. S_OK == pOutput->Send_cmd(eNewPath) &&
  732. S_OK == pOutput->SetCursor(x1, y1) &&
  733. S_OK == pOutput->LinePath(&Pointfix, 1) &&
  734. S_OK == pOutput->Paint() &&
  735. S_OK == pOutput->Flush(pdevobj))
  736. bRet = TRUE;
  737. else
  738. {
  739. pOutput->Delete();
  740. bRet = FALSE;
  741. }
  742. return bRet;
  743. }
  744. extern "C" BOOL APIENTRY
  745. PCLXLStrokePath(
  746. SURFOBJ *pso,
  747. PATHOBJ *ppo,
  748. CLIPOBJ *pco,
  749. XFORMOBJ *pxo,
  750. BRUSHOBJ *pbo,
  751. POINTL *pptlBrushOrg,
  752. LINEATTRS *plineattrs,
  753. MIX mix)
  754. /*++
  755. Routine Description:
  756. Arguments:
  757. Return Value:
  758. Note:
  759. --*/
  760. {
  761. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  762. PXLPDEV pxlpdev;
  763. TxMode TxModeValue;
  764. VERBOSE(("PCLXLStokePath() entry.\n"));
  765. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  766. BOOL bRet;
  767. XLOutput *pOutput = pxlpdev->pOutput;
  768. ROP4 rop = GET_FOREGROUND_ROP3(UlVectMixToRop4(mix));
  769. //
  770. // Quick return in the case of AA (destination).
  771. //
  772. if (rop == 0xAA)
  773. {
  774. return TRUE;
  775. }
  776. //
  777. // If there is any Pattern involved, set TxMode to Opaque.
  778. //
  779. if (ROP3_NEED_PATTERN(rop))
  780. {
  781. TxModeValue = eOpaque;
  782. }
  783. else
  784. {
  785. TxModeValue = eTransparent;
  786. }
  787. if (S_OK == pOutput->SetClip(pco) &&
  788. S_OK == pOutput->SetROP3(rop) &&
  789. S_OK == pOutput->SetPaintTxMode(TxModeValue) &&
  790. S_OK == pOutput->SetSourceTxMode(TxModeValue) &&
  791. S_OK == pOutput->SetPen(plineattrs, pxo) &&
  792. S_OK == pOutput->SetPenColor(pbo, pptlBrushOrg) &&
  793. S_OK == pOutput->SetBrush(NULL, NULL) &&
  794. S_OK == pOutput->Path(ppo) &&
  795. S_OK == pOutput->Paint() &&
  796. S_OK == pOutput->Flush(pdevobj))
  797. bRet = TRUE;
  798. else
  799. {
  800. pOutput->Delete();
  801. bRet = FALSE;
  802. }
  803. return bRet;
  804. }
  805. extern "C" BOOL APIENTRY
  806. PCLXLFillPath(
  807. SURFOBJ *pso,
  808. PATHOBJ *ppo,
  809. CLIPOBJ *pco,
  810. BRUSHOBJ *pbo,
  811. POINTL *pptlBrushOrg,
  812. MIX mix,
  813. FLONG flOptions)
  814. /*++
  815. Routine Description:
  816. Arguments:
  817. Return Value:
  818. Note:
  819. --*/
  820. {
  821. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  822. PXLPDEV pxlpdev;
  823. VERBOSE(("PCLXLFillPath() entry.\n"));
  824. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  825. BOOL bRet;
  826. XLOutput *pOutput = pxlpdev->pOutput;
  827. ROP4 rop = GET_FOREGROUND_ROP3(UlVectMixToRop4(mix));
  828. TxMode TxModeValue;
  829. //
  830. // Quick return in the case of AA (destination).
  831. //
  832. if (rop == 0xAA)
  833. {
  834. return TRUE;
  835. }
  836. //
  837. // Performance fix suggested by HP.
  838. // Fix the performance problem on CD9T_LET.cdr.
  839. //
  840. if (pco && pco->iFComplexity == FC_COMPLEX)
  841. {
  842. return FALSE;
  843. }
  844. //
  845. // If there is any Pattern involved, set TxMode to Opaque.
  846. //
  847. if (ROP3_NEED_PATTERN(rop))
  848. {
  849. TxModeValue = eOpaque;
  850. }
  851. else
  852. {
  853. TxModeValue = eTransparent;
  854. }
  855. //
  856. // Setup fill mode
  857. //
  858. FillMode FM;
  859. if (flOptions == FP_ALTERNATEMODE)
  860. {
  861. FM = eFillEvenOdd;
  862. }
  863. else if (flOptions == FP_WINDINGMODE)
  864. {
  865. FM = eFillNonZeroWinding;
  866. }
  867. if (S_OK == pOutput->SetClip(pco) &&
  868. S_OK == pOutput->SetROP3(rop) &&
  869. S_OK == pOutput->SetPaintTxMode(TxModeValue) &&
  870. S_OK == pOutput->SetSourceTxMode(TxModeValue) &&
  871. S_OK == pOutput->SetFillMode(FM) &&
  872. S_OK == pOutput->SetPenColor(NULL, NULL) &&
  873. S_OK == pOutput->SetBrush(pbo, pptlBrushOrg) &&
  874. S_OK == pOutput->Path(ppo) &&
  875. S_OK == pOutput->Paint() &&
  876. S_OK == pOutput->Flush(pdevobj))
  877. bRet = TRUE;
  878. else
  879. {
  880. pOutput->Delete();
  881. bRet = FALSE;
  882. }
  883. return bRet;
  884. }
  885. extern "C" BOOL APIENTRY
  886. PCLXLStrokeAndFillPath(
  887. SURFOBJ *pso,
  888. PATHOBJ *ppo,
  889. CLIPOBJ *pco,
  890. XFORMOBJ *pxo,
  891. BRUSHOBJ *pboStroke,
  892. LINEATTRS *plineattrs,
  893. BRUSHOBJ *pboFill,
  894. POINTL *pptlBrushOrg,
  895. MIX mixFill,
  896. FLONG flOptions)
  897. /*++
  898. Routine Description:
  899. Arguments:
  900. Return Value:
  901. Note:
  902. --*/
  903. {
  904. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  905. PXLPDEV pxlpdev;
  906. VERBOSE(("PCLXLStrokeAndFillPath() entry.\n"));
  907. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  908. XLOutput *pOutput = pxlpdev->pOutput;
  909. BOOL bRet;
  910. ROP4 rop = GET_FOREGROUND_ROP3(UlVectMixToRop4(mixFill));
  911. TxMode TxModeValue;
  912. //
  913. // Quick return in the case of AA (destination).
  914. //
  915. if (rop == 0xAA)
  916. {
  917. return TRUE;
  918. }
  919. //
  920. // If there is any Pattern involved, set TxMode to Opaque.
  921. //
  922. if (ROP3_NEED_PATTERN(rop))
  923. {
  924. TxModeValue = eOpaque;
  925. }
  926. else
  927. {
  928. TxModeValue = eTransparent;
  929. }
  930. //
  931. // Setup fill mode
  932. //
  933. FillMode FM;
  934. if (flOptions == FP_ALTERNATEMODE)
  935. {
  936. FM = eFillEvenOdd;
  937. }
  938. else if (flOptions == FP_WINDINGMODE)
  939. {
  940. FM = eFillNonZeroWinding;
  941. }
  942. if (S_OK == pOutput->SetClip(pco) &&
  943. S_OK == pOutput->SetROP3(rop) &&
  944. S_OK == pOutput->SetPaintTxMode(TxModeValue) &&
  945. S_OK == pOutput->SetSourceTxMode(TxModeValue) &&
  946. S_OK == pOutput->SetFillMode(FM) &&
  947. S_OK == pOutput->SetPen(plineattrs, pxo) &&
  948. S_OK == pOutput->SetPenColor(pboStroke, pptlBrushOrg) &&
  949. S_OK == pOutput->SetBrush(pboFill, pptlBrushOrg) &&
  950. S_OK == pOutput->Path(ppo) &&
  951. S_OK == pOutput->Paint() &&
  952. S_OK == pOutput->Flush(pdevobj))
  953. bRet = TRUE;
  954. else
  955. {
  956. pOutput->Delete();
  957. bRet = FALSE;
  958. }
  959. return bRet;
  960. }
  961. extern "C" BOOL APIENTRY
  962. PCLXLRealizeBrush(
  963. BRUSHOBJ *pbo,
  964. SURFOBJ *psoTarget,
  965. SURFOBJ *psoPattern,
  966. SURFOBJ *psoMask,
  967. XLATEOBJ *pxlo,
  968. ULONG iHatch)
  969. /*++
  970. Routine Description:
  971. Arguments:
  972. Return Value:
  973. Note:
  974. --*/
  975. {
  976. PDEVOBJ pdevobj = (PDEVOBJ)psoTarget->dhpdev;
  977. PXLPDEV pxlpdev;
  978. XLBRUSH *pBrush;
  979. BOOL bRet;
  980. OutputFormat OutputF;
  981. VERBOSE(("PCLXLRealizeBrush() entry.\n"));
  982. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  983. //
  984. // the OEM DLL should NOT hook out this function unless it wants to draw
  985. // graphics directly to the device surface. In that case, it calls
  986. // EngRealizeBrush which causes GDI to call DrvRealizeBrush.
  987. // Note that it cannot call back into Unidrv since Unidrv doesn't hook it.
  988. //
  989. if (iHatch >= HS_DDI_MAX)
  990. {
  991. LONG lHeight, lWidth, lScanline;
  992. ULONG ulOutputBPP, ulInputBPP;
  993. DWORD dwI, dwBufSize, dwLenNormal, dwLenRLE,dwLenDRC, dwcbLineSize, dwcbBmpSize;
  994. PDWORD pdwLen;
  995. PBYTE pubSrc, pBufNormal, pBufRLE, pBufDRC, pBuf, pBmpSize;
  996. XLOutput *pOutput = pxlpdev->pOutput;
  997. DetermineOutputFormat(pxlo, pOutput->GetDeviceColorDepth(), psoPattern->iBitmapFormat, &OutputF, &ulOutputBPP);
  998. //
  999. // Get Info
  1000. //
  1001. ulInputBPP = UlBPPtoNum((BPP)psoPattern->iBitmapFormat);
  1002. lHeight = psoPattern->sizlBitmap.cy;
  1003. lWidth = psoPattern->sizlBitmap.cx;
  1004. dwcbLineSize = ((lWidth * ulInputBPP) + 7) >> 3;
  1005. dwBufSize = lHeight * (((lWidth * ulOutputBPP + 31) >> 5 ) << 2) +
  1006. DATALENGTH_HEADER_SIZE + sizeof(PCLXL_EndRastPattern);
  1007. VERBOSE(("PCLXLRealizeBrush():InBPP=%d,Width=%d,Height=%d,Line=%d,Size=%d.\n",
  1008. ulInputBPP, lWidth, lHeight, dwcbLineSize, dwBufSize));
  1009. //
  1010. // Allocate output buffer
  1011. //
  1012. pBufNormal = pBufRLE = pBufDRC = NULL;
  1013. if (COMMANDPTR(((PPDEV)pdevobj)->pDriverInfo,CMD_ENABLEDRC))
  1014. {
  1015. if (NULL == (pBufDRC = (PBYTE)MemAlloc(dwBufSize)))
  1016. {
  1017. ERR(("PCLXLRealizeBrush: MemAlloc failed.\n"));
  1018. return FALSE;
  1019. }
  1020. }
  1021. if (NULL == (pBufNormal = (PBYTE)MemAlloc(dwBufSize)) ||
  1022. NULL == (pBufRLE = (PBYTE)MemAlloc(dwBufSize)) )
  1023. {
  1024. if (pBufNormal != NULL)
  1025. MemFree(pBufNormal);
  1026. if (pBufRLE != NULL)
  1027. MemFree(pBufRLE);
  1028. ERR(("PCLXLRealizeBrush: MemAlloc failed.\n"));
  1029. return FALSE;
  1030. }
  1031. CompressMode CMode;
  1032. BMPConv BMPC;
  1033. PBYTE pubDst;
  1034. DWORD dwDstSize;
  1035. #if DBG
  1036. BMPC.SetDbgLevel(BRUSHDBG);
  1037. #endif
  1038. BMPC.BSetInputBPP((BPP)psoPattern->iBitmapFormat);
  1039. BMPC.BSetOutputBPP(NumToBPP(ulOutputBPP));
  1040. BMPC.BSetOutputBMPFormat(OutputF);
  1041. BMPC.BSetXLATEOBJ(pxlo);
  1042. dwLenNormal = dwLenRLE = dwLenDRC = 0;
  1043. #define NO_COMPRESSION 0
  1044. #define RLE_COMPRESSION 1
  1045. #define DRC_COMPRESSION 2
  1046. DWORD dwComp;
  1047. if (COMMANDPTR(((PPDEV)pdevobj)->pDriverInfo,CMD_ENABLEDRC))
  1048. {
  1049. //
  1050. // Try DRC compression.
  1051. //
  1052. dwComp = 3;
  1053. }
  1054. else
  1055. {
  1056. //
  1057. // Only non and RLE comp.
  1058. //
  1059. dwComp = 2;
  1060. }
  1061. for (dwI = 0; dwI < dwComp; dwI ++)
  1062. {
  1063. bRet = TRUE;
  1064. if (NO_COMPRESSION == dwI)
  1065. {
  1066. pBuf = pBufNormal;
  1067. pdwLen = &dwLenNormal;
  1068. CMode = eNoCompression;
  1069. }
  1070. else
  1071. if (RLE_COMPRESSION == dwI)
  1072. {
  1073. pBuf = pBufRLE;
  1074. pdwLen = &dwLenRLE;
  1075. CMode = eRLECompression;
  1076. }
  1077. else
  1078. if (DRC_COMPRESSION == dwI)
  1079. {
  1080. pBuf = pBufDRC;
  1081. pdwLen = &dwLenDRC;
  1082. CMode = eDeltaRowCompression;
  1083. }
  1084. BMPC.BSetCompressionType(CMode);
  1085. lScanline = lHeight;
  1086. pubSrc = (PBYTE)psoPattern->pvScan0;
  1087. *pBuf = PCLXL_dataLength;
  1088. pBmpSize = pBuf + 1; // DWORD bitmap size
  1089. pBuf += DATALENGTH_HEADER_SIZE;
  1090. (*pdwLen) = DATALENGTH_HEADER_SIZE;
  1091. dwcbBmpSize = 0;
  1092. while (lScanline-- > 0 && dwcbBmpSize + *pdwLen < dwBufSize)
  1093. {
  1094. pubDst = BMPC.PubConvertBMP(pubSrc, dwcbLineSize);
  1095. dwDstSize = BMPC.DwGetDstSize();
  1096. VERBOSE(("PCLXLRealizeBrush[0x%x]: dwDstSize=0x%x\n", lScanline, dwDstSize));
  1097. if ( dwcbBmpSize +
  1098. dwDstSize +
  1099. DATALENGTH_HEADER_SIZE +
  1100. sizeof(PCLXL_EndRastPattern) > dwBufSize || NULL == pubDst)
  1101. {
  1102. ERR(("PCLXLRealizeBrush: Buffer size is too small.(%d)\n", dwI));
  1103. bRet = FALSE;
  1104. break;
  1105. }
  1106. memcpy(pBuf, pubDst, dwDstSize);
  1107. dwcbBmpSize += dwDstSize;
  1108. pBuf += dwDstSize;
  1109. pubSrc += psoPattern->lDelta;
  1110. }
  1111. if (lScanline > 0)
  1112. {
  1113. bRet = FALSE;
  1114. #if DBG
  1115. ERR(("PCLXLRealizeBrush: Conversion failed.\n"));
  1116. #endif
  1117. }
  1118. if (bRet)
  1119. {
  1120. if (dwI == NO_COMPRESSION)
  1121. {
  1122. //
  1123. // Scanline on PCL-XL has to be DWORD align.
  1124. //
  1125. // count byte of scanline = lWidth * ulOutputBPP / 8
  1126. //
  1127. dwcbBmpSize = lHeight * (((lWidth * ulOutputBPP + 31) >> 5 ) << 2);
  1128. }
  1129. CopyMemory(pBmpSize, &dwcbBmpSize, sizeof(dwcbBmpSize));
  1130. (*pdwLen) += dwcbBmpSize;
  1131. *pBuf = PCLXL_EndRastPattern;
  1132. (*pdwLen) ++;
  1133. }
  1134. else
  1135. {
  1136. *pdwLen = 0;
  1137. }
  1138. }
  1139. #undef NO_COMPRESSION
  1140. #undef RLE_COMPRESSION
  1141. #undef DRC_COMPRESSION
  1142. if (dwLenRLE == 0 && dwLenDRC != 0 && dwLenDRC < dwLenNormal ||
  1143. dwLenRLE != 0 && dwLenDRC != 0 && dwLenDRC < dwLenRLE &&
  1144. dwLenDRC < dwLenNormal )
  1145. {
  1146. pBuf = pBufDRC;
  1147. pdwLen = &dwLenDRC;
  1148. CMode = eDeltaRowCompression;
  1149. MemFree(pBufNormal);
  1150. MemFree(pBufRLE);
  1151. }
  1152. else
  1153. if (dwLenRLE != 0 && dwLenRLE < dwLenNormal)
  1154. {
  1155. pBuf = pBufRLE;
  1156. pdwLen = &dwLenRLE;
  1157. CMode = eRLECompression;
  1158. MemFree(pBufNormal);
  1159. MemFree(pBufDRC);
  1160. }
  1161. else
  1162. if (dwLenNormal != 0)
  1163. {
  1164. pBuf = pBufNormal;
  1165. pdwLen = &dwLenNormal;
  1166. CMode = eNoCompression;
  1167. MemFree(pBufRLE);
  1168. MemFree(pBufDRC);
  1169. }
  1170. else
  1171. {
  1172. MemFree(pBufNormal);
  1173. MemFree(pBufRLE);
  1174. MemFree(pBufDRC);
  1175. ERR(("PCLXLRealizeBrush: Conversion failed. Return FALSE.\n"));
  1176. return FALSE;
  1177. }
  1178. //
  1179. // Output
  1180. //
  1181. ColorMapping CMapping;
  1182. DWORD dwScale;
  1183. //
  1184. // Pattern scaling factor
  1185. // Scale the destination size of pattern.
  1186. // Resolution / 150 seems to be a good scaling factor.
  1187. //
  1188. dwScale = (pOutput->GetResolutionForBrush() + 149)/ 150;
  1189. if (pOutput->GetDeviceColorDepth() == e24Bit)
  1190. {
  1191. pOutput->SetColorSpace(eRGB);
  1192. }
  1193. else
  1194. {
  1195. pOutput->SetColorSpace(eGray);
  1196. }
  1197. if (OutputF == eOutputPal)
  1198. {
  1199. DWORD *pdwColorTable;
  1200. if ((pdwColorTable = GET_COLOR_TABLE(pxlo)))
  1201. {
  1202. pOutput->SetPalette(ulOutputBPP, pxlo->cEntries, pdwColorTable);
  1203. CMapping = eIndexedPixel;
  1204. }
  1205. else
  1206. {
  1207. CMapping = eDirectPixel;
  1208. }
  1209. }
  1210. else
  1211. {
  1212. CMapping = eDirectPixel;
  1213. }
  1214. pOutput->Send_cmd(eSetColorSpace);
  1215. pOutput->SetOutputBPP(CMapping, ulOutputBPP);
  1216. pOutput->SetSourceWidth((uint16)lWidth);
  1217. pOutput->SetSourceHeight((uint16)lHeight);
  1218. pOutput->SetDestinationSize((uint16)(lWidth * dwScale), (uint16)(lHeight * dwScale));
  1219. pOutput->SetPatternDefineID((sint16)pxlpdev->dwLastBrushID);
  1220. pOutput->SetPatternPersistence(eSessionPattern);
  1221. pOutput->Send_cmd(eBeginRastPattern);
  1222. pOutput->Flush(pdevobj);
  1223. pOutput->ReadRasterPattern(lHeight, CMode);
  1224. pOutput->Flush(pdevobj);
  1225. DWORD dwBitmapSize;
  1226. CopyMemory(&dwBitmapSize, pBuf + 1, sizeof(DWORD));
  1227. if (dwBitmapSize > 0xff)
  1228. {
  1229. //
  1230. // dataLength
  1231. // size (uin32) (bitmap size)
  1232. // DATA
  1233. // EndImage
  1234. //
  1235. WriteSpoolBuf((PPDEV)pdevobj, pBuf, *pdwLen);
  1236. }
  1237. else
  1238. {
  1239. //
  1240. // dataLength
  1241. // size (byte) (bitmap size)
  1242. // DATA
  1243. // EndImage
  1244. //
  1245. PBYTE pTmp = pBuf;
  1246. pBuf += 3;
  1247. *pBuf = PCLXL_dataLengthByte;
  1248. *(pBuf + 1) = (BYTE)dwBitmapSize;
  1249. WriteSpoolBuf((PPDEV)pdevobj, pBuf, (*pdwLen) - 3);
  1250. //
  1251. // Restore the original pointer
  1252. //
  1253. pBuf = pTmp;
  1254. }
  1255. MemFree(pBuf);
  1256. }
  1257. DWORD dwBrushSize;
  1258. if (pxlo->cEntries)
  1259. {
  1260. dwBrushSize = sizeof(XLBRUSH) + (pxlo->cEntries + 1) * sizeof(DWORD);
  1261. }
  1262. else
  1263. {
  1264. dwBrushSize = sizeof(XLBRUSH) + sizeof(DWORD);
  1265. }
  1266. if (pBrush = (XLBRUSH*)BRUSHOBJ_pvAllocRbrush(pbo, dwBrushSize))
  1267. {
  1268. pBrush->dwSig = XLBRUSH_SIG;
  1269. pBrush->dwHatch = iHatch;
  1270. if (iHatch >= HS_DDI_MAX)
  1271. {
  1272. pBrush->dwPatternID = pxlpdev->dwLastBrushID++;
  1273. }
  1274. else
  1275. {
  1276. //
  1277. // Set 0 for hatch brush case
  1278. //
  1279. pBrush->dwPatternID = 0;
  1280. }
  1281. DWORD *pdwColorTable;
  1282. pdwColorTable = GET_COLOR_TABLE(pxlo);
  1283. //
  1284. // get color for Graphics state cache for either palette case or
  1285. // solid color.
  1286. //
  1287. pBrush->dwColor = BRUSHOBJ_ulGetBrushColor(pbo);
  1288. if (pdwColorTable && pxlo->cEntries != 0)
  1289. {
  1290. //
  1291. // Copy palette table.
  1292. //
  1293. CopyMemory(pBrush->adwColor, pdwColorTable, pxlo->cEntries * sizeof(DWORD));
  1294. pBrush->dwCEntries = pxlo->cEntries;
  1295. }
  1296. else
  1297. {
  1298. pBrush->dwCEntries = 0;
  1299. }
  1300. pBrush->dwOutputFormat = (DWORD)OutputF;
  1301. pbo->pvRbrush = (PVOID)pBrush;
  1302. bRet = TRUE;
  1303. }
  1304. else
  1305. {
  1306. bRet = FALSE;
  1307. }
  1308. return bRet;
  1309. }
  1310. extern "C" BOOL APIENTRY
  1311. PCLXLStartPage(
  1312. SURFOBJ *pso)
  1313. /*++
  1314. Routine Description:
  1315. Arguments:
  1316. Return Value:
  1317. Note:
  1318. --*/
  1319. {
  1320. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  1321. PXLPDEV pxlpdev;
  1322. BOOL bRet;
  1323. VERBOSE(("PCLXLStartPage() entry.\n"));
  1324. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1325. XLOutput *pOutput = pxlpdev->pOutput;
  1326. pxlpdev->dwFlags |= XLPDEV_FLAGS_STARTPAGE_CALLED;
  1327. bRet = DrvStartPage(pso);
  1328. //
  1329. // Bug reported by HP.
  1330. // Plug-in could have command callback and DrvStartPage sets plug-in's
  1331. // pdev in pdevOEM.
  1332. // Need to reset it.
  1333. //
  1334. ((PPDEV)pdevobj)->devobj.pdevOEM = ((PPDEV)pdevobj)->pVectorPDEV;
  1335. //
  1336. // Reset printing mode.
  1337. // SourceTxMode, PaintTxMode
  1338. // ROP
  1339. //
  1340. pOutput->SetPaintTxMode(eOpaque);
  1341. pOutput->SetSourceTxMode(eOpaque);
  1342. pOutput->SetROP3(0xCC);
  1343. pOutput->Flush(pdevobj);
  1344. //
  1345. // Needs to reset attribute when EndPage and BeginPage are sent.
  1346. //
  1347. if (!(pxlpdev->dwFlags & XLPDEV_FLAGS_FIRSTPAGE))
  1348. {
  1349. BSaveFont(pdevobj);
  1350. //
  1351. // Reset graphcis state each page.
  1352. //
  1353. pOutput->ResetGState();
  1354. }
  1355. else
  1356. {
  1357. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_FIRSTPAGE;
  1358. }
  1359. return bRet;
  1360. }
  1361. extern "C" BOOL APIENTRY
  1362. PCLXLSendPage(
  1363. SURFOBJ *pso)
  1364. /*++
  1365. Routine Description:
  1366. Arguments:
  1367. Return Value:
  1368. Note:
  1369. --*/
  1370. {
  1371. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  1372. PXLPDEV pxlpdev;
  1373. XLOutput *pOutput;
  1374. VERBOSE(("PCLXLEndPage() entry.\n"));
  1375. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1376. pxlpdev->dwFlags &= ~XLPDEV_FLAGS_STARTPAGE_CALLED;
  1377. pOutput = pxlpdev->pOutput;
  1378. pOutput->Flush(pdevobj);
  1379. return DrvSendPage(pso);
  1380. }
  1381. extern "C" ULONG APIENTRY
  1382. PCLXLEscape(
  1383. SURFOBJ *pso,
  1384. ULONG iEsc,
  1385. ULONG cjIn,
  1386. PVOID pvIn,
  1387. ULONG cjOut,
  1388. PVOID pvOut)
  1389. /*++
  1390. Routine Description:
  1391. Arguments:
  1392. Return Value:
  1393. Note:
  1394. --*/
  1395. {
  1396. VERBOSE(("PCLXLEscape() entry.\n"));
  1397. return DrvEscape(
  1398. pso,
  1399. iEsc,
  1400. cjIn,
  1401. pvIn,
  1402. cjOut,
  1403. pvOut);
  1404. }
  1405. extern "C" BOOL APIENTRY
  1406. PCLXLStartDoc(
  1407. SURFOBJ *pso,
  1408. PWSTR pwszDocName,
  1409. DWORD dwJobId)
  1410. /*++
  1411. Routine Description:
  1412. Arguments:
  1413. Return Value:
  1414. Note:
  1415. --*/
  1416. {
  1417. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  1418. PXLPDEV pxlpdev;
  1419. VERBOSE(("PCLXLStartDoc() entry.\n"));
  1420. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1421. //
  1422. // Initialize flag
  1423. //
  1424. pxlpdev->dwFlags |= XLPDEV_FLAGS_FIRSTPAGE;
  1425. return DrvStartDoc(
  1426. pso,
  1427. pwszDocName,
  1428. dwJobId);
  1429. }
  1430. extern "C" BOOL APIENTRY
  1431. PCLXLEndDoc(
  1432. SURFOBJ *pso,
  1433. FLONG fl)
  1434. /*++
  1435. Routine Description:
  1436. Arguments:
  1437. Return Value:
  1438. Note:
  1439. --*/
  1440. {
  1441. PDEVOBJ pdevobj = (PDEVOBJ)pso->dhpdev;
  1442. PXLPDEV pxlpdev;
  1443. BOOL bRet;
  1444. VERBOSE(("PCLXLEndDoc() entry.\n"));
  1445. if (NULL == pdevobj->pdevOEM)
  1446. {
  1447. bRet = FALSE;
  1448. }
  1449. {
  1450. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1451. if (S_OK == RemoveAllFonts(pdevobj))
  1452. {
  1453. bRet = TRUE;
  1454. }
  1455. else
  1456. {
  1457. bRet = FALSE;
  1458. }
  1459. }
  1460. pxlpdev->dwFlags |= XLPDEV_FLAGS_ENDDOC_CALLED;
  1461. return bRet && DrvEndDoc(pso, fl);
  1462. }
  1463. ////////////////////////////////////////////////////////////////////////////////
  1464. //
  1465. // Sub functions
  1466. //
  1467. HRESULT
  1468. RemoveAllFonts(
  1469. PDEVOBJ pdevobj)
  1470. {
  1471. PXLPDEV pxlpdev;
  1472. XLOutput *pOutput;
  1473. DWORD dwI;
  1474. HRESULT hResult;
  1475. pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  1476. pOutput = pxlpdev->pOutput;
  1477. hResult = S_OK;
  1478. for (dwI = 0; dwI < pxlpdev->dwNumOfTTFont; dwI++)
  1479. {
  1480. if (S_OK != pOutput->Send_ubyte_array_header(PCLXL_FONTNAME_SIZE) ||
  1481. S_OK != pOutput->Write(PubGetFontName(pdevobj, dwI+1), PCLXL_FONTNAME_SIZE)||
  1482. S_OK != pOutput->Send_attr_ubyte(eFontName) ||
  1483. S_OK != pOutput->Send_cmd(eRemoveFont))
  1484. {
  1485. hResult = S_FALSE;
  1486. break;
  1487. }
  1488. }
  1489. pOutput->Flush(pdevobj);
  1490. pxlpdev->dwNumOfTTFont = 0;
  1491. return hResult;
  1492. }
  1493. HRESULT
  1494. CommonRopBlt(
  1495. IN PDEVOBJ pdevobj,
  1496. IN SURFOBJ *psoSrc,
  1497. IN CLIPOBJ *pco,
  1498. IN XLATEOBJ *pxlo,
  1499. IN BRUSHOBJ *pbo,
  1500. IN RECTL *prclSrc,
  1501. IN RECTL *prclDst,
  1502. IN POINTL *pptlBrush,
  1503. IN ROP4 rop4)
  1504. /*++
  1505. Routine Description:
  1506. Arguments:
  1507. Return Value:
  1508. Note:
  1509. --*/
  1510. {
  1511. HRESULT hRet;
  1512. VERBOSE(("CommonRopBlt() entry.\n"));
  1513. //
  1514. // Error check
  1515. //
  1516. if (pdevobj == NULL ||
  1517. prclDst == NULL )
  1518. {
  1519. ERR(("CommonRopBlt: one of parameters is NULL.\n"));
  1520. return E_UNEXPECTED;
  1521. }
  1522. PXLPDEV pxlpdev= (PXLPDEV)pdevobj->pdevOEM;
  1523. hRet = S_OK;
  1524. XLOutput *pOutput = pxlpdev->pOutput;
  1525. OutputFormat OutputF;
  1526. //
  1527. // Set Clip
  1528. //
  1529. if (!SUCCEEDED(pOutput->SetClip(pco)))
  1530. return S_FALSE;
  1531. //
  1532. // Set Cursor
  1533. //
  1534. pOutput->SetCursor(prclDst->left, prclDst->top);
  1535. //
  1536. // 1. ROP conversion
  1537. //
  1538. // (1) Fill Dstination
  1539. // 0x00 BLACKNESS
  1540. // 0xFF WHITENESS
  1541. //
  1542. // (2) Pattern copy -> P
  1543. // 0xF0 PATCOPY P
  1544. //
  1545. // (3) SRC/NOTSRCOPY -> S or ~S
  1546. // 0x11 ~( S | D)
  1547. // 0x33 ~S
  1548. // 0x44 ( S & ~D)
  1549. // 0x66 ( D ^ S)
  1550. // 0x77 ~( D & S)
  1551. // 0x99 ~( S ^ D)
  1552. // 0xCC S
  1553. // 0xDD ( S | ~D)
  1554. //
  1555. // (4) Misc ROP support
  1556. // 0xAA D
  1557. // 0x0F PATNOT ~P
  1558. //
  1559. //
  1560. ROP3 rop3 = GET_FOREGROUND_ROP3(rop4);
  1561. DWORD dwCase = 0;
  1562. #define ROP_BLACKWHITE 0x1
  1563. #define ROP_PATTERN 0x2
  1564. #define ROP_BITMAP 0x4
  1565. #define ROP_DEST 0x8
  1566. //
  1567. // Set ROP3
  1568. //
  1569. pOutput->SetROP3(GET_FOREGROUND_ROP3(rop4));
  1570. switch (rop3)
  1571. {
  1572. case 0x00:
  1573. case 0xFF:
  1574. dwCase = ROP_BLACKWHITE;
  1575. break;
  1576. case 0xF0:
  1577. dwCase = ROP_PATTERN;
  1578. break;
  1579. case 0x11:
  1580. case 0x33:
  1581. case 0x44:
  1582. case 0x66:
  1583. case 0x77:
  1584. case 0x99:
  1585. case 0xCC:
  1586. case 0xDD:
  1587. dwCase = ROP_BITMAP;
  1588. break;
  1589. case 0xAA:
  1590. dwCase = ROP_DEST;
  1591. break;
  1592. case 0x0F:
  1593. dwCase = ROP_PATTERN;
  1594. break;
  1595. default:
  1596. if (ROP3_NEED_SOURCE(rop3))
  1597. {
  1598. dwCase |= ROP_BITMAP;
  1599. }
  1600. if (ROP3_NEED_PATTERN(rop3))
  1601. {
  1602. dwCase |= ROP_PATTERN;
  1603. }
  1604. if (ROP3_NEED_DEST(rop3))
  1605. {
  1606. dwCase |= ROP_DEST;
  1607. }
  1608. break;
  1609. }
  1610. //
  1611. // Black & White case
  1612. //
  1613. if (dwCase & ROP_BLACKWHITE)
  1614. {
  1615. VERBOSE(("CommonRopBlt(): BlackWhite.\n"));
  1616. //
  1617. // SetBrushSource
  1618. // NewPath
  1619. // RectanglePath
  1620. // PaintPath
  1621. //
  1622. CMNBRUSH CmnBrush;
  1623. CmnBrush.dwSig = BRUSH_SIGNATURE;
  1624. CmnBrush.BrushType = kBrushTypeSolid;
  1625. CmnBrush.ulSolidColor = 0x00;
  1626. CmnBrush.ulHatch = 0xFFFFFFFF;
  1627. CmnBrush.dwColor = 0x00FFFFFF;
  1628. CmnBrush.dwPatternBrushID = 0xFFFFFFFF;
  1629. pOutput->SetSourceTxMode(eOpaque);
  1630. pOutput->SetPaintTxMode(eOpaque);
  1631. if(rop3 == 0x00)
  1632. {
  1633. if (e24Bit == pOutput->GetDeviceColorDepth())
  1634. {
  1635. pOutput->SetRGBColor(0);
  1636. CmnBrush.dwColor = 0x00;
  1637. }
  1638. else
  1639. {
  1640. pOutput->SetGrayLevel(0x00);
  1641. CmnBrush.dwColor = 0x00;
  1642. }
  1643. }
  1644. else
  1645. {
  1646. if (e24Bit == pOutput->GetDeviceColorDepth())
  1647. {
  1648. pOutput->SetRGBColor(0x00ffffff);
  1649. CmnBrush.dwColor = 0x00ffffff;
  1650. }
  1651. else
  1652. {
  1653. pOutput->SetGrayLevel(0xff);
  1654. CmnBrush.dwColor = 0x00ffffff;
  1655. }
  1656. }
  1657. ((XLBrush*)pOutput)->SetBrush(&CmnBrush);
  1658. pOutput->Send_cmd(eSetBrushSource);
  1659. pOutput->SetPenColor(NULL, NULL);
  1660. if (!(dwCase & ROP_BITMAP))
  1661. {
  1662. pOutput->Send_cmd(eNewPath);
  1663. pOutput->RectanglePath(prclDst);
  1664. pOutput->Send_cmd(ePaintPath);
  1665. }
  1666. pOutput->Flush(pdevobj);
  1667. }
  1668. //
  1669. // Pattern fill case
  1670. //
  1671. if (dwCase & (ROP_DEST|ROP_PATTERN))
  1672. {
  1673. VERBOSE(("CommonRopBlt(): Pattern.\n"));
  1674. //
  1675. // SetPaintTxMode
  1676. // SetSourceTxMode
  1677. // SetBrushSource
  1678. // NewPath
  1679. // RectanglePath
  1680. // PaintPath
  1681. //
  1682. pOutput->SetSourceTxMode(eOpaque);
  1683. pOutput->SetPaintTxMode(eOpaque);
  1684. pOutput->SetBrush(pbo, pptlBrush);
  1685. pOutput->SetPenColor(NULL, NULL);
  1686. if (!(dwCase & ROP_BITMAP))
  1687. {
  1688. pOutput->Send_cmd(eNewPath);
  1689. pOutput->RectanglePath(prclDst);
  1690. pOutput->Send_cmd(ePaintPath);
  1691. }
  1692. pOutput->Flush(pdevobj);
  1693. }
  1694. //
  1695. // Bitmap case
  1696. //
  1697. if (dwCase & ROP_BITMAP)
  1698. {
  1699. LONG lHeight, lWidth, lScanline;
  1700. ULONG ulOutputBPP, ulInputBPP;
  1701. DWORD dwI, dwBufSize, dwLen, dwcbLineSize, dwcbBmpSize;
  1702. PDWORD pdwLen;
  1703. PBYTE pubSrc, pBuf, pBufOrg = NULL, pBmpSize, pBufEnd;
  1704. ColorMapping CMapping;
  1705. SURFOBJ *psoBmp;
  1706. HBITMAP hBitmap = NULL;
  1707. PBYTE pubChanged = NULL;
  1708. // temporary rectangle used if the image is downscaled by the engine
  1709. RECTL rctlBitmap;
  1710. // zero out the temporary rectangle
  1711. memset( &rctlBitmap, 0, sizeof(RECTL) );
  1712. VERBOSE(("CommonRopBlt(): Bitmap\n"));
  1713. if (psoSrc == NULL ||
  1714. prclSrc == NULL )
  1715. {
  1716. ERR(("UNIDRV:CommonRopBlt:psoSrc, pxlo, or prclSrc == NULL.\n"));
  1717. pOutput->Flush(pdevobj);
  1718. return E_UNEXPECTED;
  1719. }
  1720. //
  1721. // Input BPP
  1722. //
  1723. ulInputBPP = UlBPPtoNum((BPP)psoSrc->iBitmapFormat);
  1724. psoBmp = NULL;
  1725. //
  1726. // If the source image is larger than it will appear on the
  1727. // destination surface, shrink it to the target size. No point
  1728. // in sending extra bits.
  1729. //
  1730. // This optimization could be further optimized by building up a clip
  1731. // object here if one is specified. How much of a gain this is
  1732. // worth I don't know.
  1733. //
  1734. if (prclDst->right - prclDst->left < prclSrc->right - prclSrc->left ||
  1735. prclDst->bottom - prclDst->top < prclSrc->bottom - prclSrc->top )
  1736. {
  1737. //
  1738. // Shrink source bitmap.
  1739. //
  1740. PDEV *pPDev = (PDEV*)pdevobj;
  1741. SIZEL sizlDest;
  1742. DWORD dwScanlineLength;
  1743. POINTL ptlBrushOrg;
  1744. // Translate destination rectangle to origin 0,0 and same dimensions as before
  1745. rctlBitmap.left = 0;
  1746. rctlBitmap.top = 0;
  1747. rctlBitmap.right = prclDst->right - prclDst->left;
  1748. rctlBitmap.bottom = prclDst->bottom - prclDst->top;
  1749. sizlDest.cx = prclDst->right - prclDst->left;
  1750. sizlDest.cy = prclDst->bottom - prclDst->top;
  1751. dwScanlineLength = (sizlDest.cx * ulInputBPP + 7 ) >> 3;
  1752. if (pptlBrush)
  1753. {
  1754. ptlBrushOrg = *pptlBrush;
  1755. }
  1756. else
  1757. {
  1758. ptlBrushOrg.x = ptlBrushOrg.y = 0;
  1759. }
  1760. // When we do the transfer, don't do color translation because that will be handled by the printer.
  1761. // Also, don't pass the clip object, because it's in the wrong coordinate space. We could build a
  1762. // a new clip object, but the value of doing so is questionable, and it would take a lot more testing.
  1763. if ((psoBmp = CreateBitmapSURFOBJ(pPDev,
  1764. &hBitmap,
  1765. sizlDest.cx,
  1766. sizlDest.cy,
  1767. psoSrc->iBitmapFormat)) &&
  1768. EngStretchBlt(psoBmp, psoSrc, NULL, NULL, NULL, NULL, &ptlBrushOrg, &rctlBitmap, prclSrc, NULL, HALFTONE))
  1769. {
  1770. psoSrc = psoBmp;
  1771. prclSrc = &rctlBitmap;
  1772. }
  1773. else
  1774. {
  1775. ERR(("CreateBitmapSURFOBJ or EngStretchBlt failed.\n"));
  1776. }
  1777. }
  1778. //
  1779. // Set source opaque mode
  1780. // GDI bug. CopyBits is called recursively.
  1781. //
  1782. {
  1783. PDEV *pPDev = (PDEV*)pdevobj;
  1784. if (pPDev->fMode2 & PF2_SURFACE_WHITENED)
  1785. {
  1786. pOutput->SetSourceTxMode(eTransparent);
  1787. }
  1788. else
  1789. {
  1790. pOutput->SetSourceTxMode(eOpaque);
  1791. }
  1792. }
  1793. pOutput->SetPaintTxMode(eOpaque);
  1794. //
  1795. // Bitmap output
  1796. //
  1797. DetermineOutputFormat(pxlo, pOutput->GetDeviceColorDepth(), psoSrc->iBitmapFormat, &OutputF, &ulOutputBPP);
  1798. if (pOutput->GetDeviceColorDepth() == e24Bit)
  1799. {
  1800. pOutput->SetColorSpace(eRGB);
  1801. }
  1802. else
  1803. {
  1804. pOutput->SetColorSpace(eGray);
  1805. }
  1806. if (OutputF == eOutputPal)
  1807. {
  1808. DWORD *pdwColorTable = NULL;
  1809. if (pdwColorTable = GET_COLOR_TABLE(pxlo))
  1810. {
  1811. if ( pxlpdev->dwFlags & XLPDEV_FLAGS_SUBST_TRNCOLOR_WITH_WHITE )
  1812. {
  1813. ULONG ulTransColor = pxlpdev->ulTransColor;
  1814. pdwColorTable = PdwChangeTransparentPalette(ulTransColor, pdwColorTable, pxlo->cEntries);
  1815. if (pdwColorTable)
  1816. {
  1817. pOutput->SetPalette(ulOutputBPP, pxlo->cEntries, pdwColorTable);
  1818. MemFree (pdwColorTable);
  1819. pdwColorTable = NULL;
  1820. }
  1821. else
  1822. {
  1823. ERR(("CommonRopBlt: PdwChangeTransparentPalette returned NULL.\n"));
  1824. goto ErrorReturn;
  1825. }
  1826. }
  1827. else
  1828. {
  1829. pOutput->SetPalette(ulOutputBPP, pxlo->cEntries, pdwColorTable);
  1830. }
  1831. }
  1832. CMapping = eIndexedPixel;
  1833. }
  1834. else
  1835. {
  1836. CMapping = eDirectPixel;
  1837. }
  1838. pOutput->Send_cmd(eSetColorSpace);
  1839. //
  1840. // Get height, width, and scanline size.
  1841. //
  1842. lWidth = prclSrc->right - prclSrc->left;
  1843. lHeight = prclSrc->bottom - prclSrc->top;
  1844. dwcbLineSize = ((lWidth * ulInputBPP) + 7) >> 3;
  1845. //
  1846. // Allocates memory to hold whole bitmap.
  1847. //
  1848. dwBufSize = lHeight * (((lWidth * ulOutputBPP + 31) >> 5 ) << 2);
  1849. //
  1850. // Limit Buffer Size to 16k, else if the scan line is big, huge memory will
  1851. // be allocated. But the size has to be at least able to hold one scanline.
  1852. //
  1853. #define BMPBUFSIZE 16384
  1854. if (dwBufSize > BMPBUFSIZE)
  1855. {
  1856. if (dwcbLineSize > BMPBUFSIZE)
  1857. dwBufSize = dwcbLineSize;
  1858. else
  1859. dwBufSize = BMPBUFSIZE;
  1860. }
  1861. //
  1862. // Allocate appropriate buffers before doing BeginImage.
  1863. // PCLXL expects certain things to happen after BeginImage.
  1864. // If we attempt to allocate within BeginImage and then allocation
  1865. // fails, and we try to exit midway, PCLXL will not be able to handle
  1866. // the resulting output properly.
  1867. //
  1868. // When doing TransparentBlt, we need to change colors of pixels. Instead of
  1869. // altering memory within psoSrc, we'll make copy of scan line and then alter images.
  1870. // So memory needs to be allocated for that.
  1871. //
  1872. if ( pxlpdev->dwFlags & XLPDEV_FLAGS_SUBST_TRNCOLOR_WITH_WHITE &&
  1873. eDirectPixel == CMapping )
  1874. {
  1875. if ( NULL == (pubChanged = (PBYTE) MemAlloc(dwcbLineSize)) )
  1876. {
  1877. ERR(("CommonRopBlt: Cannot allocate memory for pubChanged.\n"));
  1878. goto ErrorReturn;
  1879. }
  1880. }
  1881. //
  1882. // Allocate output buffer
  1883. //
  1884. if (NULL == (pBuf = (PBYTE)MemAlloc(dwBufSize)))
  1885. {
  1886. ERR(("CommonRopBlt: MemAlloc failed.\n"));
  1887. }
  1888. else
  1889. {
  1890. //
  1891. // BeginImage
  1892. //
  1893. pOutput->BeginImage(
  1894. CMapping,
  1895. ulOutputBPP,
  1896. lWidth,
  1897. lHeight,
  1898. prclDst->right - prclDst->left,
  1899. prclDst->bottom - prclDst->top);
  1900. pOutput->Flush(pdevobj);
  1901. VERBOSE(("CommonRopBlt: ulInputBPP=%d, ulOutputBPP=%d, lWidth=0x%x, lHeight=0x%x, dwcbLineSize=0x%x, dwBufSize=0x%x\n",ulInputBPP, ulOutputBPP, lWidth, lHeight, dwcbLineSize, dwBufSize));
  1902. pBufOrg = pBuf;
  1903. pBufEnd = pBuf + (ULONG_PTR)(dwBufSize); //point pBufEnd to byte after last allocatted byte.
  1904. CompressMode CurrentCMode, PreviousCMode;
  1905. BMPConv BMPC;
  1906. PBYTE pubDst;
  1907. DWORD dwSize;
  1908. LONG lScans, //number of scan lines stored in pBufOrg
  1909. lStart; //From which scan line do we start sending scan lines to printer.
  1910. //e.g. if lStart=5, it means 0-4 scan lines have been sent, now 5th scan line (and may be more) has to be sent
  1911. #if DBG
  1912. BMPC.SetDbgLevel(BITMAPDBG);
  1913. #endif
  1914. BMPC.BSetInputBPP((BPP)psoSrc->iBitmapFormat);
  1915. BMPC.BSetOutputBPP(NumToBPP(ulOutputBPP));
  1916. BMPC.BSetOutputBMPFormat(OutputF);
  1917. BMPC.BSetXLATEOBJ(pxlo);
  1918. lScanline = lHeight;
  1919. //
  1920. // Set pubSrc
  1921. //
  1922. pubSrc = (PBYTE)psoSrc->pvScan0;
  1923. if (!psoBmp)
  1924. {
  1925. pubSrc += (LONG_PTR) prclSrc->top * psoSrc->lDelta + ((ulInputBPP * prclSrc->left) >> 3);
  1926. }
  1927. dwcbBmpSize = 0;
  1928. lScans = 0;
  1929. lStart = 0;
  1930. PreviousCMode = eInvalidValue;
  1931. while (lScanline-- > 0)
  1932. {
  1933. PBYTE pubSrcLocal = pubSrc;
  1934. //
  1935. // When this is called from TransparentBlt, the Transparent Color
  1936. // has to be replaced by white. This is to be done only for
  1937. // direct images, not for paletted images.
  1938. //
  1939. if ( (pxlpdev->dwFlags & XLPDEV_FLAGS_SUBST_TRNCOLOR_WITH_WHITE) &&
  1940. eDirectPixel == CMapping )
  1941. {
  1942. hRet = hrChangePixelColorInScanLine( pubSrc,
  1943. ulInputBPP,
  1944. lWidth,
  1945. pxlpdev->ulTransColor,
  1946. pubChanged,
  1947. dwcbLineSize);
  1948. if ( FAILED (hRet) )
  1949. {
  1950. goto ErrorReturn;
  1951. }
  1952. pubSrcLocal = pubChanged;
  1953. }
  1954. //
  1955. // First try compression and see if the compress data is smaller
  1956. // than the original data. If it's smaller, go ahead to use the
  1957. // compression. Otherwise, use original data.
  1958. //
  1959. // While it is permitted to mix eRLECompression and eNoCompression
  1960. // blocks of ReadImage data, XL does not allow mixing JPEG or
  1961. // DeltaRow image blocks with any other compression method.
  1962. //
  1963. //
  1964. // DRC Compression
  1965. //
  1966. if (COMMANDPTR(((PPDEV)pdevobj)->pDriverInfo,CMD_ENABLEDRC))
  1967. {
  1968. CurrentCMode = eDeltaRowCompression;
  1969. BMPC.BSetCompressionType(CurrentCMode);
  1970. pubDst = BMPC.PubConvertBMP(pubSrcLocal, dwcbLineSize);
  1971. dwSize = BMPC.DwGetDstSize();
  1972. VERBOSE(("CommonRopBlt: Comp(DRC:0x%x)\n", dwSize));
  1973. }
  1974. else
  1975. {
  1976. //
  1977. // RLE compression
  1978. //
  1979. BMPC.BSetCompressionType(eRLECompression);
  1980. pubDst = BMPC.PubConvertBMP(pubSrcLocal, dwcbLineSize);
  1981. dwSize = BMPC.DwGetDstSize();
  1982. VERBOSE(("CommonRopBlt: Comp(RLE:0x%x)\n", dwSize));
  1983. if (dwSize < dwcbLineSize)
  1984. {
  1985. CurrentCMode = eRLECompression;
  1986. }
  1987. else
  1988. {
  1989. CurrentCMode = eNoCompression;
  1990. BMPC.BSetCompressionType(eNoCompression);
  1991. pubDst = BMPC.PubConvertBMP(pubSrcLocal, dwcbLineSize);
  1992. dwSize = BMPC.DwGetDstSize();
  1993. VERBOSE(("CommonRopBlt: Comp(NO:0x%x)\n", dwSize));
  1994. }
  1995. }
  1996. //
  1997. // Output bitmap.
  1998. // 1. Mostly we try to store the data bits in pBufOrg and send them
  1999. // all at once after processing has been done on the full image.
  2000. // This storage is done on a per scan line basis.
  2001. // But if image is really big, pBufOrg gets filled up and more
  2002. // scan lines cannot be copied. So we empty pBufOrg to make place
  2003. // for remaining scan lines. If either of these is true, pBufOrg
  2004. // needs to be flushed. (Both these conditions are essentially the same).
  2005. // dwcbBmpSize + dwSize > dwBufSize
  2006. // pBuf + dwSize > pBufEnd
  2007. //
  2008. // 2. If the compression has to change, we dump the data bits
  2009. // using the older compression method that have been stored in
  2010. // pBufOrg and/or pbDst.
  2011. //
  2012. if (dwcbBmpSize + dwSize > dwBufSize ||
  2013. PreviousCMode != eInvalidValue && PreviousCMode != CurrentCMode)
  2014. {
  2015. if (PreviousCMode == eInvalidValue)
  2016. {
  2017. PreviousCMode = CurrentCMode;
  2018. }
  2019. //
  2020. // Four possible cases
  2021. // 1&2. dwcbBmpSize == 0 i.e. nothing is present in pBufOrg
  2022. // So just dump whatever is present in pubDst.
  2023. // This covers both cases i.e. whether dwSize > dwBufSize or not.
  2024. // 3. dwcmBmpSize is not zero
  2025. // dump the image in pBufOrg, clean pBufOrg, and then later
  2026. // on put the contents of pubDst in pBufOrg(pBuf).
  2027. // 4. dwcbBmpSize is not zero and dwSize > dwBufSize
  2028. // i.e. somehow the compression caused the size of the
  2029. // scan line to increase beyond the dwBufSize.
  2030. // Because pBufOrg is at most dwBufSize, we cannot
  2031. // copy pubDst to pBufOrg. So we have to dump pubDst here.
  2032. //
  2033. if (dwcbBmpSize == 0)
  2034. {
  2035. //
  2036. // Case 1&2
  2037. //
  2038. BSendReadImageData(pdevobj,
  2039. PreviousCMode,
  2040. pubDst,
  2041. lStart,
  2042. 1,
  2043. dwSize);
  2044. dwSize = 0;
  2045. lStart++; //One line emitted. Therefore increment lStart
  2046. }
  2047. else
  2048. {
  2049. //
  2050. // There is some image data stored in the pBufOrg buffer.
  2051. // Emit that data. (case 3)
  2052. //
  2053. BSendReadImageData(pdevobj,
  2054. PreviousCMode,
  2055. pBufOrg,
  2056. lStart,
  2057. lScans,
  2058. dwcbBmpSize);
  2059. lStart += lScans; //lScans lines emitted
  2060. if ( dwSize > dwBufSize )
  2061. {
  2062. //
  2063. // Case 4.
  2064. //
  2065. BSendReadImageData(pdevobj,
  2066. PreviousCMode,
  2067. pubDst,
  2068. lStart,
  2069. 1,
  2070. dwSize);
  2071. dwSize = 0;
  2072. lStart++;
  2073. }
  2074. }
  2075. //
  2076. // Reset parameters
  2077. //
  2078. dwcbBmpSize = 0;
  2079. lScans = 0;
  2080. pBuf = pBufOrg;
  2081. }
  2082. if (NULL == pubDst)
  2083. {
  2084. ERR(("CommonRopBlt: Conversion failed. pubDst is NULL.\n"));
  2085. goto ErrorReturn;
  2086. }
  2087. //
  2088. // If post-compression size of image is more than zero, AND
  2089. // if destination buffer(pBuf) has enough space, then copy the compressed
  2090. // data to the destination. (Data can also be in uncompressed format if
  2091. // compression does not result in size saving).
  2092. // Increment lScans to indicicate that we are putting one more scan
  2093. // line worth of data in pBufOrg
  2094. //
  2095. if (dwSize > 0 &&
  2096. pBuf + dwSize <= pBufEnd)
  2097. {
  2098. memcpy(pBuf, pubDst, dwSize);
  2099. dwcbBmpSize += dwSize;
  2100. pBuf += dwSize;
  2101. lScans ++;
  2102. }
  2103. PreviousCMode = CurrentCMode;
  2104. if (CurrentCMode == eNoCompression)
  2105. {
  2106. DWORD dwDiff = (((lWidth * ulOutputBPP + 31) >> 5) << 2) - dwSize;
  2107. if (dwDiff)
  2108. {
  2109. memset(pBuf, 0, dwDiff);
  2110. dwcbBmpSize += dwDiff;
  2111. pBuf += dwDiff;
  2112. }
  2113. }
  2114. pubSrc += psoSrc->lDelta;
  2115. }
  2116. if (dwcbBmpSize > 0)
  2117. {
  2118. BSendReadImageData(pdevobj, CurrentCMode, pBufOrg, lStart, lScans, dwcbBmpSize);
  2119. }
  2120. pOutput->Send_cmd(eEndImage);
  2121. pOutput->Flush(pdevobj);
  2122. }
  2123. ErrorReturn:
  2124. if (pBufOrg != NULL)
  2125. MemFree(pBufOrg);
  2126. if ( NULL != pubChanged )
  2127. {
  2128. MemFree(pubChanged);
  2129. }
  2130. if (NULL != psoBmp)
  2131. {
  2132. EngUnlockSurface(psoBmp);
  2133. if (hBitmap && !EngDeleteSurface((HSURF)hBitmap))
  2134. {
  2135. ERR(("CommonRopBlt: EngDeleteSurface failed.\n"));
  2136. hRet = FALSE;
  2137. }
  2138. }
  2139. }
  2140. return hRet;
  2141. }
  2142. BOOL
  2143. BSendReadImageData(
  2144. IN PDEVOBJ pdevobj,
  2145. IN CompressMode CMode,
  2146. IN PBYTE pBuf,
  2147. IN LONG lStart,
  2148. IN LONG lHeight,
  2149. IN DWORD dwcbSize)
  2150. {
  2151. VERBOSE(("BSendReadImageData(CMode=%d, lHeight=0x%x, dwcbSize=0x%x\n", CMode, lHeight, dwcbSize));
  2152. //
  2153. // dataLength (1)
  2154. // size (byte or long) (1 or 4)
  2155. //
  2156. DWORD dwHeaderSize;
  2157. BYTE aubHeader[DATALENGTH_HEADER_SIZE];
  2158. PXLPDEV pxlpdev = (PXLPDEV)pdevobj->pdevOEM;
  2159. XLOutput *pOutput = pxlpdev->pOutput;
  2160. //
  2161. // Print the converted data.
  2162. //
  2163. pOutput->ReadImage(lStart, lHeight, CMode);
  2164. pOutput->Flush(pdevobj);
  2165. if (dwcbSize > 0xff)
  2166. {
  2167. //
  2168. // dataLength
  2169. // size (uin32) (bitmap size)
  2170. //
  2171. aubHeader[0] = PCLXL_dataLength;
  2172. dwHeaderSize = DATALENGTH_HEADER_SIZE;
  2173. CopyMemory(aubHeader + 1, &dwcbSize, sizeof(dwcbSize));
  2174. }
  2175. else
  2176. {
  2177. //
  2178. // dataLength
  2179. // size (byte) (bitmap size)
  2180. //
  2181. aubHeader[0] = PCLXL_dataLengthByte;
  2182. dwHeaderSize = DATALENGTH_HEADER_SIZE - 3;
  2183. CopyMemory(aubHeader + 1, &dwcbSize, sizeof(BYTE));
  2184. }
  2185. //
  2186. // dataLength
  2187. // size (byte/uint32)
  2188. // DATA
  2189. // EndImage
  2190. //
  2191. WriteSpoolBuf((PPDEV)pdevobj, aubHeader, dwHeaderSize);
  2192. WriteSpoolBuf((PPDEV)pdevobj, pBuf, dwcbSize);
  2193. return TRUE;
  2194. }
  2195. inline
  2196. VOID
  2197. DetermineOutputFormat(
  2198. XLATEOBJ *pxlo,
  2199. ColorDepth DeviceColorDepth,
  2200. INT iBitmapFormat,
  2201. OutputFormat *pOutputF,
  2202. ULONG *pulOutputBPP)
  2203. /*++
  2204. Routine Description:
  2205. Arguments:
  2206. Return Value:
  2207. Note:
  2208. --*/
  2209. {
  2210. switch ((BPP)iBitmapFormat)
  2211. {
  2212. case e1bpp:
  2213. case e4bpp:
  2214. *pOutputF = eOutputPal;
  2215. break;
  2216. case e8bpp:
  2217. case e16bpp:
  2218. //
  2219. // Color device or not?
  2220. //
  2221. if (DeviceColorDepth == e24Bit)
  2222. *pOutputF = eOutputPal;
  2223. else
  2224. *pOutputF = eOutputGray;
  2225. break;
  2226. case e24bpp:
  2227. case e32bpp:
  2228. //
  2229. // Color device or not?
  2230. //
  2231. if (DeviceColorDepth == e24Bit)
  2232. *pOutputF = eOutputRGB;
  2233. else
  2234. *pOutputF = eOutputGray;
  2235. break;
  2236. }
  2237. switch (*pOutputF)
  2238. {
  2239. case eOutputGray:
  2240. *pulOutputBPP = 8;
  2241. break;
  2242. case eOutputPal:
  2243. *pulOutputBPP = UlBPPtoNum((BPP)iBitmapFormat);
  2244. break;
  2245. case eOutputRGB:
  2246. case eOutputCMYK:
  2247. *pulOutputBPP = 24;
  2248. break;
  2249. }
  2250. //
  2251. // Make sure that color table is available for palette output.
  2252. //
  2253. if (*pOutputF == eOutputPal)
  2254. {
  2255. if (!(GET_COLOR_TABLE(pxlo)))
  2256. {
  2257. if (DeviceColorDepth == e24Bit)
  2258. {
  2259. *pOutputF = eOutputRGB;
  2260. *pulOutputBPP = 24;
  2261. }
  2262. else
  2263. {
  2264. *pOutputF = eOutputGray;
  2265. *pulOutputBPP = 8;
  2266. }
  2267. }
  2268. }
  2269. }
  2270. PDWORD
  2271. PdwChangeTransparentPalette(
  2272. ULONG iTransColor,
  2273. PDWORD pdwColorTable,
  2274. DWORD dwEntries)
  2275. /*++
  2276. Routine Description:
  2277. Creates another copy of palatte and replace the transparent color by white
  2278. Returns the pointer of a new palette.
  2279. The calling function has responsibility to release the palette.
  2280. Arguments:
  2281. Return Value:
  2282. Note:
  2283. --*/
  2284. {
  2285. PDWORD pdwNewPalette = NULL;
  2286. //
  2287. // Parameter check
  2288. //
  2289. if (NULL == pdwColorTable ||
  2290. dwEntries == 0 )
  2291. {
  2292. return NULL;
  2293. }
  2294. if (NULL == (pdwNewPalette = (PDWORD)MemAlloc(sizeof(DWORD) * dwEntries)))
  2295. {
  2296. return NULL;
  2297. }
  2298. CopyMemory(pdwNewPalette, pdwColorTable, sizeof(DWORD) * dwEntries);
  2299. //
  2300. // When printing in palette mode, iTransColor indicates the index into
  2301. // the palette, instead of the color in the palette. The palette entry
  2302. // at that index is the color.
  2303. //
  2304. pdwNewPalette[iTransColor] = RGB_WHITE;
  2305. return pdwNewPalette;
  2306. }
  2307. /*++
  2308. Routine Name
  2309. hrChangePixelColorInScanLine
  2310. Routine Description:
  2311. Changes the pixels in scan line that match a certain color to White
  2312. Arguments:
  2313. pubSrc : The original scan line.
  2314. ulBPP : Bits Per Pixel of scan line.
  2315. ulNumPixels : Number of Pixels in the scan line.
  2316. ulTransColor: The color that needs to be changed.
  2317. pubChanged : The memory where the new(changed) scan line should be put.
  2318. ulNumBytes : Number of bytes in pubChanged buffer.
  2319. Return Value:
  2320. S_OK : if success
  2321. E_FAIL: Otherwise
  2322. Note:
  2323. --*/
  2324. HRESULT hrChangePixelColorInScanLine(
  2325. IN PBYTE pubSrc,
  2326. IN ULONG ulBPP,
  2327. IN ULONG ulNumPixels,
  2328. IN ULONG ulTransColor,
  2329. IN OUT PBYTE pubChanged,
  2330. IN ULONG ulNumBytes )//NumBytes in pubChanged
  2331. {
  2332. ULONG ulBytesPerPixel = 3; //24bpp is more common that 16 or 32bpp
  2333. ULONG ulColor = 0;
  2334. ULONG ulDestSize = 0; //Required destination number of bytes.
  2335. HRESULT hr = S_OK;
  2336. //
  2337. // First do input validation
  2338. //
  2339. if ( NULL == pubSrc ||
  2340. NULL == pubChanged )
  2341. {
  2342. ASSERT(("Null Parameter\n"));
  2343. return E_UNEXPECTED;
  2344. }
  2345. //
  2346. // Make sure pubChanged has enough memory to hold
  2347. // the changed scan line.
  2348. //
  2349. ulBytesPerPixel = ulBPP >> 3; //8 bits per pixel.
  2350. ulDestSize = ulBytesPerPixel * ulNumPixels;
  2351. if ( ulNumBytes < ulDestSize )
  2352. {
  2353. ASSERT((FALSE, "Insufficient size of destination buffer\n"));
  2354. return E_FAIL;
  2355. }
  2356. //
  2357. // Copy Scanline from Source to Destination. Then go through the scan line and
  2358. // change the transparent color to white
  2359. // Go through each pixel (there are ulNumPixels pixels).
  2360. // Whenever the pixels's color is same as ulTransColor, replace it
  2361. // with white.
  2362. //
  2363. // Only direct images are supported in this function.
  2364. // No palletes.
  2365. // 8bpp images are mostly palettes. But when printing to monochrome
  2366. // pclxl device, they are being treated as direct images.
  2367. //
  2368. CopyMemory (pubChanged, pubSrc, ulNumBytes);
  2369. switch (ulBPP)
  2370. {
  2371. case 8:
  2372. {
  2373. for (ULONG ul = 0; ul < ulNumPixels ; ul++, pubChanged += ulBytesPerPixel)
  2374. {
  2375. ulColor = (ULONG) pubChanged[0] ;
  2376. if ( ulTransColor == ulColor )
  2377. {
  2378. pubChanged[0] = 0xFF;
  2379. }
  2380. }
  2381. }
  2382. break;
  2383. case 16:
  2384. {
  2385. for (ULONG ul = 0; ul < ulNumPixels ; ul++, pubChanged += ulBytesPerPixel)
  2386. {
  2387. ulColor = ((ULONG) pubChanged[0]) | ((ULONG) pubChanged[1] << 8);
  2388. if ( ulTransColor == ulColor )
  2389. {
  2390. pubChanged[0] = 0xFF;
  2391. pubChanged[1] = 0xFF;
  2392. }
  2393. }
  2394. }
  2395. break;
  2396. case 24:
  2397. {
  2398. for (ULONG ul = 0; ul < ulNumPixels ; ul++, pubChanged += ulBytesPerPixel)
  2399. {
  2400. ulColor = ((ULONG) pubChanged[0]) |
  2401. ((ULONG) pubChanged[1] << 8) |
  2402. ((ULONG) pubChanged[2] << 16);
  2403. if ( ulTransColor == ulColor )
  2404. {
  2405. //
  2406. // White is 0xFFFFFF (3 bytes of FF)
  2407. //
  2408. pubChanged[0] = 0xFF;
  2409. pubChanged[1] = 0xFF;
  2410. pubChanged[2] = 0xFF;
  2411. }
  2412. }
  2413. }
  2414. break;
  2415. case 32:
  2416. {
  2417. for (ULONG ul = 0; ul < ulNumPixels ; ul++, pubChanged += ulBytesPerPixel)
  2418. {
  2419. ulColor = *(PDWORD)pubChanged;
  2420. if ( ulTransColor == ulColor )
  2421. {
  2422. *(PDWORD)pubChanged |= 0x00FFFFFF; //This modifies only RGB. Alpha channel info retained.
  2423. }
  2424. }
  2425. }
  2426. break;
  2427. default:
  2428. ASSERT((FALSE, "Unsupported bpp value %d\n", ulBPP));
  2429. hr = E_FAIL;
  2430. } //switch
  2431. return hr;
  2432. }