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.

1912 lines
51 KiB

  1. /*****************************************************************************
  2. *
  3. * bitmaps - Entry points for Win32 to Win 16 converter
  4. *
  5. * History:
  6. * Sep 1992 -by- Hock San Lee [hockl]
  7. * Big rewrite.
  8. *
  9. * Copyright 1991 Microsoft Corp
  10. *****************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. HDC hdcMakeCompatibleDC(LPXFORM lpxform);
  14. HBITMAP CreateMonoDib(LPBITMAPINFO pbmi, CONST BYTE * pjBits, UINT iUsage);
  15. BOOL bEmitBitmap(PLOCALDC pLocalDC, HBITMAP hbm,
  16. LONG xDst, LONG yDst, LONG cxDst, LONG cyDst,
  17. LONG xSrc, LONG ySrc, LONG cxSrc, LONG cySrc, DWORD rop);
  18. #define ABS(A) ((A) < 0 ? (-(A)) : (A))
  19. BOOL APIENTRY DoStretchBltAlt
  20. (
  21. PLOCALDC pLocalDC,
  22. LONG xDst,
  23. LONG yDst,
  24. LONG cxDst,
  25. LONG cyDst,
  26. DWORD rop,
  27. LONG xSrc,
  28. LONG ySrc,
  29. LONG cxSrc,
  30. LONG cySrc,
  31. HDC hdcSrc,
  32. HBITMAP hbmSrc,
  33. PXFORM pxformSrc
  34. );
  35. BOOL APIENTRY DoRotatedStretchBlt
  36. (
  37. PLOCALDC pLocalDC,
  38. LONG xDst,
  39. LONG yDst,
  40. LONG cxDst,
  41. LONG cyDst,
  42. DWORD rop,
  43. LONG xSrc,
  44. LONG ySrc,
  45. LONG cxSrc,
  46. LONG cySrc,
  47. PXFORM pxformSrc,
  48. DWORD iUsageSrc,
  49. PBITMAPINFO lpBitmapInfo,
  50. DWORD cbBitmapInfo,
  51. LPBYTE lpBits
  52. );
  53. BOOL APIENTRY DoMaskBltNoSrc
  54. (
  55. PLOCALDC pLocalDC,
  56. LONG xDst,
  57. LONG yDst,
  58. LONG cxDst,
  59. LONG cyDst,
  60. DWORD rop4,
  61. PXFORM pxformSrc,
  62. LONG xMask,
  63. LONG yMask,
  64. DWORD iUsageMask,
  65. PBITMAPINFO lpBitmapInfoMask,
  66. DWORD cbBitmapInfoMask,
  67. LPBYTE lpBitsMask,
  68. DWORD cbBitsMask
  69. );
  70. /***************************************************************************
  71. * SetDIBitsToDevice - Win32 to Win16 Metafile Converter Entry Point
  72. *
  73. * CR2: Notes...
  74. * The xDib, yDib, cxDib, & cyDib are in device units. These must be
  75. * converted to logical units for the stretchblt.
  76. **************************************************************************/
  77. BOOL APIENTRY DoSetDIBitsToDevice
  78. (
  79. PLOCALDC pLocalDC,
  80. LONG xDst,
  81. LONG yDst,
  82. LONG xDib,
  83. LONG yDib,
  84. LONG cxDib,
  85. LONG cyDib,
  86. DWORD iUsage,
  87. DWORD iStartScan,
  88. DWORD cScans,
  89. LPBITMAPINFO lpBitmapInfo,
  90. DWORD cbBitmapInfo,
  91. LPBYTE lpBits,
  92. DWORD cbBits
  93. )
  94. {
  95. BOOL b ;
  96. LPBITMAPINFO pbmi;
  97. POINTL ptlDst;
  98. RECTL rclDst;
  99. LONG height;
  100. b = FALSE;
  101. if (!cbBitmapInfo)
  102. return(FALSE);
  103. // Adjust the height of the bitmap we're going to Blt.
  104. pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfo);
  105. if (pbmi == (LPBITMAPINFO) NULL)
  106. goto dsdbd_exit;
  107. RtlCopyMemory(pbmi, lpBitmapInfo, cbBitmapInfo);
  108. pbmi->bmiHeader.biHeight = cScans;
  109. pbmi->bmiHeader.biSizeImage = cbBits;
  110. // We will convert it into a StretchBlt call. But first we have to
  111. // transform the destination rectangle. In SetDIBitsToDevice, the destination
  112. // rectangle is in device units but in StretchBlt, it is in logical units.
  113. // Transform the destination origin to the device units on the original device.
  114. ptlDst.x = xDst;
  115. ptlDst.y = yDst;
  116. if (!bXformRWorldToRDev(pLocalDC, &ptlDst, 1))
  117. goto dsdbd_exit;
  118. // Transform the destination rectangle to record time world coordinates.
  119. rclDst.left = ptlDst.x;
  120. rclDst.top = ptlDst.y;
  121. rclDst.right = ptlDst.x + cxDib;
  122. rclDst.bottom = ptlDst.y + cyDib;
  123. if (!bXformRDevToRWorld(pLocalDC, (PPOINTL) &rclDst, 2))
  124. goto dsdbd_exit;
  125. // WINBUG #99421 4-17-2000 bhouse Top-Down DIBs are not supported properly
  126. // We need to check for negative heights and adjust appropriately
  127. height = ABS(pbmi->bmiHeader.biHeight);
  128. b = DoStretchBlt
  129. (
  130. pLocalDC,
  131. rclDst.left,
  132. rclDst.top,
  133. rclDst.right - rclDst.left,
  134. rclDst.bottom - rclDst.top,
  135. SRCCOPY,
  136. xDib,
  137. // dib to bitmap units
  138. height - yDib - cyDib + (LONG) iStartScan,
  139. cxDib,
  140. cyDib,
  141. &xformIdentity, // source is in device units
  142. iUsage,
  143. pbmi,
  144. cbBitmapInfo,
  145. lpBits,
  146. cbBits
  147. );
  148. dsdbd_exit:
  149. if (pbmi)
  150. LocalFree(pbmi);
  151. return(b);
  152. }
  153. /***************************************************************************
  154. * StretchDIBits - Win32 to Win16 Metafile Converter Entry Point
  155. **************************************************************************/
  156. BOOL APIENTRY DoStretchDIBits
  157. (
  158. PLOCALDC pLocalDC,
  159. LONG xDst,
  160. LONG yDst,
  161. LONG cxDst,
  162. LONG cyDst,
  163. DWORD rop,
  164. LONG xDib,
  165. LONG yDib,
  166. LONG cxDib,
  167. LONG cyDib,
  168. DWORD iUsage,
  169. LPBITMAPINFO lpBitmapInfo,
  170. DWORD cbBitmapInfo,
  171. LPBYTE lpBits,
  172. DWORD cbBits
  173. )
  174. {
  175. BOOL b ;
  176. LONG height;
  177. // WINBUG #99421 4-17-2000 bhouse Top-Down DIBs are not supported properly
  178. // We need to check for negative heights and adjust appropriately
  179. height = ABS(lpBitmapInfo->bmiHeader.biHeight);
  180. b = DoStretchBlt
  181. (
  182. pLocalDC,
  183. xDst,
  184. yDst,
  185. cxDst,
  186. cyDst,
  187. rop,
  188. xDib,
  189. ISSOURCEINROP3(rop)
  190. // dib to bitmap units
  191. ? height - yDib - cyDib
  192. : 0,
  193. cxDib,
  194. cyDib,
  195. &xformIdentity, // source is in device units
  196. iUsage,
  197. lpBitmapInfo,
  198. cbBitmapInfo,
  199. lpBits,
  200. cbBits
  201. );
  202. return(b) ;
  203. }
  204. /***************************************************************************
  205. * StretchBltAlt
  206. **************************************************************************/
  207. BOOL APIENTRY DoStretchBltAlt
  208. (
  209. PLOCALDC pLocalDC,
  210. LONG xDst,
  211. LONG yDst,
  212. LONG cxDst,
  213. LONG cyDst,
  214. DWORD rop,
  215. LONG xSrc,
  216. LONG ySrc,
  217. LONG cxSrc,
  218. LONG cySrc,
  219. HDC hdcSrc,
  220. HBITMAP hbmSrc,
  221. PXFORM pxformSrc
  222. )
  223. {
  224. BITMAPINFOHEADER bmih;
  225. DWORD cbBitmapInfo;
  226. LPBITMAPINFO lpBitmapInfo;
  227. DWORD cbBits;
  228. LPBYTE lpBits;
  229. BOOL b;
  230. b = FALSE;
  231. lpBitmapInfo = (LPBITMAPINFO) NULL;
  232. lpBits = (LPBYTE) NULL;
  233. if (!ISSOURCEINROP3(rop))
  234. return
  235. (
  236. DoStretchBlt
  237. (
  238. pLocalDC,
  239. xDst,
  240. yDst,
  241. cxDst,
  242. cyDst,
  243. rop,
  244. 0,
  245. 0,
  246. 0,
  247. 0,
  248. (PXFORM) NULL,
  249. 0,
  250. (PBITMAPINFO) NULL,
  251. 0,
  252. (LPBYTE) NULL,
  253. 0
  254. )
  255. );
  256. bmih.biSize = sizeof(BITMAPINFOHEADER);
  257. bmih.biBitCount = 0; // don't fill in color table
  258. bmih.biCompression = BI_RGB;
  259. if (!GetDIBits(hdcSrc,
  260. hbmSrc,
  261. 0,
  262. 0,
  263. (LPBYTE) NULL,
  264. (LPBITMAPINFO) &bmih,
  265. DIB_RGB_COLORS))
  266. goto dsba_exit;
  267. // Compute size of the bitmap info with color table.
  268. cbBitmapInfo= sizeof(BITMAPINFOHEADER);
  269. if (bmih.biBitCount == 16 || bmih.biBitCount == 32)
  270. cbBitmapInfo += 3 * sizeof(DWORD);
  271. else if (bmih.biClrUsed)
  272. cbBitmapInfo += bmih.biClrUsed * sizeof(RGBQUAD);
  273. else if (bmih.biBitCount < 16)
  274. cbBitmapInfo += (1 << bmih.biBitCount) * sizeof(RGBQUAD);
  275. // Compute size of the buffer required for bitmap bits.
  276. if (bmih.biSizeImage)
  277. cbBits = bmih.biSizeImage;
  278. else
  279. cbBits = CJSCAN(bmih.biWidth,bmih.biPlanes, bmih.biBitCount) *
  280. ABS(bmih.biHeight);
  281. lpBitmapInfo = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfo);
  282. if (lpBitmapInfo == (LPBITMAPINFO) NULL)
  283. goto dsba_exit;
  284. lpBits = (LPBYTE) LocalAlloc(LMEM_FIXED, cbBits);
  285. if (lpBits == (LPBYTE) NULL)
  286. goto dsba_exit;
  287. // Get bitmap info and bits.
  288. *(PBITMAPINFOHEADER) lpBitmapInfo = bmih;
  289. if (!GetDIBits(hdcSrc,
  290. hbmSrc,
  291. 0,
  292. (UINT) bmih.biHeight,
  293. lpBits,
  294. lpBitmapInfo,
  295. DIB_RGB_COLORS))
  296. goto dsba_exit;
  297. // Call DoStretchBlt.
  298. b = DoStretchBlt
  299. (
  300. pLocalDC,
  301. xDst,
  302. yDst,
  303. cxDst,
  304. cyDst,
  305. rop,
  306. xSrc,
  307. ySrc,
  308. cxSrc,
  309. cySrc,
  310. pxformSrc,
  311. DIB_RGB_COLORS,
  312. lpBitmapInfo,
  313. cbBitmapInfo,
  314. lpBits,
  315. cbBits
  316. );
  317. dsba_exit:
  318. if (lpBitmapInfo)
  319. LocalFree((HANDLE) lpBitmapInfo);
  320. if (lpBits)
  321. LocalFree((HANDLE) lpBits);
  322. return(b);
  323. }
  324. /***************************************************************************
  325. * StretchBlt - Win32 to Win16 Metafile Converter Entry Point
  326. **************************************************************************/
  327. BOOL APIENTRY DoStretchBlt
  328. (
  329. PLOCALDC pLocalDC,
  330. LONG xDst,
  331. LONG yDst,
  332. LONG cxDst,
  333. LONG cyDst,
  334. DWORD rop,
  335. LONG xSrc,
  336. LONG ySrc,
  337. LONG cxSrc,
  338. LONG cySrc,
  339. PXFORM pxformSrc,
  340. DWORD iUsageSrc,
  341. PBITMAPINFO lpBitmapInfo,
  342. DWORD cbBitmapInfo,
  343. LPBYTE lpBits,
  344. DWORD cbBits
  345. )
  346. {
  347. BOOL b;
  348. RECTL rclDst,
  349. rclSrc;
  350. // Handle strange destination transform separately.
  351. if (pLocalDC->flags & STRANGE_XFORM)
  352. return
  353. (
  354. DoRotatedStretchBlt
  355. (
  356. pLocalDC,
  357. xDst,
  358. yDst,
  359. cxDst,
  360. cyDst,
  361. rop,
  362. xSrc,
  363. ySrc,
  364. cxSrc,
  365. cySrc,
  366. pxformSrc,
  367. iUsageSrc,
  368. lpBitmapInfo,
  369. cbBitmapInfo,
  370. lpBits
  371. )
  372. );
  373. // Do stretchblt with a simple destination transform.
  374. // Translate the dest rectangle
  375. rclDst.left = xDst;
  376. rclDst.top = yDst;
  377. rclDst.right = xDst + cxDst;
  378. rclDst.bottom = yDst + cyDst;
  379. if (!bXformRWorldToPPage(pLocalDC, (PPOINTL) &rclDst, 2))
  380. return(FALSE);
  381. // Handle stretchblt without source
  382. if (!ISSOURCEINROP3(rop))
  383. {
  384. // Emit the Win16 metafile record.
  385. b = bEmitWin16BitBltNoSrc(pLocalDC,
  386. (SHORT) rclDst.left,
  387. (SHORT) rclDst.top,
  388. (SHORT) (rclDst.right - rclDst.left),
  389. (SHORT) (rclDst.bottom - rclDst.top),
  390. rop);
  391. return(b);
  392. }
  393. // Handle stretchblt with source
  394. // Note: Both Win32 and Win16 DIB Bitmaps are DWord aligned.
  395. // Make sure the source xform is valid.
  396. // The source is not allowed to have a rotation or shear.
  397. if (bRotationTest(pxformSrc) == TRUE)
  398. {
  399. RIP("MF3216: DoStretchBlt - Invalid source xform\n");
  400. SetLastError(ERROR_INVALID_DATA);
  401. return(FALSE);
  402. }
  403. // Translate the source rectangle. Win3.1 assumes that the
  404. // source rectangle is in bitmap units.
  405. rclSrc.left = xSrc;
  406. rclSrc.top = ySrc;
  407. rclSrc.right = xSrc + cxSrc;
  408. rclSrc.bottom = ySrc + cySrc;
  409. if (!bXformWorkhorse((PPOINTL) &rclSrc, 2, pxformSrc))
  410. return(FALSE);
  411. // The win3.1 StretchBlt metafile record only accepts win3.1 standard
  412. // bitmap with DIB_RGB_COLORS usage. If this is not the case, we have
  413. // to convert it to a standard bitmap.
  414. if (iUsageSrc != DIB_RGB_COLORS
  415. || lpBitmapInfo->bmiHeader.biPlanes != 1
  416. || !(lpBitmapInfo->bmiHeader.biBitCount == 1
  417. || lpBitmapInfo->bmiHeader.biBitCount == 4
  418. || lpBitmapInfo->bmiHeader.biBitCount == 8
  419. || lpBitmapInfo->bmiHeader.biBitCount == 24)
  420. || lpBitmapInfo->bmiHeader.biCompression != BI_RGB)
  421. {
  422. HBITMAP hbmSrc;
  423. DWORD fdwInit;
  424. b = FALSE;
  425. hbmSrc = (HBITMAP) 0;
  426. if( ( lpBitmapInfo->bmiHeader.biCompression == BI_RGB ) ||
  427. ( lpBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS ) )
  428. {
  429. fdwInit = CBM_INIT | CBM_CREATEDIB;
  430. }
  431. else
  432. {
  433. fdwInit = CBM_INIT;
  434. }
  435. // Create the source bitmap.
  436. // Use the helper DC in CreateDIBitmap so that the colors get bind correctly.
  437. if (!(hbmSrc = CreateDIBitmap(
  438. pLocalDC->hdcHelper,
  439. (LPBITMAPINFOHEADER) lpBitmapInfo,
  440. fdwInit,
  441. lpBits,
  442. lpBitmapInfo,
  443. (UINT) iUsageSrc)))
  444. goto dsb_internal_exit;
  445. // Emit the bitmap.
  446. b = bEmitBitmap(pLocalDC,
  447. hbmSrc,
  448. rclDst.left,
  449. rclDst.top,
  450. rclDst.right - rclDst.left,
  451. rclDst.bottom - rclDst.top,
  452. rclSrc.left,
  453. rclSrc.top,
  454. rclSrc.right - rclSrc.left,
  455. rclSrc.bottom - rclSrc.top,
  456. rop);
  457. dsb_internal_exit:
  458. if (hbmSrc)
  459. DeleteObject(hbmSrc);
  460. }
  461. else
  462. {
  463. // Handle the standard formats.
  464. // Emit a Win16 metafile record.
  465. // Recalculate size of bitmap info with color
  466. // table to trim any extra data that wouldn't
  467. // be skipped properly during playback.
  468. cbBitmapInfo = lpBitmapInfo->bmiHeader.biSize;
  469. if (lpBitmapInfo->bmiHeader.biClrUsed <= 256)
  470. cbBitmapInfo += lpBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);
  471. else if (lpBitmapInfo->bmiHeader.biBitCount < 16)
  472. cbBitmapInfo += (1 << lpBitmapInfo->bmiHeader.biBitCount) * sizeof(RGBQUAD);
  473. b = bEmitWin16StretchBlt(pLocalDC,
  474. (SHORT) rclDst.left,
  475. (SHORT) rclDst.top,
  476. (SHORT) (rclDst.right - rclDst.left),
  477. (SHORT) (rclDst.bottom - rclDst.top),
  478. (SHORT) rclSrc.left,
  479. (SHORT) rclSrc.top,
  480. (SHORT) (rclSrc.right - rclSrc.left),
  481. (SHORT) (rclSrc.bottom - rclSrc.top),
  482. rop,
  483. lpBitmapInfo,
  484. cbBitmapInfo,
  485. lpBits,
  486. cbBits);
  487. }
  488. return(b);
  489. }
  490. BOOL APIENTRY DoRotatedStretchBlt
  491. (
  492. PLOCALDC pLocalDC,
  493. LONG xDst,
  494. LONG yDst,
  495. LONG cxDst,
  496. LONG cyDst,
  497. DWORD rop,
  498. LONG xSrc,
  499. LONG ySrc,
  500. LONG cxSrc,
  501. LONG cySrc,
  502. PXFORM pxformSrc,
  503. DWORD iUsageSrc,
  504. PBITMAPINFO lpBitmapInfo,
  505. DWORD cbBitmapInfo,
  506. LPBYTE lpBits
  507. )
  508. {
  509. BOOL b;
  510. POINTL aptlDst[4];
  511. RECTL rclBndDst;
  512. HDC hdcShadow, hdcSrc;
  513. HBITMAP hbmShadow, hbmShadowOld, hbmSrc, hbmSrcOld;
  514. PBITMAPINFO pbmiShadow;
  515. b = FALSE;
  516. hdcShadow = hdcSrc = (HDC) 0;
  517. hbmShadow = hbmShadowOld = hbmSrc = hbmSrcOld = (HBITMAP) 0;
  518. pbmiShadow = (PBITMAPINFO) NULL;
  519. // First, compute the bounds of the destination rectangle.
  520. aptlDst[0].x = xDst;
  521. aptlDst[0].y = yDst;
  522. aptlDst[1].x = xDst + cxDst;
  523. aptlDst[1].y = yDst;
  524. aptlDst[2].x = xDst + cxDst;
  525. aptlDst[2].y = yDst + cyDst;
  526. aptlDst[3].x = xDst;
  527. aptlDst[3].y = yDst + cyDst;
  528. if (!bXformRWorldToPPage(pLocalDC, aptlDst, 4))
  529. goto drsb_exit;
  530. rclBndDst.left = min(aptlDst[0].x,min(aptlDst[1].x,min(aptlDst[2].x,aptlDst[3].x)));
  531. rclBndDst.top = min(aptlDst[0].y,min(aptlDst[1].y,min(aptlDst[2].y,aptlDst[3].y)));
  532. rclBndDst.right = max(aptlDst[0].x,max(aptlDst[1].x,max(aptlDst[2].x,aptlDst[3].x)));
  533. rclBndDst.bottom = max(aptlDst[0].y,max(aptlDst[1].y,max(aptlDst[2].y,aptlDst[3].y)));
  534. // Prepare the source if any.
  535. if (ISSOURCEINROP3(rop))
  536. {
  537. // Create a compatible shadow DC with the destination transform.
  538. if (!(hdcShadow = hdcMakeCompatibleDC(&pLocalDC->xformRWorldToPPage)))
  539. goto drsb_exit;
  540. // Create a shadow bitmap the size of the destination rectangle bounds.
  541. // Use the helper DC in CreateDIBitmap so that the colors get bind correctly.
  542. pbmiShadow = (PBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfo);
  543. if (pbmiShadow == (PBITMAPINFO) NULL)
  544. goto drsb_exit;
  545. RtlCopyMemory(pbmiShadow, lpBitmapInfo, cbBitmapInfo);
  546. pbmiShadow->bmiHeader.biWidth = rclBndDst.right - rclBndDst.left;
  547. pbmiShadow->bmiHeader.biHeight = rclBndDst.bottom - rclBndDst.top;
  548. pbmiShadow->bmiHeader.biSizeImage = 0;
  549. if (!(hbmShadow = CreateDIBitmap(pLocalDC->hdcHelper,
  550. (LPBITMAPINFOHEADER) pbmiShadow, CBM_CREATEDIB,
  551. (LPBYTE) NULL, pbmiShadow, iUsageSrc)))
  552. goto drsb_exit;
  553. // Select the bitmap.
  554. if (!(hbmShadowOld = (HBITMAP) SelectObject(hdcShadow, hbmShadow)))
  555. goto drsb_exit;
  556. // Create a compatible source DC with the given source transform.
  557. if (!(hdcSrc = hdcMakeCompatibleDC(pxformSrc)))
  558. goto drsb_exit;
  559. // Create the source bitmap.
  560. // Use the helper DC in CreateDIBitmap so that the colors get bind correctly.
  561. if (!(hbmSrc = CreateDIBitmap(pLocalDC->hdcHelper,
  562. (LPBITMAPINFOHEADER) lpBitmapInfo,
  563. CBM_INIT | CBM_CREATEDIB,
  564. lpBits,
  565. (LPBITMAPINFO) lpBitmapInfo,
  566. (UINT) iUsageSrc)))
  567. goto drsb_exit;
  568. // Select the bitmap.
  569. if (!(hbmSrcOld = (HBITMAP) SelectObject(hdcSrc, hbmSrc)))
  570. goto drsb_exit;
  571. // Set up the viewport origin of the shadow DC so that the destination
  572. // rectangle will map into coordinates within the shadow bitmap.
  573. OffsetViewportOrgEx(hdcShadow, (int) -rclBndDst.left,
  574. (int) -rclBndDst.top, (LPPOINT) NULL);
  575. // Stretch the source to the shadow.
  576. if (!StretchBlt
  577. (
  578. hdcShadow,
  579. (int) xDst,
  580. (int) yDst,
  581. (int) cxDst,
  582. (int) cyDst,
  583. hdcSrc,
  584. (int) xSrc,
  585. (int) ySrc,
  586. (int) cxSrc,
  587. (int) cySrc,
  588. SRCCOPY
  589. )
  590. )
  591. goto drsb_exit;
  592. // Deselect the shadow bitmap.
  593. if (!SelectObject(hdcShadow, hbmShadowOld))
  594. goto drsb_exit;
  595. }
  596. // Save the DC so that we can restore the clipping when we are done
  597. if (!DoSaveDC(pLocalDC))
  598. goto drsb_exit;
  599. // Set up the clipping rectangle on the destination.
  600. if (!DoClipRect(pLocalDC, xDst, yDst,
  601. xDst + cxDst, yDst + cyDst, EMR_INTERSECTCLIPRECT))
  602. {
  603. (void) DoRestoreDC(pLocalDC, -1);
  604. goto drsb_exit;
  605. }
  606. // Blt the shadow to the destination.
  607. // Emit a Win16 metafile record.
  608. if (ISSOURCEINROP3(rop))
  609. b = bEmitBitmap(pLocalDC,
  610. hbmShadow,
  611. rclBndDst.left,
  612. rclBndDst.top,
  613. rclBndDst.right - rclBndDst.left,
  614. rclBndDst.bottom - rclBndDst.top,
  615. 0,
  616. 0,
  617. rclBndDst.right - rclBndDst.left,
  618. rclBndDst.bottom - rclBndDst.top,
  619. rop);
  620. else
  621. b = bEmitWin16BitBltNoSrc(pLocalDC,
  622. (SHORT) rclBndDst.left,
  623. (SHORT) rclBndDst.top,
  624. (SHORT) (rclBndDst.right - rclBndDst.left),
  625. (SHORT) (rclBndDst.bottom - rclBndDst.top),
  626. rop);
  627. // Restore the clipping region.
  628. (void) DoRestoreDC(pLocalDC, -1);
  629. // Cleanup
  630. drsb_exit:
  631. if (hbmShadowOld)
  632. SelectObject(hdcShadow, hbmShadowOld);
  633. if (hbmShadow)
  634. DeleteObject(hbmShadow);
  635. if (hdcShadow)
  636. DeleteDC(hdcShadow);
  637. if (hbmSrcOld)
  638. SelectObject(hdcSrc, hbmSrcOld);
  639. if (hbmSrc)
  640. DeleteObject(hbmSrc);
  641. if (hdcSrc)
  642. DeleteDC(hdcSrc);
  643. if (pbmiShadow)
  644. LocalFree((HANDLE) pbmiShadow);
  645. return(b);
  646. }
  647. /*****************************************************************************
  648. * hdcMakeCompatibleDC
  649. * Create a compatible DC with the given transform.
  650. ****************************************************************************/
  651. HDC hdcMakeCompatibleDC(LPXFORM lpxform)
  652. {
  653. HDC hdc;
  654. hdc = CreateCompatibleDC((HDC) 0);
  655. if(hdc == 0)
  656. {
  657. RIP("MF3216: hdcMakeCompatibleDC, CreateCompatibleDC failed\n");
  658. return (HDC)0;
  659. }
  660. // Must be in the advanced graphics mode to modify the world transform.
  661. SetGraphicsMode(hdc, GM_ADVANCED);
  662. // Set the transform.
  663. if (!SetWorldTransform(hdc, lpxform))
  664. {
  665. DeleteDC(hdc);
  666. RIP("MF3216: hdcMakeCompatibleDC, SetWorldTransform failed\n");
  667. return((HDC) 0);
  668. }
  669. return(hdc);
  670. }
  671. /***************************************************************************
  672. * bEmitBitmap
  673. **************************************************************************/
  674. BOOL bEmitBitmap
  675. (
  676. PLOCALDC pLocalDC,
  677. HBITMAP hbm,
  678. LONG xDst,
  679. LONG yDst,
  680. LONG cxDst,
  681. LONG cyDst,
  682. LONG xSrc,
  683. LONG ySrc,
  684. LONG cxSrc,
  685. LONG cySrc,
  686. DWORD rop
  687. )
  688. {
  689. BITMAPINFOHEADER bmih;
  690. DWORD cbBitmapInfo;
  691. LPBITMAPINFO lpBitmapInfo;
  692. DWORD cbBits;
  693. LPBYTE lpBits;
  694. BOOL b;
  695. b = FALSE;
  696. lpBitmapInfo = (LPBITMAPINFO) NULL;
  697. lpBits = (LPBYTE) NULL;
  698. bmih.biSize = sizeof(BITMAPINFOHEADER);
  699. bmih.biBitCount = 0; // don't fill in color table
  700. bmih.biCompression = BI_RGB;
  701. if (!GetDIBits(pLocalDC->hdcHelper, hbm, 0, 0,
  702. (LPBYTE) NULL, (LPBITMAPINFO) &bmih, DIB_RGB_COLORS))
  703. goto eb_exit;
  704. // Compute size of the bitmap info with color table.
  705. cbBitmapInfo= sizeof(BITMAPINFOHEADER);
  706. if (bmih.biPlanes != 1 || bmih.biBitCount == 16 || bmih.biBitCount == 32)
  707. {
  708. bmih.biPlanes = 1;
  709. bmih.biBitCount = 24;
  710. bmih.biCompression = BI_RGB;
  711. bmih.biSizeImage = 0;
  712. bmih.biClrUsed = 0;
  713. bmih.biClrImportant = 0;
  714. }
  715. else if (bmih.biClrUsed)
  716. cbBitmapInfo += bmih.biClrUsed * sizeof(RGBQUAD);
  717. else if (bmih.biBitCount < 16)
  718. cbBitmapInfo += (1 << bmih.biBitCount) * sizeof(RGBQUAD);
  719. // Compute size of the buffer required for bitmap bits.
  720. if (bmih.biSizeImage)
  721. cbBits = bmih.biSizeImage;
  722. else
  723. cbBits = CJSCAN(bmih.biWidth,bmih.biPlanes, bmih.biBitCount) *
  724. ABS(bmih.biHeight);
  725. lpBitmapInfo = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfo);
  726. if (lpBitmapInfo == (LPBITMAPINFO) NULL)
  727. goto eb_exit;
  728. lpBits = (LPBYTE) LocalAlloc(LMEM_FIXED, cbBits);
  729. if (lpBits == (LPBYTE) NULL)
  730. goto eb_exit;
  731. // Get bitmap info and bits.
  732. *(PBITMAPINFOHEADER) lpBitmapInfo = bmih;
  733. if (!GetDIBits(pLocalDC->hdcHelper,
  734. hbm,
  735. 0,
  736. (UINT) ABS(bmih.biHeight),
  737. lpBits,
  738. lpBitmapInfo,
  739. DIB_RGB_COLORS))
  740. goto eb_exit;
  741. // Emit the metafile record.
  742. b = bEmitWin16StretchBlt(pLocalDC,
  743. (SHORT) xDst,
  744. (SHORT) yDst,
  745. (SHORT) cxDst,
  746. (SHORT) cyDst,
  747. (SHORT) xSrc,
  748. (SHORT) ySrc,
  749. (SHORT) cxSrc,
  750. (SHORT) cySrc,
  751. rop,
  752. lpBitmapInfo,
  753. cbBitmapInfo,
  754. lpBits,
  755. cbBits);
  756. eb_exit:
  757. if (lpBitmapInfo)
  758. LocalFree((HANDLE) lpBitmapInfo);
  759. if (lpBits)
  760. LocalFree((HANDLE) lpBits);
  761. return(b);
  762. }
  763. /***************************************************************************
  764. * MaskBlt - Win32 to Win16 Metafile Converter Entry Point
  765. **************************************************************************/
  766. BOOL APIENTRY DoMaskBlt
  767. (
  768. PLOCALDC pLocalDC,
  769. LONG xDst,
  770. LONG yDst,
  771. LONG cxDst,
  772. LONG cyDst,
  773. DWORD rop4,
  774. LONG xSrc,
  775. LONG ySrc,
  776. PXFORM pxformSrc,
  777. DWORD iUsageSrc,
  778. PBITMAPINFO lpBitmapInfoSrc,
  779. DWORD cbBitmapInfoSrc,
  780. LPBYTE lpBitsSrc,
  781. DWORD cbBitsSrc,
  782. LONG xMask,
  783. LONG yMask,
  784. DWORD iUsageMask,
  785. PBITMAPINFO lpBitmapInfoMask,
  786. DWORD cbBitmapInfoMask,
  787. LPBYTE lpBitsMask,
  788. DWORD cbBitsMask
  789. )
  790. {
  791. BOOL b;
  792. DWORD rop1;
  793. DWORD rop0;
  794. HDC hdcMask, hdcSrc;
  795. HBITMAP hbmMask, hbmMaskOld, hbmSrc, hbmSrcOld;
  796. RECTL rclMask;
  797. b = FALSE;
  798. hdcMask = hdcSrc = (HDC) 0;
  799. hbmMask = hbmMaskOld = hbmSrc = hbmSrcOld = (HBITMAP) 0;
  800. rop0 = rop4 >> 8; // rop for 0's
  801. rop1 = rop4 & 0xFF0000; // rop for 1's
  802. // If no mask is given, the mask is assumed to contain all 1's.
  803. // This is equivalent to a BitBlt using the low rop.
  804. if (!cbBitmapInfoMask)
  805. return
  806. (
  807. DoStretchBlt
  808. (
  809. pLocalDC,
  810. xDst,
  811. yDst,
  812. cxDst,
  813. cyDst,
  814. rop1,
  815. xSrc,
  816. ySrc,
  817. cxDst,
  818. cyDst,
  819. pxformSrc,
  820. iUsageSrc,
  821. lpBitmapInfoSrc,
  822. cbBitmapInfoSrc,
  823. lpBitsSrc,
  824. cbBitsSrc
  825. )
  826. );
  827. // Handle MaskBlt with no source bitmap.
  828. if (!ISSOURCEINROP3(rop4))
  829. return
  830. (
  831. DoMaskBltNoSrc
  832. (
  833. pLocalDC,
  834. xDst,
  835. yDst,
  836. cxDst,
  837. cyDst,
  838. rop4,
  839. pxformSrc,
  840. xMask,
  841. yMask,
  842. iUsageMask,
  843. lpBitmapInfoMask,
  844. cbBitmapInfoMask,
  845. lpBitsMask,
  846. cbBitsMask
  847. )
  848. );
  849. // Create a compatible mask DC.
  850. if (!(hdcMask = CreateCompatibleDC((HDC) 0)))
  851. goto dmb_exit;
  852. // Must be in the advanced graphics mode to modify the world transform.
  853. SetGraphicsMode(hdcMask, GM_ADVANCED);
  854. // Create the mask bitmap.
  855. // Make it as big as the source and initialize it.
  856. // Create the mask bitmap as big as the source bitmap.
  857. if (!(hbmMask = CreateBitmap((int) lpBitmapInfoSrc->bmiHeader.biWidth,
  858. (int) lpBitmapInfoSrc->bmiHeader.biHeight,
  859. 1, 1, (CONST VOID *) NULL)))
  860. goto dmb_exit;
  861. // Select the bitmap.
  862. if (!(hbmMaskOld = (HBITMAP) SelectObject(hdcMask, hbmMask)))
  863. goto dmb_exit;
  864. // Initialize the mask bitmap to 0's.
  865. if (!PatBlt(hdcMask,0,0,(int) lpBitmapInfoSrc->bmiHeader.biWidth,
  866. (int) lpBitmapInfoSrc->bmiHeader.biHeight,BLACKNESS))
  867. goto dmb_exit;
  868. // Compute the mask rectangle.
  869. // The mask bitmap is aligned against the source device rectangle.
  870. rclMask.left = xSrc;
  871. rclMask.top = ySrc;
  872. rclMask.right = xSrc + cxDst;
  873. rclMask.bottom = ySrc + cyDst;
  874. if (!bXformWorkhorse((PPOINTL) &rclMask, 2, pxformSrc))
  875. goto dmb_exit;
  876. if (rclMask.left > rclMask.right)
  877. rclMask.left = rclMask.right /* + 1 */;// align the mask against the left edge
  878. if (rclMask.top > rclMask.bottom)
  879. rclMask.top = rclMask.bottom /* + 1 */;// align the mask against the top edge
  880. // Set the mask bits.
  881. if (!StretchDIBits(hdcMask,
  882. (int) rclMask.left - xMask,
  883. (int) rclMask.top - yMask,
  884. (int) lpBitmapInfoMask->bmiHeader.biWidth,
  885. (int) lpBitmapInfoMask->bmiHeader.biHeight,
  886. (int) 0,
  887. (int) 0,
  888. (int) lpBitmapInfoMask->bmiHeader.biWidth,
  889. (int) lpBitmapInfoMask->bmiHeader.biHeight,
  890. (CONST VOID *) lpBitsMask,
  891. (LPBITMAPINFO) lpBitmapInfoMask,
  892. (UINT) iUsageMask,
  893. SRCCOPY))
  894. goto dmb_exit;
  895. // Set the source transform in the mask DC.
  896. if (!SetWorldTransform(hdcMask, pxformSrc))
  897. goto dmb_exit;
  898. // Create a compatible source DC with the given source transform.
  899. if (!(hdcSrc = hdcMakeCompatibleDC(pxformSrc)))
  900. goto dmb_exit;
  901. // Create the source bitmap.
  902. // We cannot use CBM_CREATEDIB option here because index 0 does not
  903. // neccesarily contain black and index 15 or 255 does not have to be white.
  904. // We need a compatible bitmap that contain the standard color table so
  905. // that we can perform the following rop operations to emulate the maskblt.
  906. // Gdi uses rgb colors to perform rop operations in dibs, not color indices!
  907. // The helper DC is needed to create the compatible format bitmap.
  908. if (!(hbmSrc = CreateDIBitmap(pLocalDC->hdcHelper,
  909. (LPBITMAPINFOHEADER) lpBitmapInfoSrc,
  910. CBM_INIT,
  911. lpBitsSrc,
  912. (LPBITMAPINFO) lpBitmapInfoSrc,
  913. (UINT) iUsageSrc)))
  914. goto dmb_exit;
  915. // Select the bitmap.
  916. if (!(hbmSrcOld = (HBITMAP) SelectObject(hdcSrc, hbmSrc)))
  917. goto dmb_exit;
  918. // We need to handle the low rop (mask bit 1) and high rop (mask bit 0)
  919. // separately. For each rop, we need to go through two passes.
  920. //
  921. // For the low rop (mask bit 1), we use the following rop table:
  922. //
  923. // P S D | R1 R2
  924. // ------+--------
  925. // 0 0 0 | 0 x
  926. // 0 0 1 | 1 x
  927. // 0 1 0 | x 0
  928. // 0 1 1 | x 1
  929. // 1 0 0 | 0 x
  930. // 1 0 1 | 1 x
  931. // 1 1 0 | x 0
  932. // 1 1 1 | x 1
  933. //
  934. // In the first pass, we AND the mask to the source bitmap to remove
  935. // the mask 0 bits. This is then used to get the result (R1) for the
  936. // bitblt involving source 1's.
  937. //
  938. // In the second pass, we OR the NOT of the mask to the source bitmap
  939. // to obtain the source 0 bits. This is then used to get the result (R2)
  940. // for the bitblt involving source 0's.
  941. // AND the mask to the source bitmap to remove the mask 0 bits.
  942. if (!BitBlt(hdcSrc,
  943. (int) xSrc, (int) ySrc,
  944. (int) cxDst, (int) cyDst,
  945. hdcMask,
  946. (int) xSrc, (int) ySrc,
  947. SRCAND))
  948. goto dmb_exit;
  949. // Get the result (R1) for the bits involving source 1's.
  950. if (!DoStretchBltAlt
  951. (
  952. pLocalDC,
  953. xDst,
  954. yDst,
  955. cxDst,
  956. cyDst,
  957. (rop1 & 0xCC0000) | 0x220000,
  958. xSrc,
  959. ySrc,
  960. cxDst,
  961. cyDst,
  962. hdcSrc,
  963. hbmSrc,
  964. pxformSrc
  965. )
  966. )
  967. goto dmb_exit;
  968. // OR the NOT of the mask to the source bitmap to obtain the source 0 bits.
  969. if (!BitBlt(hdcSrc,
  970. (int) xSrc, (int) ySrc,
  971. (int) cxDst, (int) cyDst,
  972. hdcMask,
  973. (int) xSrc, (int) ySrc,
  974. MERGEPAINT))
  975. goto dmb_exit;
  976. // Get the result (R2) for the bitblt involving source 0's.
  977. if (!DoStretchBltAlt
  978. (
  979. pLocalDC,
  980. xDst,
  981. yDst,
  982. cxDst,
  983. cyDst,
  984. (rop1 & 0x330000) | 0x880000,
  985. xSrc,
  986. ySrc,
  987. cxDst,
  988. cyDst,
  989. hdcSrc,
  990. hbmSrc,
  991. pxformSrc
  992. )
  993. )
  994. goto dmb_exit;
  995. // For the high rop (mask bit 0), we use the following rop table:
  996. //
  997. // P S D | R1 R2
  998. // ------+--------
  999. // 0 0 0 | 0 x
  1000. // 0 0 1 | 1 x
  1001. // 0 1 0 | x 0
  1002. // 0 1 1 | x 1
  1003. // 1 0 0 | 0 x
  1004. // 1 0 1 | 1 x
  1005. // 1 1 0 | x 0
  1006. // 1 1 1 | x 1
  1007. //
  1008. // In the first pass, we AND the NOT of the mask to the source bitmap to remove
  1009. // the mask 1 bits. This is then used to get the result (R1) for the
  1010. // bitblt involving source 1's.
  1011. //
  1012. // In the second pass, we OR the mask to the source bitmap
  1013. // to obtain the source 0 bits. This is then used to get the result (R2)
  1014. // for the bitblt involving source 0's.
  1015. // Restore the source bits.
  1016. if (!SelectObject(hdcSrc, hbmSrcOld))
  1017. goto dmb_exit;
  1018. if (!SetDIBits(pLocalDC->hdcHelper,
  1019. hbmSrc,
  1020. 0,
  1021. (UINT) lpBitmapInfoSrc->bmiHeader.biHeight,
  1022. (CONST VOID *) lpBitsSrc,
  1023. (LPBITMAPINFO) lpBitmapInfoSrc,
  1024. (UINT) iUsageSrc))
  1025. goto dmb_exit;
  1026. if (!SelectObject(hdcSrc, hbmSrc))
  1027. goto dmb_exit;
  1028. // AND the NOT of the mask to the source bitmap to remove the mask 1 bits.
  1029. if (!BitBlt(hdcSrc,
  1030. (int) xSrc, (int) ySrc,
  1031. (int) cxDst, (int) cyDst,
  1032. hdcMask,
  1033. (int) xSrc, (int) ySrc,
  1034. 0x220326)) // DSna
  1035. goto dmb_exit;
  1036. // Get the result (R1) for the bits involving source 1's.
  1037. if (!DoStretchBltAlt
  1038. (
  1039. pLocalDC,
  1040. xDst,
  1041. yDst,
  1042. cxDst,
  1043. cyDst,
  1044. (rop0 & 0xCC0000) | 0x220000,
  1045. xSrc,
  1046. ySrc,
  1047. cxDst,
  1048. cyDst,
  1049. hdcSrc,
  1050. hbmSrc,
  1051. pxformSrc
  1052. )
  1053. )
  1054. goto dmb_exit;
  1055. // OR the mask to the source bitmap to obtain the source 0 bits.
  1056. if (!BitBlt(hdcSrc,
  1057. (int) xSrc, (int) ySrc,
  1058. (int) cxDst, (int) cyDst,
  1059. hdcMask,
  1060. (int) xSrc, (int) ySrc,
  1061. SRCPAINT))
  1062. goto dmb_exit;
  1063. // Get the result (R2) for the bitblt involving source 0's.
  1064. if (!DoStretchBltAlt
  1065. (
  1066. pLocalDC,
  1067. xDst,
  1068. yDst,
  1069. cxDst,
  1070. cyDst,
  1071. (rop0 & 0x330000) | 0x880000,
  1072. xSrc,
  1073. ySrc,
  1074. cxDst,
  1075. cyDst,
  1076. hdcSrc,
  1077. hbmSrc,
  1078. pxformSrc
  1079. )
  1080. )
  1081. goto dmb_exit;
  1082. b = TRUE;
  1083. // Cleanup.
  1084. dmb_exit:
  1085. if (hbmMaskOld)
  1086. SelectObject(hdcMask, hbmMaskOld);
  1087. if (hbmMask)
  1088. DeleteObject(hbmMask);
  1089. if (hdcMask)
  1090. DeleteDC(hdcMask);
  1091. if (hbmSrcOld)
  1092. SelectObject(hdcSrc, hbmSrcOld);
  1093. if (hbmSrc)
  1094. DeleteObject(hbmSrc);
  1095. if (hdcSrc)
  1096. DeleteDC(hdcSrc);
  1097. return(b);
  1098. }
  1099. /***************************************************************************
  1100. * MaskBltNoSrc
  1101. **************************************************************************/
  1102. BOOL APIENTRY DoMaskBltNoSrc
  1103. (
  1104. PLOCALDC pLocalDC,
  1105. LONG xDst,
  1106. LONG yDst,
  1107. LONG cxDst,
  1108. LONG cyDst,
  1109. DWORD rop4,
  1110. PXFORM pxformSrc,
  1111. LONG xMask,
  1112. LONG yMask,
  1113. DWORD iUsageMask,
  1114. PBITMAPINFO lpBitmapInfoMask,
  1115. DWORD cbBitmapInfoMask,
  1116. LPBYTE lpBitsMask,
  1117. DWORD cbBitsMask
  1118. )
  1119. {
  1120. BOOL b;
  1121. DWORD rop1;
  1122. DWORD rop0;
  1123. HDC hdcMask;
  1124. HBITMAP hbmMask, hbmMaskOld;
  1125. RECTL rclMask;
  1126. LONG cxMask, cyMask;
  1127. b = FALSE;
  1128. hdcMask = (HDC) 0;
  1129. hbmMask = hbmMaskOld = (HBITMAP) 0;
  1130. rop0 = rop4 >> 8; // rop for 0's
  1131. rop1 = rop4 & 0xFF0000; // rop for 1's
  1132. // When no source bitmap is required in the rop4, the mask is used
  1133. // as the source in that the low rop is applied to the corresponding
  1134. // mask 1 bits and the high rop is applied to mask 0 bits. The source
  1135. // transform is used to determine the mask rectangle to be used.
  1136. // Create a compatible mask DC.
  1137. if (!(hdcMask = CreateCompatibleDC((HDC) 0)))
  1138. goto dmbns_exit;
  1139. // Create the mask bitmap.
  1140. if (!(hbmMask = CreateMonoDib(lpBitmapInfoMask, lpBitsMask, (UINT) iUsageMask)))
  1141. goto dmbns_exit;
  1142. // Select the bitmap.
  1143. if (!(hbmMaskOld = (HBITMAP) SelectObject(hdcMask, hbmMask)))
  1144. goto dmbns_exit;
  1145. // Compute the mask extents.
  1146. rclMask.left = 0;
  1147. rclMask.top = 0;
  1148. rclMask.right = cxDst;
  1149. rclMask.bottom = cyDst;
  1150. if (!bXformWorkhorse((PPOINTL) &rclMask, 2, pxformSrc))
  1151. goto dmbns_exit;
  1152. cxMask = rclMask.right - rclMask.left;
  1153. cyMask = rclMask.bottom - rclMask.top;
  1154. // Align the mask rectangle.
  1155. if (cxMask < 0)
  1156. xMask = xMask - cxMask + 1;
  1157. if (cyMask < 0)
  1158. yMask = yMask - cyMask + 1;
  1159. // We need to handle the low rop (mask bit 1) and high rop (mask bit 0)
  1160. // separately.
  1161. //
  1162. // For the low rop (mask bit 1), we use the following rop table:
  1163. //
  1164. // P M D | R
  1165. // ------+---
  1166. // 0 0 0 | 0
  1167. // 0 0 1 | 1
  1168. // 0 1 0 | x
  1169. // 0 1 1 | x
  1170. // 1 0 0 | 0
  1171. // 1 0 1 | 1
  1172. // 1 1 0 | x
  1173. // 1 1 1 | x
  1174. //
  1175. // The above rop will give us the result for bits that correspond to 1's
  1176. // in the mask bitmap. The destination bits that correspond to the 0 mask
  1177. // bits will not be changed. We effectively treat the mask as the source
  1178. // in the operation.
  1179. // Get the result (R) for the bits involving mask 1's.
  1180. if (!DoStretchBltAlt
  1181. (
  1182. pLocalDC,
  1183. xDst,
  1184. yDst,
  1185. cxDst,
  1186. cyDst,
  1187. (rop1 & 0xCC0000) | 0x220000,
  1188. xMask,
  1189. yMask,
  1190. cxMask,
  1191. cyMask,
  1192. hdcMask,
  1193. hbmMask,
  1194. &xformIdentity
  1195. )
  1196. )
  1197. goto dmbns_exit;
  1198. #if 0
  1199. DoStretchBlt
  1200. (
  1201. pLocalDC,
  1202. xDst,
  1203. yDst,
  1204. cxDst,
  1205. cyDst,
  1206. (rop1 & 0xCC0000) | 0x220000,
  1207. xMask,
  1208. yMask,
  1209. cxMask,
  1210. cyMask,
  1211. &xformIdentity,
  1212. iUsageMask,
  1213. lpBitmapInfoMask,
  1214. cbBitmapInfoMask,
  1215. lpBitsMask,
  1216. cbBitsMask
  1217. )
  1218. #endif // 0
  1219. // For the high rop (mask bit 0), we use the following rop table:
  1220. //
  1221. // P M D | R
  1222. // ------+---
  1223. // 0 0 0 | x
  1224. // 0 0 1 | x
  1225. // 0 1 0 | 0
  1226. // 0 1 1 | 1
  1227. // 1 0 0 | x
  1228. // 1 0 1 | x
  1229. // 1 1 0 | 0
  1230. // 1 1 1 | 1
  1231. //
  1232. // The above rop will give us the result for bits that correspond to 0's
  1233. // in the mask bitmap. The destination bits that correspond to the 1 mask
  1234. // bits will not be changed. We effectively treat the mask as the source
  1235. // in the operation.
  1236. // Get the result (R) for the bits involving mask 0's.
  1237. if (!DoStretchBltAlt
  1238. (
  1239. pLocalDC,
  1240. xDst,
  1241. yDst,
  1242. cxDst,
  1243. cyDst,
  1244. (rop0 & 0x330000) | 0x880000,
  1245. xMask,
  1246. yMask,
  1247. cxMask,
  1248. cyMask,
  1249. hdcMask,
  1250. hbmMask,
  1251. &xformIdentity
  1252. )
  1253. )
  1254. goto dmbns_exit;
  1255. #if 0
  1256. DoStretchBlt
  1257. (
  1258. pLocalDC,
  1259. xDst,
  1260. yDst,
  1261. cxDst,
  1262. cyDst,
  1263. (rop0 & 0x330000) | 0x880000,
  1264. xMask,
  1265. yMask,
  1266. cxMask,
  1267. cyMask,
  1268. &xformIdentity,
  1269. iUsageMask,
  1270. lpBitmapInfoMask,
  1271. cbBitmapInfoMask,
  1272. lpBitsMask,
  1273. cbBitsMask
  1274. )
  1275. #endif // 0
  1276. b = TRUE;
  1277. // Cleanup.
  1278. dmbns_exit:
  1279. if (hbmMaskOld)
  1280. SelectObject(hdcMask, hbmMaskOld);
  1281. if (hbmMask)
  1282. DeleteObject(hbmMask);
  1283. if (hdcMask)
  1284. DeleteDC(hdcMask);
  1285. return(b);
  1286. }
  1287. /***************************************************************************
  1288. * PlgBlt - Win32 to Win16 Metafile Converter Entry Point
  1289. **************************************************************************/
  1290. BOOL APIENTRY DoPlgBlt
  1291. (
  1292. PLOCALDC pLocalDC,
  1293. PPOINTL pptlDst,
  1294. LONG xSrc,
  1295. LONG ySrc,
  1296. LONG cxSrc,
  1297. LONG cySrc,
  1298. PXFORM pxformSrc,
  1299. DWORD iUsageSrc,
  1300. PBITMAPINFO lpBitmapInfoSrc,
  1301. DWORD cbBitmapInfoSrc,
  1302. LPBYTE lpBitsSrc,
  1303. DWORD cbBitsSrc,
  1304. LONG xMask,
  1305. LONG yMask,
  1306. DWORD iUsageMask,
  1307. PBITMAPINFO lpBitmapInfoMask,
  1308. DWORD cbBitmapInfoMask,
  1309. LPBYTE lpBitsMask,
  1310. DWORD cbBitsMask
  1311. )
  1312. {
  1313. BOOL b, bMask;
  1314. DWORD rop4;
  1315. HDC hdcSrc, hdcSrcRDev;
  1316. PBITMAPINFO pbmiSrcRDev, pbmiMaskRDev;
  1317. LPBYTE lpBitsSrcRDev, lpBitsMaskRDev;
  1318. DWORD cbBitsSrcRDev, cbBitsMaskRDev;
  1319. HBITMAP hbmMask, hbmMaskRDev, hbmSrc, hbmSrcRDev, hbmSrcOld, hbmSrcRDevOld;
  1320. RECTL rclBndRDev;
  1321. POINTL aptlDst[4];
  1322. POINT ptMask;
  1323. BITMAPINFOHEADER bmihMask;
  1324. // We are going to convert the PlgBlt into a MaskBlt. This can be done
  1325. // by converting the source and mask bitmaps to the device space of the
  1326. // recording device and then maskblt the result.
  1327. b = FALSE;
  1328. hdcSrc = hdcSrcRDev = (HDC) 0;
  1329. hbmMask = hbmMaskRDev = hbmSrc = hbmSrcRDev = hbmSrcOld = hbmSrcRDevOld = (HBITMAP) 0;
  1330. pbmiSrcRDev = pbmiMaskRDev = (PBITMAPINFO) NULL;
  1331. lpBitsSrcRDev = lpBitsMaskRDev = (LPBYTE) NULL;
  1332. bMask = (cbBitmapInfoMask != 0);
  1333. rop4 = 0xAACC0000; // rop for MaskBlt
  1334. // First, we transform the destination parallelogram to the device space
  1335. // of the recording device. This device parallelogram is then used in
  1336. // plgblt'ing the source and mask bitmaps to the device space of the
  1337. // recording device.
  1338. aptlDst[0] = pptlDst[0];
  1339. aptlDst[1] = pptlDst[1];
  1340. aptlDst[2] = pptlDst[2];
  1341. aptlDst[3].x = aptlDst[1].x + aptlDst[2].x - aptlDst[0].x;
  1342. aptlDst[3].y = aptlDst[1].y + aptlDst[2].y - aptlDst[0].y;
  1343. if (!bXformRWorldToRDev(pLocalDC, aptlDst, 4))
  1344. goto dpb_exit;
  1345. // Find the bounding rectangle of the parallelogram in the recording
  1346. // device space. This rectangle is used as the basis of the MaskBlt call.
  1347. rclBndRDev.left = min(aptlDst[0].x,min(aptlDst[1].x,min(aptlDst[2].x,aptlDst[3].x)));
  1348. rclBndRDev.top = min(aptlDst[0].y,min(aptlDst[1].y,min(aptlDst[2].y,aptlDst[3].y)));
  1349. rclBndRDev.right = max(aptlDst[0].x,max(aptlDst[1].x,max(aptlDst[2].x,aptlDst[3].x)));
  1350. rclBndRDev.bottom = max(aptlDst[0].y,max(aptlDst[1].y,max(aptlDst[2].y,aptlDst[3].y)));
  1351. // Offset the device parallelogram to the origin.
  1352. aptlDst[0].x -= rclBndRDev.left; aptlDst[0].y -= rclBndRDev.top;
  1353. aptlDst[1].x -= rclBndRDev.left; aptlDst[1].y -= rclBndRDev.top;
  1354. aptlDst[2].x -= rclBndRDev.left; aptlDst[2].y -= rclBndRDev.top;
  1355. aptlDst[3].x -= rclBndRDev.left; aptlDst[3].y -= rclBndRDev.top;
  1356. // Create the source bitmap in the recording device space for MaskBlt.
  1357. // The size of the source bitmap is that of rclBndRDev.
  1358. // The source image is then plgblt'd into the device parallelogram.
  1359. // PlgBlt always takes a source bitmap.
  1360. // Create the original source.
  1361. if (!(hdcSrc = hdcMakeCompatibleDC(pxformSrc)))
  1362. goto dpb_exit;
  1363. if (!(hbmSrc = CreateDIBitmap(hdcSrc,
  1364. (LPBITMAPINFOHEADER) lpBitmapInfoSrc,
  1365. CBM_INIT | CBM_CREATEDIB,
  1366. lpBitsSrc,
  1367. (LPBITMAPINFO) lpBitmapInfoSrc,
  1368. (UINT) iUsageSrc)))
  1369. goto dpb_exit;
  1370. if (!(hbmSrcOld = (HBITMAP) SelectObject(hdcSrc, hbmSrc)))
  1371. goto dpb_exit;
  1372. // Create the source for MaskBlt.
  1373. if (!(hdcSrcRDev = CreateCompatibleDC((HDC) 0)))
  1374. goto dpb_exit;
  1375. pbmiSrcRDev = (PBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfoSrc);
  1376. if (pbmiSrcRDev == (PBITMAPINFO) NULL)
  1377. goto dpb_exit;
  1378. RtlCopyMemory(pbmiSrcRDev, lpBitmapInfoSrc, cbBitmapInfoSrc);
  1379. pbmiSrcRDev->bmiHeader.biWidth = rclBndRDev.right - rclBndRDev.left + 1;
  1380. pbmiSrcRDev->bmiHeader.biHeight = rclBndRDev.bottom - rclBndRDev.top + 1;
  1381. pbmiSrcRDev->bmiHeader.biSizeImage = 0;
  1382. if (!(hbmSrcRDev = CreateDIBitmap(hdcSrcRDev, (LPBITMAPINFOHEADER) pbmiSrcRDev,
  1383. CBM_CREATEDIB, (LPBYTE) NULL, pbmiSrcRDev, iUsageSrc)))
  1384. goto dpb_exit;
  1385. if (!(hbmSrcRDevOld = (HBITMAP) SelectObject(hdcSrcRDev, hbmSrcRDev)))
  1386. goto dpb_exit;
  1387. // PlgBlt the original source bitmap into the source bitmap for MaskBlt.
  1388. if (!PlgBlt(hdcSrcRDev, (LPPOINT) aptlDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, (HBITMAP) NULL, 0, 0))
  1389. goto dpb_exit;
  1390. // Retrieve the source bits for MaskBlt.
  1391. // Get biSizeImage!
  1392. if (!GetDIBits(hdcSrcRDev, hbmSrcRDev, 0, 0, (LPBYTE) NULL, pbmiSrcRDev, iUsageSrc))
  1393. goto dpb_exit;
  1394. // Compute size of the buffer required for source bits.
  1395. if (pbmiSrcRDev->bmiHeader.biSizeImage)
  1396. cbBitsSrcRDev = pbmiSrcRDev->bmiHeader.biSizeImage;
  1397. else
  1398. cbBitsSrcRDev = CJSCAN(pbmiSrcRDev->bmiHeader.biWidth,
  1399. pbmiSrcRDev->bmiHeader.biPlanes,
  1400. pbmiSrcRDev->bmiHeader.biBitCount)
  1401. * ABS(pbmiSrcRDev->bmiHeader.biHeight);
  1402. lpBitsSrcRDev = (LPBYTE) LocalAlloc(LMEM_FIXED, cbBitsSrcRDev);
  1403. if (lpBitsSrcRDev == (LPBYTE) NULL)
  1404. goto dpb_exit;
  1405. // Get the source bits.
  1406. if (!GetDIBits(hdcSrcRDev, hbmSrcRDev, 0, (UINT) pbmiSrcRDev->bmiHeader.biHeight,
  1407. lpBitsSrcRDev, pbmiSrcRDev, iUsageSrc))
  1408. goto dpb_exit;
  1409. // Create the mask bitmap in the recording device space for MaskBlt.
  1410. // The size of the mask bitmap is that of rclBndRDev.
  1411. // The mask image is then plgblt'd into the device parallelogram.
  1412. // If a mask is not given, create one that describes the parallelogram
  1413. // for the source.
  1414. if (bMask)
  1415. {
  1416. // Create the original mask.
  1417. if (!(hbmMask = CreateMonoDib(lpBitmapInfoMask, lpBitsMask, (UINT) iUsageMask)))
  1418. goto dpb_exit;
  1419. if (!SelectObject(hdcSrc, hbmMask))
  1420. goto dpb_exit;
  1421. }
  1422. else
  1423. {
  1424. // Create a mask describing the original source bitmap.
  1425. ASSERTGDI(sizeof(BITMAPINFOHEADER) == 0x28,
  1426. "MF3216: DoPlgBlt, BITMAPINFOHEADER has changed!\n");
  1427. iUsageMask = DIB_PAL_INDICES;
  1428. cbBitmapInfoMask = 0x28;
  1429. lpBitmapInfoMask = (PBITMAPINFO) &bmihMask;
  1430. bmihMask.biSize = 0x28;
  1431. bmihMask.biWidth = lpBitmapInfoSrc->bmiHeader.biWidth;
  1432. bmihMask.biHeight = lpBitmapInfoSrc->bmiHeader.biHeight;
  1433. bmihMask.biPlanes = 1;
  1434. bmihMask.biBitCount = 1;
  1435. bmihMask.biCompression = BI_RGB;
  1436. bmihMask.biSizeImage = 0;
  1437. bmihMask.biXPelsPerMeter = 0;
  1438. bmihMask.biYPelsPerMeter = 0;
  1439. bmihMask.biClrUsed = 0;
  1440. bmihMask.biClrImportant = 0;
  1441. if (!(hbmMask = CreateBitmap((int) bmihMask.biWidth,
  1442. (int) bmihMask.biHeight, 1, 1, (CONST VOID *) NULL)))
  1443. goto dpb_exit;
  1444. if (!SelectObject(hdcSrc, hbmMask))
  1445. goto dpb_exit;
  1446. // Initialize the mask bitmap to 1's.
  1447. if (!PatBlt(hdcSrc,0,0,(int)bmihMask.biWidth,(int)bmihMask.biHeight,WHITENESS))
  1448. goto dpb_exit;
  1449. }
  1450. // Create the mask for MaskBlt.
  1451. pbmiMaskRDev = (PBITMAPINFO) LocalAlloc(LMEM_FIXED, cbBitmapInfoMask);
  1452. if (pbmiMaskRDev == (PBITMAPINFO) NULL)
  1453. goto dpb_exit;
  1454. RtlCopyMemory(pbmiMaskRDev, lpBitmapInfoMask, cbBitmapInfoMask);
  1455. pbmiMaskRDev->bmiHeader.biWidth = rclBndRDev.right - rclBndRDev.left + 1;
  1456. pbmiMaskRDev->bmiHeader.biHeight = rclBndRDev.bottom - rclBndRDev.top + 1;
  1457. pbmiMaskRDev->bmiHeader.biSizeImage = 0;
  1458. pbmiMaskRDev->bmiHeader.biCompression = BI_RGB;
  1459. if (!(hbmMaskRDev = CreateBitmap(pbmiMaskRDev->bmiHeader.biWidth,
  1460. pbmiMaskRDev->bmiHeader.biHeight, 1, 1, (CONST VOID *) NULL)))
  1461. goto dpb_exit;
  1462. if (!SelectObject(hdcSrcRDev, hbmMaskRDev))
  1463. goto dpb_exit;
  1464. // Initialize the mask bitmap to 0's.
  1465. if (!PatBlt(hdcSrcRDev,0,0,(int)pbmiMaskRDev->bmiHeader.biWidth,
  1466. (int)pbmiMaskRDev->bmiHeader.biHeight,BLACKNESS))
  1467. goto dpb_exit;
  1468. // PlgBlt the original mask bitmap into the mask bitmap for MaskBlt.
  1469. if (bMask)
  1470. {
  1471. ptMask.x = xMask;
  1472. ptMask.y = yMask;
  1473. if (!DPtoLP(hdcSrc, &ptMask, 1))
  1474. goto dpb_exit;
  1475. }
  1476. else
  1477. {
  1478. ptMask.x = xSrc;
  1479. ptMask.y = ySrc;
  1480. }
  1481. if (!PlgBlt(hdcSrcRDev, (LPPOINT) aptlDst, hdcSrc, ptMask.x, ptMask.y, cxSrc, cySrc, (HBITMAP) NULL, 0, 0))
  1482. goto dpb_exit;
  1483. // Retrieve the mask bits for MaskBlt.
  1484. // Compute size of the buffer required for mask bits.
  1485. cbBitsMaskRDev = CJSCAN(pbmiMaskRDev->bmiHeader.biWidth,
  1486. pbmiMaskRDev->bmiHeader.biPlanes,
  1487. pbmiMaskRDev->bmiHeader.biBitCount)
  1488. * ABS(pbmiMaskRDev->bmiHeader.biHeight);
  1489. lpBitsMaskRDev = (LPBYTE) LocalAlloc(LMEM_FIXED, cbBitsMaskRDev);
  1490. if (lpBitsMaskRDev == (LPBYTE) NULL)
  1491. goto dpb_exit;
  1492. // Get the mask bits.
  1493. if (!GetDIBits(hdcSrcRDev, hbmMaskRDev, 0, (UINT) pbmiMaskRDev->bmiHeader.biHeight,
  1494. lpBitsMaskRDev, pbmiMaskRDev, iUsageMask))
  1495. goto dpb_exit;
  1496. // Prepare for the MaskBlt.
  1497. // The destination for the MaskBlt is rclBndRDev. Since the extents for
  1498. // the destination and source share the same logical values in MaskBlt,
  1499. // we have to set the transform in the destination DC to identity.
  1500. // Save the DC so that we can restore the transform when we are done
  1501. if (!DoSaveDC(pLocalDC))
  1502. goto dpb_exit;
  1503. // Set the transforms to identity.
  1504. if (!DoSetMapMode(pLocalDC, MM_TEXT)
  1505. || !DoModifyWorldTransform(pLocalDC, (PXFORM) NULL, MWT_IDENTITY)
  1506. || !DoSetWindowOrg(pLocalDC, 0, 0)
  1507. || !DoSetViewportOrg(pLocalDC, 0, 0))
  1508. goto dpb_restore_exit;
  1509. // Now do the MaskBlt.
  1510. b = DoMaskBlt
  1511. (
  1512. pLocalDC,
  1513. rclBndRDev.left, // xDst
  1514. rclBndRDev.top, // yDst
  1515. rclBndRDev.right - rclBndRDev.left + 1,
  1516. rclBndRDev.bottom - rclBndRDev.top + 1,
  1517. rop4,
  1518. 0, // xSrc
  1519. 0, // ySrc
  1520. &xformIdentity,
  1521. iUsageSrc,
  1522. pbmiSrcRDev,
  1523. cbBitmapInfoSrc,
  1524. lpBitsSrcRDev,
  1525. cbBitsSrcRDev,
  1526. 0, // xMask
  1527. 0, // yMask
  1528. iUsageMask,
  1529. pbmiMaskRDev,
  1530. cbBitmapInfoMask,
  1531. lpBitsMaskRDev,
  1532. cbBitsMaskRDev
  1533. );
  1534. // Restore the transforms.
  1535. dpb_restore_exit:
  1536. (void) DoRestoreDC(pLocalDC, -1);
  1537. // Cleanup.
  1538. dpb_exit:
  1539. if (hbmSrcOld)
  1540. SelectObject(hdcSrc, hbmSrcOld);
  1541. if (hbmSrcRDevOld)
  1542. SelectObject(hdcSrcRDev, hbmSrcRDevOld);
  1543. if (hbmSrc)
  1544. DeleteObject(hbmSrc);
  1545. if (hbmSrcRDev)
  1546. DeleteObject(hbmSrcRDev);
  1547. if (hbmMask)
  1548. DeleteObject(hbmMask);
  1549. if (hbmMaskRDev)
  1550. DeleteObject(hbmMaskRDev);
  1551. if (hdcSrc)
  1552. DeleteDC(hdcSrc);
  1553. if (hdcSrcRDev)
  1554. DeleteDC(hdcSrcRDev);
  1555. if (pbmiSrcRDev)
  1556. LocalFree((HANDLE) pbmiSrcRDev);
  1557. if (pbmiMaskRDev)
  1558. LocalFree((HANDLE) pbmiMaskRDev);
  1559. if (lpBitsSrcRDev)
  1560. LocalFree((HANDLE) lpBitsSrcRDev);
  1561. if (lpBitsMaskRDev)
  1562. LocalFree((HANDLE) lpBitsMaskRDev);
  1563. return(b);
  1564. }
  1565. /***************************************************************************
  1566. * SetPixel - Win32 to Win16 Metafile Converter Entry Point
  1567. **************************************************************************/
  1568. BOOL WINAPI DoSetPixel
  1569. (
  1570. PLOCALDC pLocalDC,
  1571. int x,
  1572. int y,
  1573. COLORREF crColor
  1574. )
  1575. {
  1576. POINTL ptl ;
  1577. BOOL b ;
  1578. ptl.x = (LONG) x ;
  1579. ptl.y = (LONG) y ;
  1580. b = bXformRWorldToPPage(pLocalDC, &ptl, 1) ;
  1581. if (b == FALSE)
  1582. goto exit1 ;
  1583. b = bEmitWin16SetPixel(pLocalDC, LOWORD(ptl.x), LOWORD(ptl.y), crColor) ;
  1584. exit1:
  1585. return(b) ;
  1586. }
  1587. /***************************************************************************
  1588. * SetStretchBltMode - Win32 to Win16 Metafile Converter Entry Point
  1589. **************************************************************************/
  1590. BOOL WINAPI DoSetStretchBltMode
  1591. (
  1592. PLOCALDC pLocalDC,
  1593. DWORD iStretchMode
  1594. )
  1595. {
  1596. BOOL b ;
  1597. // Emit the Win16 metafile drawing order.
  1598. b = bEmitWin16SetStretchBltMode(pLocalDC, LOWORD(iStretchMode)) ;
  1599. return(b) ;
  1600. }