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.

850 lines
27 KiB

  1. /******************************Public*Routine******************************\
  2. * bbddi.cxx
  3. *
  4. * This contains the bitblt simulations code.
  5. *
  6. * Copyright (c) 1993-1999 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "precomp.hxx"
  9. /******************************Public*Routine******************************\
  10. * EngBitBlt
  11. *
  12. * DDI entry point. Blts to a engine managed surface.
  13. *
  14. * History:
  15. * 16-Feb-1991 -by- Patrick Haluptzok patrickh
  16. * Wrote it.
  17. \**************************************************************************/
  18. BOOL
  19. EngBitBlt(
  20. SURFOBJ *psoDst, // Target surface
  21. SURFOBJ *psoSrc, // Source surface
  22. SURFOBJ *psoMask, // Mask
  23. CLIPOBJ *pco, // Clip through this
  24. XLATEOBJ *pxlo, // Color translation
  25. RECTL *prclDst, // Target offset and extent
  26. POINTL *pptlSrc, // Source offset
  27. POINTL *pptlMask, // Mask offset
  28. BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush)
  29. POINTL *pptlBrush, // Brush offset (origin)
  30. ROP4 rop4 // Raster operation
  31. )
  32. {
  33. //
  34. // Validate the ROP
  35. //
  36. ASSERTGDI(psoDst != (SURFOBJ *) NULL, "NULL target passed in\n");
  37. ASSERTGDI(prclDst != (PRECTL) NULL, "Target range\n");
  38. ASSERTGDI(prclDst->left <= prclDst->right, "ERROR Target width not ordered\n");
  39. ASSERTGDI(prclDst->top <= prclDst->bottom, "ERROR Target height not ordered\n");
  40. ASSERTGDI(!(ROP4NEEDPAT(rop4) && (pdbrush == (BRUSHOBJ *) NULL)), "EngBitBlt: Pattern\n");
  41. ASSERTGDI(!(ROP4NEEDPAT(rop4) && (pdbrush->iSolidColor == 0xFFFFFFFF) && (pptlBrush == (PPOINTL) NULL)), "EngBitBlt: Pattern offset\n");
  42. ASSERTGDI(!((psoSrc == (SURFOBJ *) NULL) && ROP4NEEDSRC(rop4)), "EngBitBlt: Source\n");
  43. ASSERTGDI(!((pptlSrc == (PPOINTL) NULL) && ROP4NEEDSRC(rop4)), "EngBitBlt: Source offset\n");
  44. PSURFACE pSurfDst = SURFOBJ_TO_SURFACE_NOT_NULL(psoDst);
  45. PSURFACE pSurfSrc = SURFOBJ_TO_SURFACE(psoSrc);
  46. PSURFACE pSurfMask = SURFOBJ_TO_SURFACE(psoMask);
  47. RECTL rclSrc;
  48. ASSERTGDI(pSurfDst->iFormat() != BMF_JPEG, "EngBitBlt: dst BMF_JPEG not supported\n");
  49. ASSERTGDI(pSurfDst->iFormat() != BMF_PNG, "EngBitBlt: dst BMF_PNG not supported\n");
  50. ASSERTGDI(!(ROP4NEEDSRC(rop4) && (pSurfSrc->iFormat() == BMF_JPEG)), "EngBitBlt: src BMF_JPEG not supported\n");
  51. ASSERTGDI(!(ROP4NEEDSRC(rop4) && (pSurfSrc->iFormat() == BMF_PNG)), "EngBitBlt: src BMF_PNG not supported\n");
  52. if (psoDst->iType == STYPE_BITMAP)
  53. {
  54. //
  55. // For profiling purposes, set a flag in the PDEV to indicate that the
  56. // driver punted this call.
  57. //
  58. {
  59. PDEVOBJ po(pSurfDst->hdev());
  60. if (po.bValid())
  61. {
  62. po.vDriverPuntedCall(TRUE);
  63. }
  64. }
  65. //
  66. // Synchronize with the device driver before touching the device surface.
  67. //
  68. {
  69. PDEVOBJ po(pSurfDst->hdev());
  70. po.vSync(psoDst,NULL, 0);
  71. }
  72. //
  73. // inc surface uniq for all cases
  74. //
  75. INC_SURF_UNIQ(pSurfDst);
  76. //
  77. // Quick check for dst and pattern rops, and source copy
  78. //
  79. switch(rop4)
  80. {
  81. case 0x00000000: // DDx (BLACKNESS)
  82. case 0x0000FFFF: // DDxn (WHITENESS)
  83. vDIBSolidBlt(pSurfDst,
  84. prclDst,
  85. pco,
  86. ((rop4 != 0) ? ~0 : 0),
  87. 0);
  88. return(TRUE);
  89. case 0x0000F0F0: // P (PATCOPY)
  90. case 0x00000F0F: // Pn (NOTPATCOPY)
  91. if (pdbrush->iSolidColor != 0xFFFFFFFF)
  92. {
  93. vDIBSolidBlt(pSurfDst,
  94. prclDst,
  95. pco,
  96. (rop4 & 0x00000001) ? ~(pdbrush->iSolidColor) : pdbrush->iSolidColor,
  97. 0);
  98. return(TRUE);
  99. }
  100. if ((pSurfDst->iFormat() == BMF_8BPP) && (rop4 == 0x0000F0F0))
  101. {
  102. //
  103. // We only support 8x8 DIB8 patterns with SRCCOPY right now
  104. //
  105. if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
  106. {
  107. if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
  108. (((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8))
  109. {
  110. vDIBPatBltSrccopy8x8(pSurfDst,
  111. pco,
  112. prclDst,
  113. pdbrush,
  114. pptlBrush,
  115. vPatCpyRect8_8x8);
  116. return(TRUE);
  117. }
  118. }
  119. }
  120. if (pSurfDst->iFormat() >= BMF_8BPP)
  121. {
  122. if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
  123. {
  124. if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
  125. {
  126. vDIBPatBlt(pSurfDst,
  127. pco,
  128. prclDst,
  129. pdbrush,
  130. pptlBrush,
  131. (rop4 == 0x0000F0F0) ? DPA_PATCOPY : DPA_PATNOT);
  132. return(TRUE);
  133. }
  134. }
  135. }
  136. else if ((pSurfDst->iFormat() == BMF_4BPP) &&
  137. (rop4 == 0x0000F0F0))
  138. {
  139. //
  140. // We only support 8x8 DIB4 patterns with SRCCOPY right now
  141. //
  142. if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
  143. {
  144. if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
  145. (((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8))
  146. {
  147. ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 4,
  148. "BBDDI.CXX: lDeltaPat != 4");
  149. vDIBPatBltSrccopy8x8(pSurfDst,
  150. pco,
  151. prclDst,
  152. pdbrush,
  153. pptlBrush,
  154. vPatCpyRect4_8x8);
  155. return(TRUE);
  156. }
  157. }
  158. }
  159. else if ((pSurfDst->iFormat() == BMF_1BPP) &&
  160. (rop4 == 0x0000F0F0))
  161. {
  162. //
  163. // We support 8x8 and 6x6 DIB1 patterns with SRCCOPY
  164. //
  165. if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
  166. {
  167. //
  168. // Look for 8x8 patterns
  169. //
  170. if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
  171. (((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8) )
  172. {
  173. ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 4,
  174. "BBDDI.CXX: lDeltaPat != 4");
  175. vDIBPatBltSrccopy8x8(pSurfDst,
  176. pco,
  177. prclDst,
  178. pdbrush,
  179. pptlBrush,
  180. vPatCpyRect1_8x8 );
  181. return(TRUE);
  182. }
  183. //
  184. // Look for 6x6 patterns
  185. //
  186. if ((((EBRUSHOBJ *)pdbrush)->pengbrush()->cxPat == 6) &&
  187. (((EBRUSHOBJ *)pdbrush)->pengbrush()->cyPat == 6) )
  188. {
  189. ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 8,
  190. "BBDDI.CXX: lDeltaPat != 8");
  191. vDIBnPatBltSrccopy6x6(pSurfDst,
  192. pco,
  193. prclDst,
  194. pdbrush,
  195. pptlBrush,
  196. vPatCpyRect1_6x6 );
  197. return(TRUE);
  198. }
  199. }
  200. }
  201. break;
  202. case 0x00005A5A: // DPx
  203. if (pdbrush->iSolidColor != 0xFFFFFFFF)
  204. {
  205. vDIBSolidBlt(pSurfDst,
  206. prclDst,
  207. pco,
  208. pdbrush->iSolidColor,
  209. 1);
  210. return(TRUE);
  211. }
  212. if (pSurfDst->iFormat() >= BMF_8BPP)
  213. {
  214. if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
  215. {
  216. if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
  217. {
  218. vDIBPatBlt(pSurfDst,
  219. pco,
  220. prclDst,
  221. pdbrush,
  222. pptlBrush,
  223. DPA_PATXOR);
  224. return(TRUE);
  225. }
  226. }
  227. }
  228. break;
  229. //
  230. // Dn degenerates to DPx with a pattern of all ones (0xFFFFFFFF)
  231. //
  232. case 0x00005555: // Dn (DSTINVERT)
  233. vDIBSolidBlt(pSurfDst,
  234. prclDst,
  235. pco,
  236. (ULONG)~0,
  237. 1);
  238. return(TRUE);
  239. //
  240. // 0xCCAA with a mask surface of NULL really means EngTransparentBlt
  241. // or EngDrawStream.
  242. // We do this as an optimization; see the tops of EngTransparentBlt
  243. // and EngDrawStream for details.
  244. //
  245. case 0x0000CCAA: // Transparent blt or DrawStream
  246. if (psoMask == NULL)
  247. {
  248. if(pdbrush->pvRbrush == NULL)
  249. {
  250. rclSrc.left = pptlSrc->x;
  251. rclSrc.right = pptlSrc->x + (prclDst->right - prclDst->left);
  252. rclSrc.top = pptlSrc->y;
  253. rclSrc.bottom = pptlSrc->y + (prclDst->bottom - prclDst->top);
  254. return(EngTransparentBlt(psoDst,
  255. psoSrc,
  256. pco,
  257. pxlo,
  258. prclDst,
  259. &rclSrc,
  260. pdbrush->iSolidColor,
  261. TRUE));
  262. }
  263. else
  264. {
  265. PDRAWSTREAMINFO pdsi = (PDRAWSTREAMINFO) pdbrush->pvRbrush;
  266. pdsi->bCalledFromBitBlt = TRUE;
  267. return(EngDrawStream(psoDst, psoSrc, pco, pxlo, prclDst,
  268. pdsi->pptlDstOffset,
  269. pdsi->ulStreamLength,
  270. pdsi->pvStream,
  271. (DSSTATE*) pdsi));
  272. }
  273. }
  274. break;
  275. //
  276. // We special case source copy since it must be one of the two following cases:
  277. // a) DIB to DIB, which will just call EngCopyBits.
  278. // b) Device format to DIB, which will just call DrvCopyBits.
  279. //
  280. // We also expect source copy to occur A LOT!
  281. //
  282. case 0x0000CCCC:
  283. if (pSurfSrc->iType() == STYPE_BITMAP)
  284. {
  285. return(EngCopyBits(psoDst,
  286. psoSrc,
  287. pco,
  288. pxlo,
  289. prclDst,
  290. pptlSrc));
  291. }
  292. else
  293. {
  294. PDEVOBJ pdoSrc(pSurfSrc->hdev());
  295. return((*PPFNDRV(pdoSrc,CopyBits)) (psoDst,
  296. psoSrc,
  297. pco,
  298. pxlo,
  299. prclDst,
  300. pptlSrc));
  301. }
  302. }
  303. //
  304. // Synchronize with the device driver before touching the device surface.
  305. //
  306. if ((psoSrc != (SURFOBJ *) NULL))
  307. {
  308. PDEVOBJ po(pSurfSrc->hdev());
  309. po.vSync(psoSrc, NULL, 0);
  310. }
  311. //
  312. // We have to create an empty DIB incase DrvCopyBits needs to be performed.
  313. // We also have to have a POINTL for the final blt for use as the source org.
  314. //
  315. SURFMEM SurfDimo;
  316. //
  317. // Handle the Device ==> DIB conversion if required
  318. //
  319. if (ROP4NEEDSRC(rop4) && (pSurfSrc->iType() != STYPE_BITMAP))
  320. {
  321. PDEVOBJ pdoSrc(pSurfSrc->hdev());
  322. //
  323. // Allocate an intermediate DIB for a source.
  324. //
  325. ERECTL erclTmp(0L,
  326. 0L,
  327. prclDst->right - prclDst->left,
  328. prclDst->bottom - prclDst->top);
  329. DEVBITMAPINFO dbmi;
  330. dbmi.iFormat = pSurfDst->iFormat();
  331. dbmi.cxBitmap = erclTmp.right;
  332. dbmi.cyBitmap = erclTmp.bottom;
  333. dbmi.hpal = 0;
  334. dbmi.fl = pSurfSrc->bUMPD() ? UMPD_SURFACE : 0;
  335. if (!SurfDimo.bCreateDIB(&dbmi, NULL))
  336. {
  337. WARNING("bCreateDIB failed in EngBitBlt\n");
  338. return(FALSE);
  339. }
  340. (*PPFNDRV(pdoSrc,CopyBits)) ( (SURFOBJ *) SurfDimo.pSurfobj(),
  341. psoSrc,
  342. (CLIPOBJ *) NULL,
  343. pxlo,
  344. (PRECTL) &erclTmp,
  345. pptlSrc);
  346. //
  347. // Make psoSrc and pptlSrc point to the correct thing.
  348. //
  349. pptlSrc = (POINTL *) &gptl00;
  350. pSurfSrc = SurfDimo.ps;
  351. //
  352. // Color translation has already been performed, so make
  353. // the XLATE an identity.
  354. //
  355. pxlo = &xloIdent;
  356. }
  357. //
  358. // Call BltLnk to perform the ROP
  359. //
  360. if (!BltLnk(pSurfDst,
  361. pSurfSrc,
  362. pSurfMask,
  363. (ECLIPOBJ *) pco,
  364. (XLATE *) pxlo,
  365. prclDst,
  366. pptlSrc,
  367. pptlMask,
  368. pdbrush,
  369. pptlBrush,
  370. rop4)
  371. )
  372. {
  373. WARNING1("BltLnk Returns FALSE\n");
  374. }
  375. }
  376. else
  377. {
  378. //
  379. // We have to do simulations on a device surface
  380. //
  381. return(SimBitBlt(psoDst,psoSrc,psoMask,
  382. pco,pxlo,
  383. prclDst,pptlSrc,pptlMask,
  384. pdbrush,pptlBrush,rop4, NULL));
  385. }
  386. return(TRUE);
  387. }
  388. /******************************Public*Routine******************************\
  389. * EngEraseSurface
  390. *
  391. * Asks GDI to erase the surface. The rcl will be filled with
  392. * iColor.
  393. *
  394. * History:
  395. * 02-May-1991 -by- Patrick Haluptzok patrickh
  396. * Wrote it.
  397. \**************************************************************************/
  398. BOOL
  399. EngEraseSurface(
  400. SURFOBJ *pso,
  401. PRECTL prcl,
  402. ULONG iColor
  403. )
  404. {
  405. PSURFACE pSurf = (SURFACE *)(SURFOBJ_TO_SURFACE(pso));
  406. if(pSurf == 0)
  407. return FALSE;
  408. ASSERTGDI(prcl != (PRECTL) NULL, "ERROR EngEraseSurface1");
  409. ASSERTGDI(prcl->left >= 0, "ERROR EngEraseSurface2");
  410. ASSERTGDI(prcl->top >= 0, "ERROR EngEraseSurface3");
  411. ASSERTGDI(prcl->right <= pSurf->sizl().cx, "ERROR EngEraseSurface4");
  412. ASSERTGDI(prcl->bottom <= pSurf->sizl().cy, "ERROR EngEraseSurface5");
  413. //
  414. // Synchronize with the device driver before touching the device surface.
  415. //
  416. {
  417. PDEVOBJ po(pSurf->hdev());
  418. po.vSync(pso,NULL, 0);
  419. }
  420. vDIBSolidBlt(pSurf, prcl, (CLIPOBJ *) NULL, iColor, 0);
  421. return(TRUE);
  422. }
  423. /******************************Public*Routine******************************\
  424. * SimBitBlt
  425. *
  426. * The engine sends EngBitBlt here if a DEVICE surface is passed as psoTrg
  427. *
  428. * History:
  429. * 23-Feb-1994 -by- Eric Kutter [erick]
  430. * Made it callable from other functions - allow device to device blts.
  431. *
  432. * 09-Sep-1992 -by- Donald Sidoroff [donalds]
  433. * Made it callable from EngBitBlt only.
  434. *
  435. * 07-Sep-1991 -by- Patrick Haluptzok patrickh
  436. * Wrote it.
  437. \**************************************************************************/
  438. BOOL
  439. SimBitBlt(
  440. SURFOBJ *psoDst, // Target surface
  441. SURFOBJ *psoSrc, // Source surface
  442. SURFOBJ *psoMask, // Mask
  443. CLIPOBJ *pco, // Clip through this
  444. XLATEOBJ *pxlo, // Color translation
  445. RECTL *prclDst, // Target offset and extent
  446. POINTL *pptlSrc, // Source offset
  447. POINTL *pptlMask, // Mask offset
  448. BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush)
  449. POINTL *pptlBrush, // Brush offset (origin)
  450. ROP4 rop4, // Raster operation
  451. PVOID pdlo // for unlock if necessary
  452. )
  453. {
  454. BOOL bNeedSrc = ROP4NEEDSRC(rop4);
  455. PSURFACE pSurfDst = (SURFACE *)(SURFOBJ_TO_SURFACE(psoDst));
  456. PSURFACE pSurfSrc = (SURFACE *)(SURFOBJ_TO_SURFACE(psoSrc));
  457. PDEVOBJ pdoDst(pSurfDst->hdev());
  458. ASSERTGDI(pdoDst.bValid(), "EngPuntBlt poDst.bValid");
  459. //
  460. // if source and destination are both engine managed
  461. // bitmaps, then BitBlt directly
  462. //
  463. if (
  464. (pSurfDst->iType() == STYPE_BITMAP) &&
  465. ((!bNeedSrc) || (pSurfSrc->iType() == STYPE_BITMAP)) &&
  466. (psoMask == NULL)
  467. )
  468. {
  469. BOOL bReturn;
  470. if (!pdoDst.bUMPD())
  471. {
  472. bReturn = (*(pSurfDst->pfnBitBlt())) (
  473. psoDst,
  474. psoSrc,
  475. psoMask,
  476. pco,
  477. pxlo,
  478. prclDst,
  479. pptlSrc,
  480. pptlMask,
  481. pdbrush,
  482. pptlBrush,
  483. rop4);
  484. }
  485. else
  486. {
  487. bReturn = EngBitBlt(
  488. psoDst,
  489. psoSrc,
  490. psoMask,
  491. pco,
  492. pxlo,
  493. prclDst,
  494. pptlSrc,
  495. pptlMask,
  496. pdbrush,
  497. pptlBrush,
  498. rop4);
  499. }
  500. return(bReturn);
  501. }
  502. //
  503. // For profiling purposes, set a flag in the PDEV to indicate that the
  504. // driver punted this call.
  505. //
  506. {
  507. PDEVOBJ po(pSurfDst->hdev());
  508. if (po.bValid())
  509. {
  510. po.vDriverPuntedCall(TRUE);
  511. }
  512. }
  513. // Get the bounds of the destination rectangle
  514. RECTL rclDstBounds;
  515. if( pSurfDst->iType() == STYPE_DEVICE &&
  516. pdoDst.bValid() && pdoDst.bMetaDriver())
  517. {
  518. rclDstBounds.left = pdoDst.pptlOrigin()->x;
  519. rclDstBounds.top = pdoDst.pptlOrigin()->y;
  520. rclDstBounds.right = pdoDst.pptlOrigin()->x + pSurfDst->sizl().cx;
  521. rclDstBounds.bottom = pdoDst.pptlOrigin()->y + pSurfDst->sizl().cy;
  522. }
  523. else
  524. {
  525. rclDstBounds.left = 0;
  526. rclDstBounds.top = 0;
  527. rclDstBounds.right = pSurfDst->sizl().cx;
  528. rclDstBounds.bottom = pSurfDst->sizl().cy;
  529. }
  530. //
  531. // Set up new rectangle clipped to destination surface. Clip source
  532. // pointl and mask pointl accordingly.
  533. //
  534. RECTL rclReduced = *prclDst;
  535. POINTL ptlSrc;
  536. POINTL ptlMask;
  537. if (bNeedSrc)
  538. {
  539. ptlSrc = *pptlSrc;
  540. }
  541. if (psoMask != NULL)
  542. {
  543. ptlMask = *pptlMask;
  544. }
  545. if (rclReduced.top < rclDstBounds.top)
  546. {
  547. ptlSrc.y += (rclDstBounds.top-rclReduced.top);
  548. ptlMask.y += (rclDstBounds.top-rclReduced.top);
  549. rclReduced.top = rclDstBounds.top;
  550. }
  551. if (rclReduced.left < rclDstBounds.left)
  552. {
  553. ptlSrc.x += (rclDstBounds.left-rclReduced.left);
  554. ptlMask.x += (rclDstBounds.left-rclReduced.left);
  555. rclReduced.left = rclDstBounds.left;
  556. }
  557. if (rclReduced.bottom > rclDstBounds.bottom)
  558. {
  559. rclReduced.bottom = rclDstBounds.bottom;
  560. }
  561. if (rclReduced.right > rclDstBounds.right)
  562. {
  563. rclReduced.right = rclDstBounds.right;
  564. }
  565. if( rclReduced.top >= rclReduced.bottom ||
  566. rclReduced.left >= rclReduced.right )
  567. {
  568. // Destination rectangle is outside of the
  569. // destination surface
  570. return TRUE;
  571. }
  572. //
  573. // Ok we clipped everything to our reduced rectangle, now use the clipped offsets.
  574. //
  575. prclDst = &rclReduced;
  576. pptlSrc = &ptlSrc;
  577. pptlMask = &ptlMask;
  578. //
  579. // Set up our temporary DIB rectangle to blt to.
  580. //
  581. ERECTL erclDst(0, 0, prclDst->right - prclDst->left,
  582. prclDst->bottom - prclDst->top);
  583. //
  584. // iDitherFormat must match destination format
  585. //
  586. if (pSurfDst->iFormat() != pdoDst.iDitherFormat())
  587. {
  588. WARNING("SimBitBlt: pSurfDst->iFormat != pdoDst.iDitherFormat\n");
  589. return(FALSE);
  590. }
  591. //
  592. // We have to create an empty DIB incase DrvCopyBits needs to be performed.
  593. // We also have to have a POINTL for the final blt for use as the source org.
  594. //
  595. SURFMEM SurfDimoSrc;
  596. //
  597. // Handle the Device ==> DIB conversion if required
  598. //
  599. if (bNeedSrc && (pSurfSrc->iType() != STYPE_BITMAP))
  600. {
  601. PDEVOBJ pdoSrc(pSurfSrc->hdev());
  602. //
  603. // Allocate an intermediate DIB for a source.
  604. //
  605. DEVBITMAPINFO dbmiSrc;
  606. dbmiSrc.iFormat = pdoDst.iDitherFormat();
  607. dbmiSrc.cxBitmap = erclDst.right;
  608. dbmiSrc.cyBitmap = erclDst.bottom;
  609. dbmiSrc.hpal = 0;
  610. dbmiSrc.fl = pSurfSrc->bUMPD() ? UMPD_SURFACE : 0;
  611. if (!SurfDimoSrc.bCreateDIB(&dbmiSrc, NULL))
  612. {
  613. WARNING("Failed dimoSrc memory alloc in EngPuntBlt\n");
  614. return(FALSE);
  615. }
  616. (*PPFNGET(pdoSrc,CopyBits,pSurfSrc->flags())) (SurfDimoSrc.pSurfobj(),
  617. psoSrc,
  618. (CLIPOBJ *) NULL,
  619. pxlo,
  620. (PRECTL) &erclDst,
  621. pptlSrc);
  622. //
  623. // Make psoSrc and pptlSrc point to the correct thing.
  624. //
  625. pptlSrc = &gptl00;
  626. psoSrc = SurfDimoSrc.pSurfobj();
  627. //
  628. // Color translation has already been performed, so make
  629. // the XLATEOBJ an identity.
  630. //
  631. pxlo = &xloIdent;
  632. }
  633. DEVBITMAPINFO dbmiDst;
  634. dbmiDst.iFormat = pdoDst.iDitherFormat();
  635. dbmiDst.cxBitmap = erclDst.right;
  636. dbmiDst.cyBitmap = erclDst.bottom;
  637. dbmiDst.hpal = 0;
  638. dbmiDst.fl = pSurfDst->bUMPD() ? UMPD_SURFACE : 0;
  639. SURFMEM SurfDimoDst;
  640. SurfDimoDst.bCreateDIB(&dbmiDst, NULL);
  641. if (!SurfDimoDst.bValid())
  642. {
  643. return(FALSE);
  644. }
  645. POINTL ptlDst;
  646. ptlDst.x = prclDst->left;
  647. ptlDst.y = prclDst->top;
  648. POINTL ptlBrush;
  649. if (pptlBrush != (POINTL *) NULL)
  650. {
  651. ptlBrush.x = pptlBrush->x - prclDst->left;
  652. ptlBrush.y = pptlBrush->y - prclDst->top;
  653. }
  654. //
  655. // if we are going out to the user mode printer driver
  656. // unlock the DEVLOCKBLTOBJ. Only the src might be locked
  657. // and from here we are only going to deal with the temp src dib
  658. // so it's safe to unlock here.
  659. //
  660. if (pdoDst.bPrinter() && pdlo)
  661. {
  662. ((DEVLOCKBLTOBJ *)pdlo)->vUnLock();
  663. }
  664. // WINBUG #206475 bhouse 10-18-2000 Old potential perf bug
  665. // We should only copy the destination if the ROP requires
  666. // destination data.
  667. (*PPFNGET(pdoDst,CopyBits,pSurfDst->flags())) (SurfDimoDst.pSurfobj(),
  668. psoDst,
  669. (CLIPOBJ *) NULL,
  670. &xloIdent,
  671. &erclDst,
  672. &ptlDst);
  673. ASSERTGDI(SurfDimoDst.ps->iType() == STYPE_BITMAP, "ERROR dimoDst.iType 1");
  674. //
  675. // Call off to BitBlt, if it fails who cares.
  676. //
  677. EngBitBlt(SurfDimoDst.pSurfobj(),
  678. psoSrc,
  679. psoMask,
  680. (ECLIPOBJ *) NULL,
  681. pxlo,
  682. &erclDst,
  683. pptlSrc,
  684. pptlMask,
  685. pdbrush,
  686. &ptlBrush,
  687. rop4);
  688. //
  689. // Inc output surface uniqueness
  690. //
  691. INC_SURF_UNIQ(pSurfDst);
  692. return((*PPFNGET(pdoDst,CopyBits,pSurfDst->flags())) (
  693. psoDst,
  694. SurfDimoDst.pSurfobj(),
  695. pco,
  696. &xloIdent,
  697. prclDst,
  698. &gptl00));
  699. }