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.

2278 lines
65 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name
  4. Abstract:
  5. Lingyun Wang
  6. Author:
  7. Enviornment:
  8. User Mode
  9. Revision History:
  10. --*/
  11. #include "precomp.hxx"
  12. #include <ddraw.h>
  13. #include <ddrawp.h>
  14. #include <ddrawi.h>
  15. #pragma hdrstop
  16. extern PFNTRANSBLT gpfnTransparentImage;
  17. extern PFNTRANSDIB gpfnTransparentDIBImage;
  18. BOOL gbddrawSet = FALSE;
  19. #if (_WIN32_WINNT == 0x400)
  20. extern HMODULE ghddrawlib;
  21. extern BOOL gbddraw;
  22. extern PFN_GETSURFACEFROMDC pfnGetSurfaceFromDC;
  23. PFN_GETSURFACEFROMDC pfnGetSurfaceDesc;
  24. PALETTEENTRY gapeVgaPalette[16] =
  25. {
  26. { 0, 0, 0, 0 },
  27. { 0x80,0, 0, 0 },
  28. { 0, 0x80,0, 0 },
  29. { 0x80,0x80,0, 0 },
  30. { 0, 0, 0x80, 0 },
  31. { 0x80,0, 0x80, 0 },
  32. { 0, 0x80,0x80, 0 },
  33. { 0x80,0x80,0x80, 0 },
  34. { 0xC0,0xC0,0xC0, 0 },
  35. { 0xFF,0, 0, 0 },
  36. { 0, 0xFF,0, 0 },
  37. { 0xFF,0xFF,0, 0 },
  38. { 0, 0, 0xFF, 0 },
  39. { 0xFF,0, 0xFF, 0 },
  40. { 0, 0xFF,0xFF, 0 },
  41. { 0xFF,0xFF,0xFF, 0 }
  42. };
  43. /**************************************************************************\
  44. * Dprintf
  45. *
  46. *
  47. * Arguments:
  48. *
  49. * szFmt - format string and argrs
  50. *
  51. * Return Value:
  52. *
  53. * none
  54. *
  55. * History:
  56. *
  57. *
  58. \**************************************************************************/
  59. #if DBG
  60. VOID Dprintf( LPSTR szFmt, ... ) {
  61. TCHAR szMsg[80];
  62. DWORD cb;
  63. va_list marker;
  64. va_start( marker, szFmt );
  65. wvsprintf( szMsg, szFmt, marker );
  66. cb = lstrlen(szMsg);
  67. szMsg[cb++] = '\r';
  68. szMsg[cb++] = '\n';
  69. WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), szMsg, sizeof(TCHAR) * cb,
  70. &cb, NULL );
  71. va_end( marker );
  72. return;
  73. }
  74. #else
  75. VOID Dprintf (LPSTR szFmt, ...) {
  76. return;
  77. }
  78. #endif
  79. /******************************Public*Routine******************************\
  80. * MyGetSystemPaletteEntries
  81. *
  82. * Internal version of GetSystemPaletteEntries.
  83. *
  84. * GetSystemPaletteEntries fails on some 4bpp devices. This version
  85. * will detect the 4bpp case and supply the hardcoded 16-color VGA palette.
  86. * Otherwise, it will pass the call on to GDI's GetSystemPaletteEntries.
  87. *
  88. * It is expected that this call will only be called in the 4bpp and 8bpp
  89. * cases as it is not necessary for OpenGL to query the system palette
  90. * for > 8bpp devices.
  91. *
  92. * History:
  93. * 17-Aug-1995 -by- Gilman Wong [gilmanw]
  94. * Wrote it.
  95. \**************************************************************************/
  96. static UINT
  97. MyGetSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries,
  98. LPPALETTEENTRY lppe)
  99. {
  100. int nDeviceBits;
  101. nDeviceBits = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
  102. //
  103. // Some 4bpp displays will fail the GetSystemPaletteEntries call.
  104. // So if detected, return the hardcoded table.
  105. //
  106. if ( nDeviceBits == 4 )
  107. {
  108. if ( lppe )
  109. {
  110. nEntries = min(nEntries, (16 - iStartIndex));
  111. memcpy(lppe, &gapeVgaPalette[iStartIndex],
  112. nEntries * sizeof(PALETTEENTRY));
  113. }
  114. else
  115. nEntries = 16;
  116. return nEntries;
  117. }
  118. else
  119. {
  120. return GetSystemPaletteEntries(hdc, iStartIndex, nEntries, lppe);
  121. }
  122. }
  123. /******************************Public*Routine******************************\
  124. * bFillColorTable
  125. *
  126. * Initialize the color table of the BITMAPINFO pointed to by pbmi. Colors
  127. * are set to the current system palette.
  128. *
  129. * Note: call only valid for displays of 8bpp or less.
  130. *
  131. * Returns:
  132. * TRUE if successful, FALSE otherwise.
  133. *
  134. * History:
  135. * 23-Jan-1996 -by- Gilman Wong [gilmanw]
  136. * Wrote it.
  137. \**************************************************************************/
  138. static BOOL
  139. bFillColorTable(HDC hdc, HPALETTE hpal, BITMAPINFO *pbmi)
  140. {
  141. BOOL bRet = FALSE;
  142. BYTE aj[sizeof(PALETTEENTRY) * 256];
  143. LPPALETTEENTRY lppe = (LPPALETTEENTRY) aj;
  144. RGBQUAD *prgb = (RGBQUAD *) &pbmi->bmiColors[0];
  145. ULONG cColors;
  146. cColors = 1 << pbmi->bmiHeader.biBitCount;
  147. if ( cColors <= 256 )
  148. {
  149. if ( hpal ? GetPaletteEntries(hpal, 0, cColors, lppe)
  150. : MyGetSystemPaletteEntries(hdc, 0, cColors, lppe) )
  151. {
  152. UINT i;
  153. for (i = 0; i < cColors; i++)
  154. {
  155. prgb[i].rgbRed = lppe[i].peRed;
  156. prgb[i].rgbGreen = lppe[i].peGreen;
  157. prgb[i].rgbBlue = lppe[i].peBlue;
  158. prgb[i].rgbReserved = 0;
  159. }
  160. bRet = TRUE;
  161. }
  162. else
  163. {
  164. //WARNING ("bFillColorTable: MyGetSystemPaletteEntries failed\n");
  165. }
  166. }
  167. return bRet;
  168. }
  169. /******************************Public*Routine******************************\
  170. * bFillBitmapInfoDirect
  171. *
  172. * Fills in the fields of a BITMAPINFO so that we can create a bitmap
  173. * that matches the format of the display.
  174. *
  175. * This is done by creating a compatible bitmap and calling GetDIBits
  176. * to return the color masks. This is done with two calls. The first
  177. * call passes in biBitCount = 0 to GetDIBits which will fill in the
  178. * base BITMAPINFOHEADER data. The second call to GetDIBits (passing
  179. * in the BITMAPINFO filled in by the first call) will return the color
  180. * table or bitmasks, as appropriate.
  181. *
  182. * Returns:
  183. * TRUE if successful, FALSE otherwise.
  184. *
  185. * History:
  186. * 07-Jun-1995 -by- Gilman Wong [gilmanw]
  187. * Wrote it.
  188. \**************************************************************************/
  189. BOOL
  190. bFillBitmapInfoDirect(HDC hdc, HPALETTE hpal, BITMAPINFO *pbmi)
  191. {
  192. HBITMAP hbm;
  193. BOOL bRet = FALSE;
  194. //
  195. // Create a dummy bitmap from which we can query color format info
  196. // about the device surface.
  197. //
  198. if ((hbm = CreateCompatibleBitmap(hdc, 1, 1)) != NULL)
  199. {
  200. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  201. //
  202. // Call first time to fill in BITMAPINFO header.
  203. //
  204. GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
  205. if (( pbmi->bmiHeader.biBitCount <= 8 ) || ( pbmi->bmiHeader.biCompression == BI_BITFIELDS ))
  206. {
  207. //
  208. // Call a second time to get the color masks.
  209. // It's a GetDIBits Win32 "feature".
  210. //
  211. GetDIBits(hdc, hbm, 0, pbmi->bmiHeader.biHeight, NULL, pbmi,
  212. DIB_RGB_COLORS);
  213. }
  214. bRet = TRUE;
  215. DeleteObject(hbm);
  216. }
  217. else
  218. {
  219. WARNING("bFillBitmapInfoDirect: CreateCompatibleBitmap failed\n");
  220. }
  221. return bRet;
  222. }
  223. /******************************Public*Routine******************************\
  224. * bFillBitmapInfoMemory
  225. *
  226. * Fills in the fields of a BITMAPINFO so that we can create a bitmap
  227. * that matches the format of a memory DC.
  228. *
  229. *
  230. * Returns:
  231. * TRUE if successful, FALSE otherwise.
  232. *
  233. * History:
  234. * 05-Dec-1996 -by- Lingyun Wang [lingyunw]
  235. * Wrote it.
  236. \**************************************************************************/
  237. BOOL
  238. bFillBitmapInfoMemory(HDC hdc, HPALETTE hpal, BITMAPINFO *pbmi)
  239. {
  240. HBITMAP hbm;
  241. BOOL bRet = FALSE;
  242. if ( (hbm = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP)) != NULL )
  243. {
  244. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  245. //
  246. // Call first time to fill in BITMAPINFO header.
  247. //
  248. GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
  249. if (( pbmi->bmiHeader.biBitCount <= 8 )
  250. || ( pbmi->bmiHeader.biCompression == BI_BITFIELDS ))
  251. {
  252. //
  253. // Call a second time to get the color masks.
  254. // It's a GetDIBits Win32 "feature".
  255. //
  256. GetDIBits(hdc, hbm, 0, pbmi->bmiHeader.biHeight, NULL, pbmi,
  257. DIB_RGB_COLORS);
  258. }
  259. bRet = TRUE;
  260. }
  261. else
  262. {
  263. WARNING("bFillBitmapInfoMemory: CreateCompatibleBitmap failed\n");
  264. }
  265. return bRet;
  266. }
  267. /******************************Public*Routine******************************\
  268. * bFillDIBSection
  269. *
  270. * Fill in the DIBSection structure for a memory dc
  271. * Fills in the fields of a BITMAPINFO so that we can create a bitmap
  272. * that matches the format of a memory DC.
  273. *
  274. *
  275. * Returns:
  276. * TRUE if successful, FALSE otherwise.
  277. *
  278. * History:
  279. * 05-Dec-1996 -by- Lingyun Wang [lingyunw]
  280. * Wrote it.
  281. \**************************************************************************/
  282. BOOL
  283. bFillDIBSection(
  284. PDIBINFO pDibInfo)
  285. {
  286. HBITMAP hbm;
  287. BOOL bRet = FALSE;
  288. BOOL bddraw = FALSE;
  289. DIBSECTION dib;
  290. if ( (hbm = (HBITMAP)GetCurrentObject(pDibInfo->hdc, OBJ_BITMAP)) != NULL )
  291. {
  292. GetObject (hbm, sizeof(DIBSECTION), &dib);
  293. #if 0
  294. Dprintf ("DIBSECTION is:\n");
  295. Dprintf("bmType=%x dsBm.bmBits = %x\n", dib.dsBm.bmType, dib.dsBm.bmBits);
  296. Dprintf("bmWidth = %x, bmHeight = %x, bmWidthBytes = %x \n",
  297. dib.dsBm.bmWidth, dib.dsBm.bmHeight, dib.dsBm.bmWidthBytes);
  298. Dprintf("bmPlanes = %x, bmBitsPixel = %x\n",dib.dsBm.bmPlanes, dib.dsBm.bmBitsPixel);
  299. Dprintf("dsBmh.biSize=%x, biWidth = %x, biHeight = %x\n",
  300. dib.dsBmih.biSize, dib.dsBmih.biWidth, dib.dsBmih.biHeight);
  301. Dprintf("dsBmh.biPlanes = %x, biBitCount = %x, biCompression = %x, biSizeImage = %x\n",
  302. dib.dsBmih.biPlanes, dib.dsBmih.biBitCount, dib.dsBmih.biSizeImage);
  303. #endif
  304. //
  305. // it is a DIBSECTION
  306. //
  307. if ((pDibInfo->pvBits = dib.dsBm.bmBits) != NULL)
  308. {
  309. //
  310. // it is a DIBSection, now see if it might be a DD Surface (on WIn95)
  311. //
  312. // gbddraw is set at msimg32.dll's dll init time
  313. // gbddrawSet is set by ddraw.dll at its init time
  314. //
  315. if (gbddraw || gbddrawSet)
  316. {
  317. //
  318. // if this is the first time we call in here
  319. //
  320. if (!ghddrawlib)
  321. {
  322. //
  323. // increment handle count for ddraw.dll
  324. //
  325. ghddrawlib = LoadLibrary (TEXT("ddraw.dll"));
  326. //Dprintf("LoadLibrary returns %x", hddrawlib);
  327. if (ghddrawlib)
  328. pfnGetSurfaceFromDC = (PFN_GETSURFACEFROMDC)GetProcAddress(
  329. ghddrawlib, "GetSurfaceFromDC");
  330. }
  331. HDC hdcDevice;
  332. HRESULT ddVal;
  333. if (pfnGetSurfaceFromDC &&
  334. ((ddVal = pfnGetSurfaceFromDC(pDibInfo->hdc, &pDibInfo->pdds, &hdcDevice)) == DD_OK))
  335. {
  336. bddraw = TRUE;
  337. ddVal = pDibInfo->pdds->GetSurfaceDesc(&pDibInfo->ddsd);
  338. //
  339. // !!we DON'T need to lock the surface here, GetDC will do an internal lock
  340. // until dc is release!!
  341. //
  342. if (ddVal == DD_OK)
  343. {
  344. Dprintf("pfnGetSurfaceFromDC succeed\n");
  345. // printout ddsurface
  346. Dprintf ("ddsd.lpSurface = %x\n", pDibInfo->ddsd.lpSurface);
  347. Dprintf ("ddsd.lPitch = %x\n", pDibInfo->ddsd.lPitch);
  348. Dprintf ("ddsd.dwWidth = %x, ddsd.dwHight = %x\n", pDibInfo->ddsd.dwWidth, pDibInfo->ddsd.dwHeight);
  349. Dprintf ("ddsd.ddpfPixelFormat.dwRGBBitCount=%x\n", pDibInfo->ddsd.ddpfPixelFormat.dwRGBBitCount);
  350. //
  351. // correct the stride
  352. //
  353. dib.dsBm.bmWidthBytes = pDibInfo->ddsd.lPitch;
  354. #if 0
  355. pDibInfo->stride = pDibInfo->ddsd.lPitch;
  356. pDibInfo->pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  357. pDibInfo->pbmi->bmiHeader.biCompression = BI_RGB;
  358. pDibInfo->pbmi->bmiHeader.biPlanes = 1;
  359. pDibInfo->pbmi->bmiHeader.biWidth = pDibInfo->ddsd.dwWidth;
  360. pDibInfo->pbmi->bmiHeader.biHeight = pDibInfo->ddsd.dwHeight;
  361. switch (pDibInfo->ddsd.ddpfPixelFormat.dwRGBBitCount)
  362. {
  363. case DDBD_1:
  364. pDibInfo->pbmi->bmiHeader.biBitCount = 1;
  365. break;
  366. case DDBD_4:
  367. pDibInfo->pbmi->bmiHeader.biBitCount = 4;
  368. break;
  369. case DDBD_8:
  370. pDibInfo->pbmi->bmiHeader.biBitCount = 8;
  371. bFillColorTable (pDibInfo->hdc, 0, pDibInfo->pbmi);
  372. break;
  373. case DDBD_16:
  374. pDibInfo->pbmi->bmiHeader.biBitCount = 16;
  375. *(DWORD *)&pDibInfo->pbmi->bmiColors[0] = pDibInfo->ddsd.ddpfPixelFormat.dwRBitMask;
  376. *(DWORD *)&pDibInfo->pbmi->bmiColors[1] = pDibInfo->ddsd.ddpfPixelFormat.dwGBitMask;
  377. *(DWORD *)&pDibInfo->pbmi->bmiColors[2] = pDibInfo->ddsd.ddpfPixelFormat.dwBBitMask;
  378. break;
  379. case DDBD_24:
  380. pDibInfo->pbmi->bmiHeader.biBitCount = 24;
  381. break;
  382. case DDBD_32:
  383. pDibInfo->pbmi->bmiHeader.biBitCount = 32;
  384. break;
  385. default:
  386. WARNING("bad bitformat for ddraw surface\n");
  387. }
  388. pDibInfo->rclClipDC.left = 0;
  389. pDibInfo->rclClipDC.top =0;
  390. pDibInfo->rclClipDC.right = pDibInfo->ddsd.dwWidth;
  391. pDibInfo->rclClipDC.bottom = pDibInfo->ddsd.dwHeight;
  392. #endif
  393. bRet = TRUE;
  394. }
  395. else
  396. {
  397. Dprintf("fail to GET the surface, ddVal = %x\n", ddVal);
  398. }
  399. }
  400. else
  401. {
  402. Dprintf("fail GetSurfaceFromDC, ddVal = %x\n", ddVal);
  403. }
  404. }
  405. Dprintf ("bddraw = %x\n", gbddraw);
  406. //
  407. // continue with dibsection
  408. //
  409. {
  410. //
  411. // If biHeight is positive, then the bitmap is a bottom-up DIB.
  412. // If biHeight is negative, then the bitmap is a top-down DIB.
  413. //
  414. {
  415. // WINBUG #365315 4-10-2001 jasonha Bug in bFillDIBSection
  416. //
  417. // Old Comment:
  418. // GDI Bug 19374: bmWidthBytes returns pitch assuming
  419. // that DIB scanlines are WORD aligned (as they
  420. // are in Win95). But NT DIBs are DWORD aligned.
  421. // When bug if corrected, we can remove this block of
  422. // code.
  423. OSVERSIONINFO osvi;
  424. osvi.dwOSVersionInfoSize = sizeof(osvi);
  425. if (GetVersionEx(&osvi))
  426. {
  427. if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
  428. {
  429. dib.dsBm.bmWidthBytes = (dib.dsBm.bmWidthBytes + 3) & ~3;
  430. }
  431. }
  432. else
  433. {
  434. return bRet;
  435. }
  436. }
  437. if ( dib.dsBmih.biHeight > 0 )
  438. {
  439. pDibInfo->pvBase = (PVOID) (((int) dib.dsBm.bmBits) + (dib.dsBm.bmWidthBytes *
  440. (dib.dsBm.bmHeight - 1)));
  441. pDibInfo->stride = (ULONG) (-dib.dsBm.bmWidthBytes);
  442. }
  443. else
  444. {
  445. pDibInfo->pvBase = dib.dsBm.bmBits;
  446. pDibInfo->stride = dib.dsBm.bmWidthBytes;
  447. }
  448. //
  449. // fill up the BITMAPINFOHEADER
  450. //
  451. pDibInfo->pbmi->bmiHeader = dib.dsBmih;
  452. //
  453. // fill up the color table
  454. //
  455. if ((pDibInfo->pbmi->bmiHeader.biBitCount <= 8) || ( pDibInfo->pbmi->bmiHeader.biCompression == BI_BITFIELDS ))
  456. {
  457. ULONG count = 1 << pDibInfo->pbmi->bmiHeader.biBitCount;
  458. GetDIBits(pDibInfo->hdc, hbm, 0, pDibInfo->pbmi->bmiHeader.biHeight, NULL, pDibInfo->pbmi,
  459. DIB_RGB_COLORS);
  460. }
  461. //
  462. // fill prcl
  463. //
  464. pDibInfo->rclClipDC.left = 0;
  465. pDibInfo->rclClipDC.top = 0;
  466. pDibInfo->rclClipDC.right = dib.dsBm.bmWidth;
  467. pDibInfo->rclClipDC.bottom = dib.dsBm.bmHeight;
  468. if (pDibInfo->rclClipDC.bottom < 0)
  469. {
  470. pDibInfo->rclClipDC.bottom = -pDibInfo->rclClipDC.bottom;
  471. }
  472. bRet = TRUE;
  473. }
  474. }
  475. else
  476. {
  477. Dprintf("not a dibseciton");
  478. }
  479. }
  480. return(bRet);
  481. }
  482. /******************************Public*Routine******************************\
  483. * bFillBimapInfo
  484. *
  485. * Fill up the BITMAPINFO structure based on the hdc passed in
  486. * and fill up the window(if direct dc) or surface (if memory dc)
  487. * rectangle.
  488. *
  489. * if it's a dibsection, convert DIBSECTION to BITMAPINFO
  490. *
  491. * Returns:
  492. * BOOLEAN
  493. *
  494. * History:
  495. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  496. * Wrote it.
  497. \**************************************************************************/
  498. BOOL bFillBitmapInfo(
  499. PDIBINFO pDibInfo
  500. )
  501. {
  502. BOOL bRet = FALSE;
  503. //
  504. // if it is printer surface, return TRUE
  505. //
  506. if (GetDeviceCaps(pDibInfo->hdc, TECHNOLOGY) == DT_RASPRINTER)
  507. {
  508. pDibInfo->flag |= PRINTER_DC;
  509. pDibInfo->rclClipDC.left = 0;
  510. pDibInfo->rclClipDC.right = GetDeviceCaps(pDibInfo->hdc, HORZRES);
  511. pDibInfo->rclClipDC.top = 0;
  512. pDibInfo->rclClipDC.bottom = GetDeviceCaps(pDibInfo->hdc, VERTRES);
  513. pDibInfo->rclDIB = pDibInfo->rclClipDC;
  514. return (TRUE);
  515. }
  516. {
  517. //
  518. // fill up a BITMAPINFO structure compatible with the
  519. // Destination DC and reduce ulWidth and ulHeight if
  520. // possible
  521. //
  522. if (GetObjectType(pDibInfo->hdc) == OBJ_DC)
  523. {
  524. //
  525. // get the destination bitmapinfo struct
  526. //
  527. if (bRet = bFillBitmapInfoDirect(pDibInfo->hdc, 0, pDibInfo->pbmi))
  528. {
  529. HWND hwnd = WindowFromDC(pDibInfo->hdc);
  530. if (hwnd)
  531. {
  532. GetClientRect(hwnd,(RECT *)&pDibInfo->rclClipDC);
  533. }
  534. }
  535. }
  536. else if (GetObjectType(pDibInfo->hdc) == OBJ_MEMDC)
  537. {
  538. if (!(bRet = bFillDIBSection (pDibInfo)))
  539. {
  540. //
  541. // if the bitmap selected in the memory dc is NOT
  542. // a DIBSECTION, call bFillBitmapInfoMemory
  543. //
  544. if (bRet = bFillBitmapInfoMemory(pDibInfo->hdc, 0, pDibInfo->pbmi))
  545. {
  546. pDibInfo->rclClipDC.left = 0;
  547. pDibInfo->rclClipDC.top = 0;
  548. pDibInfo->rclClipDC.right = pDibInfo->pbmi->bmiHeader.biWidth;
  549. pDibInfo->rclClipDC.bottom = pDibInfo->pbmi->bmiHeader.biHeight;
  550. if (pDibInfo->rclClipDC.bottom < 0)
  551. {
  552. pDibInfo->rclClipDC.bottom = -pDibInfo->rclClipDC.bottom;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. return(bRet);
  559. }
  560. /******************************Public*Routine******************************\
  561. * bSameDIBformat
  562. *
  563. * Given two BITMAPINFO structs and compare if they are the same
  564. *
  565. * Returns:
  566. * VOID
  567. *
  568. * History:
  569. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  570. * Wrote it.
  571. \**************************************************************************/
  572. BOOL bSameDIBformat (
  573. PBITMAPINFO pbmiDst,
  574. PBITMAPINFO pbmiSrc)
  575. {
  576. BOOL bRet = FALSE;
  577. if ((pbmiDst->bmiHeader.biBitCount == pbmiSrc->bmiHeader.biBitCount) &&
  578. (pbmiDst->bmiHeader.biCompression == pbmiSrc->bmiHeader.biCompression))
  579. {
  580. bRet = TRUE;
  581. //
  582. // compare bit Bitfields masks
  583. //
  584. if (pbmiDst->bmiHeader.biCompression == BI_BITFIELDS)
  585. {
  586. if ((*(DWORD *)&pbmiDst->bmiColors[0] != *(DWORD *)&pbmiSrc->bmiColors[0]) ||
  587. (*(DWORD *)&pbmiDst->bmiColors[1] != *(DWORD *)&pbmiSrc->bmiColors[1]) ||
  588. (*(DWORD *)&pbmiDst->bmiColors[2] != *(DWORD *)&pbmiSrc->bmiColors[2]))
  589. {
  590. bRet = FALSE;
  591. }
  592. }
  593. //
  594. // compare color table
  595. //
  596. if (pbmiDst->bmiHeader.biBitCount <= 8)
  597. {
  598. ULONG cColors = 1 << pbmiDst->bmiHeader.biBitCount;
  599. ULONG i;
  600. for (i = 0; i < cColors; i++)
  601. {
  602. if ((pbmiDst->bmiColors[i].rgbBlue != pbmiSrc->bmiColors[i].rgbBlue) ||
  603. (pbmiDst->bmiColors[i].rgbGreen != pbmiSrc->bmiColors[i].rgbGreen) ||
  604. (pbmiDst->bmiColors[i].rgbRed != pbmiSrc->bmiColors[i].rgbRed))
  605. {
  606. return (FALSE);
  607. }
  608. }
  609. }
  610. }
  611. return (bRet);
  612. }
  613. /******************************Public*Routine******************************\
  614. * CreateCompatibleDIB
  615. *
  616. * Create a DIB_RGB_COLORS dib section based on the given width/height and pbmi
  617. *
  618. * Returns:
  619. * Bitmap handle
  620. *
  621. * History:
  622. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  623. * Wrote it.
  624. \**************************************************************************/
  625. HBITMAP CreateCompatibleDIB (
  626. HDC hdc,
  627. ULONG ulWidth,
  628. ULONG ulHeight,
  629. PVOID *ppvBits,
  630. PBITMAPINFO pbmi)
  631. {
  632. HBITMAP hbm;
  633. //
  634. // Change bitmap size to match specified dimensions.
  635. //
  636. pbmi->bmiHeader.biWidth = ulWidth;
  637. pbmi->bmiHeader.biHeight = ulHeight;
  638. if (pbmi->bmiHeader.biCompression == BI_RGB)
  639. {
  640. pbmi->bmiHeader.biSizeImage = 0;
  641. }
  642. else
  643. {
  644. if ( pbmi->bmiHeader.biBitCount == 16 )
  645. pbmi->bmiHeader.biSizeImage = ulWidth * ulHeight * 2;
  646. else if ( pbmi->bmiHeader.biBitCount == 32 )
  647. pbmi->bmiHeader.biSizeImage = ulWidth * ulHeight * 4;
  648. else
  649. pbmi->bmiHeader.biSizeImage = 0;
  650. }
  651. pbmi->bmiHeader.biClrUsed = 0;
  652. pbmi->bmiHeader.biClrImportant = 0;
  653. hbm = CreateDIBSection(hdc, (PBITMAPINFO)pbmi, DIB_RGB_COLORS, ppvBits, NULL, 0);
  654. return (hbm);
  655. }
  656. /******************************Public*Routine******************************\
  657. * GetCompatibleDIBInfo
  658. *
  659. * Copies pointer to bitmap origin to ppvBase and bitmap stride to plStride.
  660. * Win32 DIBs can be created bottom-up (the default) with the origin at the
  661. * lower left corner or top-down with the origin at the upper left corner.
  662. * If the bitmap is top-down, *plStride is positive; if bottom-up, *plStride
  663. * us negative.
  664. *
  665. * Also, because of restrictions on the alignment of scan lines the width
  666. * the bitmap is often not the same as the stride (stride is the number of
  667. * bytes between vertically adjacent pixels).
  668. *
  669. * The ppvBase and plStride value returned will allow you to address any
  670. * given pixel (x, y) in the bitmap as follows:
  671. *
  672. * PIXEL *ppix;
  673. *
  674. * ppix = (PIXEL *) (((BYTE *)*ppvBase) + (y * *plStride) + (x * sizeof(PIXEL)));
  675. *
  676. * Returns:
  677. * TRUE if successful, FALSE otherwise.
  678. *
  679. * History:
  680. * 02-Feb-1996 -by- Gilman Wong [gilmanw]
  681. * Wrote it.
  682. \**************************************************************************/
  683. BOOL GetCompatibleDIBInfo(HBITMAP hbm, PVOID *ppvBase, LONG *plStride)
  684. {
  685. BOOL bRet = FALSE;
  686. DIBSECTION ds;
  687. //
  688. // Call GetObject to return a DIBSECTION. If successful, the
  689. // bitmap is a DIB section and we can retrieve the pointer to
  690. // the bitmap bits and other parameters.
  691. //
  692. if ( (GetObject(hbm, sizeof(ds), &ds) == sizeof(ds))
  693. && ds.dsBm.bmBits )
  694. {
  695. // WINBUG #365315 4-10-2001 jasonha Bug in GetCompatibleDIBInfo
  696. //
  697. // Old Comment:
  698. // GDI Bug 19374: bmWidthBytes returns pitch assuming
  699. // that DIB scanlines are WORD aligned (as they
  700. // are in Win95). But NT DIBs are DWORD aligned.
  701. // When bug if corrected, we can remove this block of
  702. // code.
  703. {
  704. OSVERSIONINFO osvi;
  705. osvi.dwOSVersionInfoSize = sizeof(osvi);
  706. if (GetVersionEx(&osvi))
  707. {
  708. if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
  709. {
  710. ds.dsBm.bmWidthBytes = (ds.dsBm.bmWidthBytes + 3) & ~3;
  711. }
  712. }
  713. else
  714. {
  715. return bRet;
  716. }
  717. }
  718. //
  719. // If biHeight is positive, then the bitmap is a bottom-up DIB.
  720. // If biHeight is negative, then the bitmap is a top-down DIB.
  721. //
  722. if ( ds.dsBmih.biHeight > 0 )
  723. {
  724. *ppvBase = (PVOID) (((int) ds.dsBm.bmBits) + (ds.dsBm.bmWidthBytes * (ds.dsBm.bmHeight - 1)));
  725. *plStride = (ULONG) (-ds.dsBm.bmWidthBytes);
  726. }
  727. else
  728. {
  729. *ppvBase = ds.dsBm.bmBits;
  730. *plStride = ds.dsBm.bmWidthBytes;
  731. }
  732. bRet = TRUE;
  733. }
  734. else
  735. {
  736. WARNING("GetCompatibleDIBInfo: cannot get pointer to DIBSECTION bmBits\n");
  737. }
  738. return bRet;
  739. }
  740. /******************************************************
  741. * bSetupBitmapInfos
  742. *
  743. * Calls bFillBitmapInfo to fill the Dst and Src DIBINFO
  744. *
  745. * 4/4/97 -- by Lingyun Wang [lingyunw]
  746. *******************************************************/
  747. BOOL bSetupBitmapInfos(
  748. PDIBINFO pDibInfoDst,
  749. PDIBINFO pDibInfoSrc
  750. )
  751. {
  752. BOOL bRet;
  753. bRet = bFillBitmapInfo (pDibInfoDst);
  754. //
  755. // fill up bitmapinfo if it is not coming from TransparentDIBits
  756. //
  757. if (bRet && (pDibInfoSrc != NULL))
  758. {
  759. if (pDibInfoSrc->hdc != NULL)
  760. {
  761. bRet = bFillBitmapInfo (pDibInfoSrc);
  762. }
  763. else
  764. {
  765. //
  766. // src is DIB
  767. //
  768. pDibInfoSrc->rclClipDC.left = 0;
  769. pDibInfoSrc->rclClipDC.right = pDibInfoSrc->pbmi->bmiHeader.biWidth;
  770. pDibInfoSrc->rclClipDC.top = 0;
  771. pDibInfoSrc->rclClipDC.bottom = pDibInfoSrc->pbmi->bmiHeader.biHeight;
  772. if (pDibInfoSrc->rclClipDC.bottom < 0)
  773. {
  774. pDibInfoSrc->rclClipDC.bottom = -pDibInfoSrc->rclClipDC.bottom;
  775. }
  776. }
  777. }
  778. return (bRet);
  779. }
  780. /******************************Public*Routine******************************\
  781. * vCopyBitmapInfo
  782. *
  783. * Copy a BITMAPINFO stucture along with its bit masks or colortable
  784. *
  785. * Returns:
  786. * VOID.
  787. *
  788. * History:
  789. * 16-Dec-1996 -by- Lingyun Wang [lingyunw]
  790. * Wrote it.
  791. \**************************************************************************/
  792. VOID vCopyBitmapInfo (
  793. PBITMAPINFO pbmiTo,
  794. PBITMAPINFO pbmiFrom
  795. )
  796. {
  797. *pbmiTo = *pbmiFrom;
  798. //
  799. // copy BitFields masks
  800. //
  801. if (pbmiFrom->bmiHeader.biCompression == BI_BITFIELDS)
  802. {
  803. pbmiTo->bmiColors[0] = pbmiFrom->bmiColors[0];
  804. pbmiTo->bmiColors[1] = pbmiFrom->bmiColors[1];
  805. pbmiTo->bmiColors[2] = pbmiFrom->bmiColors[2];
  806. }
  807. else
  808. {
  809. //
  810. // copy color table
  811. //
  812. ULONG cMaxColors = 1 << pbmiFrom->bmiHeader.biBitCount;
  813. ULONG cColors = pbmiFrom->bmiHeader.biClrUsed;
  814. //
  815. // validate number of colors
  816. //
  817. if ((cColors == 0) || (cColors > cMaxColors))
  818. {
  819. cColors = cMaxColors;
  820. }
  821. if (cColors <= 256)
  822. {
  823. UINT i;
  824. for (i = 0; i < cColors; i++)
  825. {
  826. pbmiTo->bmiColors[i] = pbmiFrom->bmiColors[i];
  827. }
  828. }
  829. }
  830. return;
  831. }
  832. /**************************************************************************\
  833. * vIndexToRGB
  834. *
  835. *
  836. * Arguments:
  837. *
  838. *
  839. *
  840. * Return Value:
  841. *
  842. *
  843. *
  844. * History:
  845. *
  846. * 4/16/1997 -by- Lingyun Wang [lingyunw]
  847. *
  848. \**************************************************************************/
  849. VOID vIndexToRGB (
  850. RGBQUAD *pIndex,
  851. RGBQUAD *pColors,
  852. ULONG count)
  853. {
  854. ULONG i;
  855. if (count > 256)
  856. {
  857. WARNING ("vIndexToRGB -- bad count\n");
  858. return;
  859. }
  860. for (i=0; i < count; i++)
  861. {
  862. pIndex[i] = pColors[((ULONG *)pIndex)[i]];
  863. }
  864. return;
  865. }
  866. #if 1
  867. /******************************Public*Routine******************************\
  868. * vMapPALtoRGB
  869. *
  870. * Given a DIB_PAL_COLORS iusage bmiColors table, convert the indices into RGB
  871. * colors, the bmiColors table will be a DIB_RGB_COLORS table after the convertion.
  872. *
  873. * Returns:
  874. * VOID.
  875. *
  876. * History:
  877. * 16-Dec-1996 -by- Lingyun Wang [lingyunw]
  878. * Wrote it.
  879. \**************************************************************************/
  880. VOID
  881. vMapPALtoRGB(
  882. PDIBINFO pDibInfoDst,
  883. PDIBINFO pDibInfoSrc,
  884. ULONG TransColor)
  885. {
  886. //
  887. // only called in DIB API case
  888. //
  889. if (pDibInfoSrc->hdc == NULL)
  890. {
  891. PBITMAPINFO pbmi = (PBITMAPINFO)LOCALALLOC(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
  892. if (pbmi)
  893. {
  894. ZeroMemory (pbmi,sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
  895. vCopyBitmapInfo(pbmi, pDibInfoSrc->pbmi);
  896. HPALETTE hpalDC = (HPALETTE)GetCurrentObject(pDibInfoDst->hdc,OBJ_PAL);
  897. if (hpalDC)
  898. {
  899. USHORT usNumPaletteEntries = 0;
  900. DWORD numColors;
  901. DWORD bmiClrUsed = pDibInfoSrc->pbmi->bmiHeader.biClrUsed;
  902. int iRet = GetObject(hpalDC,2,&usNumPaletteEntries);
  903. if ((iRet != 0) && (usNumPaletteEntries != 0))
  904. {
  905. switch (pDibInfoSrc->pbmi->bmiHeader.biBitCount)
  906. {
  907. case 1:
  908. numColors = 2;
  909. break;
  910. case 4:
  911. numColors = 16;
  912. if ((bmiClrUsed > 0) &&
  913. (bmiClrUsed < 16)
  914. )
  915. {
  916. numColors = bmiClrUsed;
  917. }
  918. break;
  919. case 8:
  920. numColors = 256;
  921. if ((bmiClrUsed > 0) &&
  922. (bmiClrUsed < 256)
  923. )
  924. {
  925. numColors = bmiClrUsed;
  926. }
  927. break;
  928. default:
  929. numColors = 0;
  930. }
  931. if (numColors != 0)
  932. {
  933. PALETTEENTRY *ppal = (PALETTEENTRY *)LOCALALLOC(sizeof(PALETTEENTRY) * usNumPaletteEntries);
  934. if (ppal)
  935. {
  936. iRet = GetPaletteEntries(hpalDC,0,usNumPaletteEntries,ppal);
  937. if (iRet == (int)usNumPaletteEntries)
  938. {
  939. ULONG Index;
  940. RGBQUAD *pRGB = (RGBQUAD *)&pbmi->bmiColors[0];
  941. PUSHORT pPalIndex = (PUSHORT)&pDibInfoSrc->pbmi->bmiColors[0];
  942. //
  943. // map PALETTEENTRY to RGBQUAD
  944. //
  945. for (Index=0;Index<numColors;Index++)
  946. {
  947. ULONG CurIndex = pPalIndex[Index];
  948. if (CurIndex > usNumPaletteEntries)
  949. {
  950. CurIndex = CurIndex % usNumPaletteEntries;
  951. }
  952. pRGB[Index].rgbRed = ppal[CurIndex].peRed;
  953. pRGB[Index].rgbGreen = ppal[CurIndex].peGreen;
  954. pRGB[Index].rgbBlue = ppal[CurIndex].peBlue;
  955. pRGB[Index].rgbReserved = ppal[CurIndex].peFlags;
  956. }
  957. //
  958. // swap pbmi in pDibInfoSrc
  959. //
  960. LOCALFREE(pDibInfoSrc->pbmi);
  961. pDibInfoSrc->pbmi = pbmi;
  962. }
  963. LOCALFREE(ppal);
  964. }
  965. }
  966. }
  967. }
  968. }
  969. }
  970. }
  971. #else
  972. /******************************Public*Routine******************************\
  973. * vMapPALtoRGB
  974. *
  975. * Given a DIB_PAL_COLORS iusage bmiColors table, convert the indices into RGB
  976. * colors, the bmiColors table will be a DIB_RGB_COLORS table after the convertion.
  977. *
  978. * Returns:
  979. * VOID.
  980. *
  981. * History:
  982. * 16-Dec-1996 -by- Lingyun Wang [lingyunw]
  983. * Wrote it.
  984. \**************************************************************************/
  985. VOID
  986. vMapPALtoRGB(
  987. PDIBINFO pDibInfoDst,
  988. PDIBINFO pDibInfoSrc,
  989. ULONG TransColor)
  990. {
  991. HDC hdc = pDibInfoDst->hdc;
  992. HDC hdcMem;
  993. ULONG cx = 1 << pDibInfoSrc->pbmi->bmiHeader.biBitCount;
  994. HBITMAP hbm;
  995. PULONG pBits;
  996. ULONG cBytes = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 2;
  997. PBITMAPINFO pbmi;
  998. ULONG i;
  999. BYTE pBytes[256];
  1000. ULONG ulWidthDst, ulHeightDst, ulWidthSrc, ulHeightSrc;
  1001. HPALETTE hpalDC;
  1002. pbmi = (PBITMAPINFO)LOCALALLOC(cBytes);
  1003. if (pbmi == NULL)
  1004. {
  1005. WARNING("MapCopy fail to alloc mem\n");
  1006. return ;
  1007. }
  1008. hdcMem = CreateCompatibleDC (hdc);
  1009. if (hdcMem != NULL)
  1010. {
  1011. HPALETTE hpalDC = (HPALETTE)GetCurrentObject(hdc,OBJ_PAL);
  1012. SelectPalette(hdcMem,hpalDC,TRUE);
  1013. RealizePalette(hdcMem);
  1014. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1015. pbmi->bmiHeader.biWidth = 256;
  1016. pbmi->bmiHeader.biHeight = 1;
  1017. pbmi->bmiHeader.biPlanes = 1;
  1018. pbmi->bmiHeader.biBitCount = 32;
  1019. pbmi->bmiHeader.biCompression = BI_RGB;
  1020. pbmi->bmiHeader.biSizeImage = 0;
  1021. pbmi->bmiHeader.biXPelsPerMeter = 0;
  1022. pbmi->bmiHeader.biYPelsPerMeter = 0;
  1023. pbmi->bmiHeader.biClrUsed = 0;
  1024. pbmi->bmiHeader.biClrImportant = 0;
  1025. //
  1026. // save the original width/height
  1027. //
  1028. ulWidthDst = pDibInfoDst->pbmi->bmiHeader.biWidth;
  1029. ulHeightDst = pDibInfoDst->pbmi->bmiHeader.biHeight;
  1030. pDibInfoDst->pbmi->bmiHeader.biWidth = 256;
  1031. pDibInfoDst->pbmi->bmiHeader.biHeight = 1;
  1032. //
  1033. // create a dib using 32 format
  1034. //
  1035. hbm = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (PVOID *)&pBits, NULL, 0);
  1036. if ((hbm != NULL) && (SelectObject(hdcMem,hbm) != NULL))
  1037. {
  1038. //
  1039. // init pBytes to array of each pixel
  1040. //
  1041. switch (cx)
  1042. {
  1043. case 256:
  1044. for (i=0; i < cx; i++)
  1045. {
  1046. pBytes[i] = (BYTE)i;
  1047. }
  1048. break;
  1049. case 16:
  1050. pBytes[0] = 0x01;
  1051. pBytes[1] = 0x23;
  1052. pBytes[2] = 0x45;
  1053. pBytes[3] = 0x67;
  1054. pBytes[4] = 0x89;
  1055. pBytes[5] = 0xab;
  1056. pBytes[6] = 0xcd;
  1057. pBytes[7] = 0xef;
  1058. break;
  1059. case 2:
  1060. pBytes[0] = 0x40;
  1061. break;
  1062. }
  1063. ulWidthSrc = pDibInfoSrc->pbmi->bmiHeader.biWidth;
  1064. ulHeightSrc = pDibInfoSrc->pbmi->bmiHeader.biHeight;
  1065. pDibInfoSrc->pbmi->bmiHeader.biWidth = cx;
  1066. pDibInfoSrc->pbmi->bmiHeader.biHeight = 1;
  1067. if (!SetDIBitsToDevice (hdcMem, 0, 0, cx, 1, 0, 0, 0, 1, pBytes, pDibInfoSrc->pbmi, DIB_PAL_COLORS))
  1068. {
  1069. //Dprintf("fail to SetDIBitsTodevice HDC=%x\n",hdcMem);
  1070. }
  1071. for (i=0; i < cx; i++)
  1072. {
  1073. pDibInfoSrc->pbmi->bmiColors[i] = ((RGBQUAD *)pBits)[i];
  1074. //Dprintf("i=%x, pBits[i]=%x", i, pBits[i]);
  1075. }
  1076. pDibInfoSrc->pbmi->bmiHeader.biWidth = ulWidthSrc;
  1077. pDibInfoSrc->pbmi->bmiHeader.biHeight = ulHeightSrc;
  1078. pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
  1079. pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
  1080. pDibInfoSrc->iUsage = DIB_RGB_COLORS;
  1081. }
  1082. DeleteDC (hdcMem);
  1083. if (hbm != NULL)
  1084. {
  1085. DeleteObject(hbm);
  1086. }
  1087. }
  1088. }
  1089. #endif
  1090. /**************************************************************************\
  1091. * bGetSrcDIBits:
  1092. *
  1093. * Setup SRC DIB surface and retrieve the dibits.
  1094. * Ported from kernel mode
  1095. *
  1096. * Arguments:
  1097. *
  1098. * pDibInfoDst - information on dest surface
  1099. * pDibInfoSrc - information on src surfcace
  1100. * ulSourceType - type of src surface needed
  1101. * ulTranColor - transparent color for TransparentBlt
  1102. *
  1103. * Return Value:
  1104. *
  1105. * Status
  1106. *
  1107. * History:
  1108. *
  1109. * 4/16/1997 - by Lingyun Wang [lingyunw]
  1110. *
  1111. \**************************************************************************/
  1112. BOOL
  1113. bGetSrcDIBits(
  1114. PDIBINFO pDibInfoDst,
  1115. PDIBINFO pDibInfoSrc,
  1116. ULONG ulSourceType,
  1117. ULONG ulTranColor
  1118. )
  1119. {
  1120. BOOL bRet = TRUE;
  1121. LONG DstCx = pDibInfoDst->rclBounds.right - pDibInfoDst->rclBounds.left;
  1122. LONG DstCy = pDibInfoDst->rclBounds.bottom - pDibInfoDst->rclBounds.top;
  1123. LONG SrcCx = pDibInfoSrc->rclBounds.right - pDibInfoSrc->rclBounds.left;
  1124. LONG SrcCy = pDibInfoSrc->rclBounds.bottom - pDibInfoSrc->rclBounds.top;
  1125. PVOID pvBits = pDibInfoSrc->pvBits;
  1126. PBITMAPINFO pbmi = NULL;
  1127. HDC hdcTemp = NULL;
  1128. HBITMAP hbm;
  1129. LONG SrcTrimLeft;
  1130. LONG SrcTrimRight;
  1131. LONG SrcTrimTop;
  1132. LONG SrcTrimBottom;
  1133. BOOL bStretch = ((DstCx != SrcCx) || (DstCy != SrcCy));
  1134. SrcTrimLeft = 0;
  1135. SrcTrimRight = 0;
  1136. SrcTrimTop = 0;
  1137. SrcTrimBottom = 0;
  1138. //
  1139. // trim destination bounds rect to surface bounds. Src rect must also
  1140. // be trimmed by same amount (in src space)
  1141. //
  1142. if (pDibInfoDst->rclBoundsTrim.left < pDibInfoDst->rclClipDC.left)
  1143. {
  1144. SrcTrimLeft = pDibInfoDst->rclClipDC.left - pDibInfoDst->rclBoundsTrim.left;
  1145. pDibInfoDst->rclBoundsTrim.left = pDibInfoDst->rclClipDC.left;
  1146. }
  1147. if (pDibInfoDst->rclBoundsTrim.top < pDibInfoDst->rclClipDC.top)
  1148. {
  1149. SrcTrimTop = pDibInfoDst->rclClipDC.top - pDibInfoDst->rclBoundsTrim.top;
  1150. pDibInfoDst->rclBoundsTrim.top = pDibInfoDst->rclClipDC.top;
  1151. }
  1152. if (pDibInfoDst->rclBoundsTrim.right > pDibInfoDst->rclClipDC.right)
  1153. {
  1154. SrcTrimRight = pDibInfoDst->rclBoundsTrim.right - pDibInfoDst->rclClipDC.right;
  1155. pDibInfoDst->rclBoundsTrim.right = pDibInfoDst->rclClipDC.right;
  1156. }
  1157. if (pDibInfoDst->rclBoundsTrim.bottom > pDibInfoDst->rclClipDC.bottom)
  1158. {
  1159. SrcTrimBottom = pDibInfoDst->rclBoundsTrim.bottom - pDibInfoDst->rclClipDC.bottom;
  1160. pDibInfoDst->rclBoundsTrim.bottom = pDibInfoDst->rclClipDC.bottom;
  1161. }
  1162. //
  1163. // does src need to be reduced because of dst
  1164. //
  1165. if (bStretch)
  1166. {
  1167. //
  1168. // convert dst trim to src space and reduce src rect
  1169. //
  1170. // WARNING: ROUNDING
  1171. //
  1172. if ((SrcTrimLeft != 0) || (SrcTrimRight != 0))
  1173. {
  1174. double fDstToSrcX = (double)SrcCx / (double)DstCx;
  1175. //
  1176. // convert dst trim amound to src
  1177. //
  1178. SrcTrimLeft = (LONG)((double)SrcTrimLeft * fDstToSrcX);
  1179. SrcTrimRight = (LONG)((double)SrcTrimRight * fDstToSrcX);
  1180. pDibInfoSrc->rclBoundsTrim.left += SrcTrimLeft;
  1181. pDibInfoSrc->rclBoundsTrim.right -= SrcTrimRight;
  1182. }
  1183. if ((SrcTrimTop != 0) || (SrcTrimBottom != 0))
  1184. {
  1185. double fDstToSrcY = (double)SrcCy / (double)DstCy;
  1186. //
  1187. // convert dst trim amound to src
  1188. //
  1189. SrcTrimTop = (LONG)((double)SrcTrimTop * fDstToSrcY);
  1190. SrcTrimBottom = (LONG)((double)SrcTrimBottom * fDstToSrcY);
  1191. pDibInfoSrc->rclBoundsTrim.top += SrcTrimTop;
  1192. pDibInfoSrc->rclBoundsTrim.bottom -= SrcTrimBottom;
  1193. }
  1194. }
  1195. else
  1196. {
  1197. //
  1198. // reduce src rect
  1199. //
  1200. if (SrcTrimLeft != 0)
  1201. {
  1202. pDibInfoSrc->rclBoundsTrim.left += SrcTrimLeft;
  1203. }
  1204. if (SrcTrimRight != 0)
  1205. {
  1206. pDibInfoSrc->rclBoundsTrim.right -= SrcTrimRight;
  1207. }
  1208. if (SrcTrimTop != 0)
  1209. {
  1210. pDibInfoSrc->rclBoundsTrim.top += SrcTrimTop;
  1211. }
  1212. if (SrcTrimBottom != 0)
  1213. {
  1214. pDibInfoSrc->rclBoundsTrim.bottom -= SrcTrimBottom;
  1215. }
  1216. }
  1217. //
  1218. // Does src still exceed bounds
  1219. //
  1220. SrcTrimLeft = 0;
  1221. SrcTrimRight = 0;
  1222. SrcTrimTop = 0;
  1223. SrcTrimBottom = 0;
  1224. //
  1225. // trim destination bounds rect to surface bounds. Src rect must also
  1226. // be trimmed by same amount (in src space)
  1227. //
  1228. if (pDibInfoSrc->rclBoundsTrim.left < pDibInfoSrc->rclClipDC.left)
  1229. {
  1230. SrcTrimLeft = pDibInfoSrc->rclClipDC.left - pDibInfoSrc->rclBoundsTrim.left;
  1231. pDibInfoSrc->rclBoundsTrim.left = pDibInfoSrc->rclClipDC.left;
  1232. }
  1233. if (pDibInfoSrc->rclBoundsTrim.top < pDibInfoSrc->rclClipDC.top)
  1234. {
  1235. SrcTrimTop = pDibInfoSrc->rclClipDC.top - pDibInfoSrc->rclBoundsTrim.top;
  1236. pDibInfoSrc->rclBoundsTrim.top = pDibInfoSrc->rclClipDC.top;
  1237. }
  1238. if (pDibInfoSrc->rclBoundsTrim.right > pDibInfoSrc->rclClipDC.right)
  1239. {
  1240. SrcTrimRight = pDibInfoSrc->rclBoundsTrim.right - pDibInfoSrc->rclClipDC.right;
  1241. pDibInfoSrc->rclBoundsTrim.right = pDibInfoSrc->rclClipDC.right;
  1242. }
  1243. if (pDibInfoSrc->rclBoundsTrim.bottom > pDibInfoSrc->rclClipDC.bottom)
  1244. {
  1245. SrcTrimBottom = pDibInfoSrc->rclBoundsTrim.bottom - pDibInfoSrc->rclClipDC.bottom;
  1246. pDibInfoSrc->rclBoundsTrim.bottom = pDibInfoSrc->rclClipDC.bottom;
  1247. }
  1248. //
  1249. // Src rectangle is not allowed to exceed src surface bounds (same
  1250. // behavior as NT)
  1251. //
  1252. if (SrcTrimLeft || SrcTrimRight || SrcTrimTop || SrcTrimBottom)
  1253. {
  1254. WARNING("Error in dib.cxx: source rectangle exceeds source surface bounds");
  1255. return FALSE;
  1256. }
  1257. //
  1258. // does Dst need to be reduced because of Src
  1259. //
  1260. if (bStretch)
  1261. {
  1262. //
  1263. // WARNING: ROUNDING
  1264. //
  1265. if ((SrcTrimLeft != 0) || (SrcTrimRight != 0))
  1266. {
  1267. double fSrcToDstX = (double)DstCx / (double)SrcCx;
  1268. //
  1269. // convert dst trim amound to src
  1270. //
  1271. SrcTrimLeft = (LONG)((double)SrcTrimLeft * fSrcToDstX);
  1272. SrcTrimRight = (LONG)((double)SrcTrimRight * fSrcToDstX);
  1273. pDibInfoDst->rclBoundsTrim.left += SrcTrimLeft;
  1274. pDibInfoDst->rclBoundsTrim.right -= SrcTrimRight;
  1275. }
  1276. if ((SrcTrimTop != 0) || (SrcTrimBottom != 0))
  1277. {
  1278. double fSrcToDstY = (double)DstCy / (double)SrcCy;
  1279. //
  1280. // convert dst trim amound to src
  1281. //
  1282. SrcTrimTop = (LONG)((double)SrcTrimTop * fSrcToDstY);
  1283. SrcTrimBottom = (LONG)((double)SrcTrimBottom * fSrcToDstY);
  1284. pDibInfoDst->rclBoundsTrim.top += SrcTrimTop;
  1285. pDibInfoDst->rclBoundsTrim.bottom -= SrcTrimBottom;
  1286. }
  1287. }
  1288. else
  1289. {
  1290. //
  1291. // reduce dst rect
  1292. //
  1293. if (SrcTrimLeft != 0)
  1294. {
  1295. pDibInfoDst->rclBoundsTrim.left += SrcTrimLeft;
  1296. }
  1297. if (SrcTrimRight != 0)
  1298. {
  1299. pDibInfoDst->rclBoundsTrim.right -= SrcTrimRight;
  1300. }
  1301. if (SrcTrimTop != 0)
  1302. {
  1303. pDibInfoDst->rclBoundsTrim.top += SrcTrimTop;
  1304. }
  1305. if (SrcTrimBottom != 0)
  1306. {
  1307. pDibInfoDst->rclBoundsTrim.bottom -= SrcTrimBottom;
  1308. }
  1309. }
  1310. //
  1311. // check for clipped out Dst and Src
  1312. //
  1313. if (
  1314. (pDibInfoDst->rclBoundsTrim.left < pDibInfoDst->rclBoundsTrim.right) &&
  1315. (pDibInfoDst->rclBoundsTrim.top < pDibInfoDst->rclBoundsTrim.bottom) &&
  1316. (pDibInfoSrc->rclBoundsTrim.left < pDibInfoSrc->rclBoundsTrim.right) &&
  1317. (pDibInfoSrc->rclBoundsTrim.top < pDibInfoSrc->rclBoundsTrim.bottom)
  1318. )
  1319. {
  1320. if ((bStretch) || (pDibInfoSrc->pvBits == NULL))
  1321. {
  1322. //
  1323. // allocate compatible DC and surface
  1324. //
  1325. hdcTemp = CreateCompatibleDC(pDibInfoSrc->hdc);
  1326. if (hdcTemp)
  1327. {
  1328. //
  1329. // copy pDibInfoSrc->pbmi into pbmi
  1330. //
  1331. if (!pDibInfoSrc->hdc)
  1332. {
  1333. ULONG cBytes = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
  1334. pbmi = (PBITMAPINFO)LOCALALLOC(cBytes);
  1335. if (pbmi != NULL)
  1336. {
  1337. ZeroMemory (pbmi,cBytes);
  1338. vCopyBitmapInfo (pbmi, pDibInfoSrc->pbmi);
  1339. }
  1340. else
  1341. {
  1342. WARNING("bGetSrcDIBits fail to alloc mem\n");
  1343. bRet = FALSE;
  1344. }
  1345. }
  1346. if (bRet)
  1347. {
  1348. //
  1349. // create temp DIB size of dst rect
  1350. //
  1351. RECTL rclDstCopy = {
  1352. 0,
  1353. 0,
  1354. pDibInfoDst->rclBoundsTrim.right - pDibInfoDst->rclBoundsTrim.left,
  1355. pDibInfoDst->rclBoundsTrim.bottom - pDibInfoDst->rclBoundsTrim.top
  1356. };
  1357. hbm = CreateCompatibleDIB(hdcTemp,
  1358. rclDstCopy.right,
  1359. rclDstCopy.bottom,
  1360. &pDibInfoSrc->pvBits,
  1361. pDibInfoSrc->pbmi);
  1362. if (hbm)
  1363. {
  1364. pDibInfoSrc->hDIB = hbm;
  1365. GetCompatibleDIBInfo (hbm, &pDibInfoSrc->pvBase, &pDibInfoSrc->stride);
  1366. HBITMAP hbmDefault = (HBITMAP)SelectObject (hdcTemp, hbm);
  1367. ULONG OldMode = SetStretchBltMode(hdcTemp,COLORONCOLOR);
  1368. //
  1369. // Stretch data into source temp DIB
  1370. //
  1371. //
  1372. // Blt data into source temp DIB
  1373. //
  1374. if (pDibInfoSrc->hdc)
  1375. {
  1376. StretchBlt (hdcTemp,
  1377. 0,
  1378. 0,
  1379. rclDstCopy.right,
  1380. rclDstCopy.bottom,
  1381. pDibInfoSrc->hdc,
  1382. pDibInfoSrc->rclBoundsTrim.left,
  1383. pDibInfoSrc->rclBoundsTrim.top,
  1384. pDibInfoSrc->rclBoundsTrim.right - pDibInfoSrc->rclBoundsTrim.left,
  1385. pDibInfoSrc->rclBoundsTrim.bottom - pDibInfoSrc->rclBoundsTrim.top,
  1386. SRCCOPY);
  1387. }
  1388. else
  1389. {
  1390. //
  1391. // adjust ySrc to be compatible
  1392. //
  1393. LONG cySrc = pDibInfoSrc->rclBoundsTrim.bottom-pDibInfoSrc->rclBoundsTrim.top;
  1394. LONG ySrc = pDibInfoSrc->rclClipDC.bottom - pDibInfoSrc->rclBoundsTrim.top - cySrc;
  1395. StretchDIBits (hdcTemp,
  1396. 0,
  1397. 0,
  1398. rclDstCopy.right,
  1399. rclDstCopy.bottom,
  1400. pDibInfoSrc->rclBoundsTrim.left,
  1401. ySrc,
  1402. pDibInfoSrc->rclBoundsTrim.right-pDibInfoSrc->rclBoundsTrim.left,
  1403. cySrc,
  1404. pvBits,
  1405. pbmi,
  1406. DIB_RGB_COLORS,
  1407. SRCCOPY);
  1408. }
  1409. SetStretchBltMode(hdcTemp,OldMode);
  1410. SelectObject (hdcTemp, hbmDefault);
  1411. pDibInfoSrc->rclDIB = rclDstCopy;
  1412. }
  1413. else
  1414. {
  1415. WARNING ("bGetSrcDIBits -- fail to createcompatibleDIB\n");
  1416. bRet = FALSE;
  1417. }
  1418. }
  1419. }
  1420. else
  1421. {
  1422. WARNING ("bGetSrcDIBits -- fail to createcompatibledc\n");
  1423. bRet = FALSE;
  1424. }
  1425. }
  1426. else
  1427. {
  1428. pDibInfoSrc->rclDIB = pDibInfoSrc->rclBoundsTrim;
  1429. }
  1430. }
  1431. else
  1432. {
  1433. //
  1434. // clipped out
  1435. //
  1436. pDibInfoDst->rclBoundsTrim.left = pDibInfoDst->rclBoundsTrim.right = 0;
  1437. pDibInfoDst->rclBoundsTrim.top = pDibInfoDst->rclBoundsTrim.bottom = 0;
  1438. pDibInfoSrc->rclBoundsTrim.left = pDibInfoSrc->rclBoundsTrim.right = 0;
  1439. pDibInfoSrc->rclBoundsTrim.top = pDibInfoSrc->rclBoundsTrim.bottom = 0;
  1440. bRet = FALSE;
  1441. }
  1442. if (pbmi)
  1443. {
  1444. LOCALFREE (pbmi);
  1445. }
  1446. if (hdcTemp)
  1447. {
  1448. DeleteDC(hdcTemp);
  1449. }
  1450. return(bRet);
  1451. }
  1452. /******************************Public*Routine******************************\
  1453. * bGetDstDIBits
  1454. *
  1455. * Setup the destination DIB surface and retrieve the bits
  1456. *
  1457. * Ported from psSetupDstSurface
  1458. *
  1459. *
  1460. *
  1461. * Return Value:
  1462. *
  1463. *
  1464. *
  1465. * History:
  1466. *
  1467. * 4-April-1997 -by- Lingyun Wang [lingyunw]
  1468. *
  1469. \**************************************************************************/
  1470. BOOL
  1471. bGetDstDIBits
  1472. (
  1473. PDIBINFO pDibInfoDst,
  1474. BOOL *pbReadable,
  1475. FLONG flCopyMode
  1476. )
  1477. {
  1478. HDC hdc = pDibInfoDst->hdc;
  1479. BOOL bRet = TRUE;
  1480. int iRegionComplexity;
  1481. RECT rclClipBox;
  1482. *pbReadable = TRUE;
  1483. //
  1484. // read clipping of dst surface. Clipping complexity must not be
  1485. // more than SIMPLEREGION, and bounding box must fill drawing
  1486. // rect or a temp DIB is created.
  1487. //
  1488. iRegionComplexity = GetClipBox(pDibInfoDst->hdc,&rclClipBox);
  1489. //
  1490. // try to clip to dst surface, dst should be clipped in all cases except
  1491. // gradient fill
  1492. //
  1493. if (flCopyMode & (SOURCE_GRADIENT_RECT | SOURCE_GRADIENT_TRI))
  1494. {
  1495. //
  1496. // trim destination bounds rect to surface bounds. Src rect must also
  1497. // be trimmed by same amount (in src space)
  1498. //
  1499. if (pDibInfoDst->rclBoundsTrim.left < pDibInfoDst->rclClipDC.left)
  1500. {
  1501. pDibInfoDst->rclBoundsTrim.left = pDibInfoDst->rclClipDC.left;
  1502. }
  1503. if (pDibInfoDst->rclBoundsTrim.top < pDibInfoDst->rclClipDC.top)
  1504. {
  1505. pDibInfoDst->rclBoundsTrim.top = pDibInfoDst->rclClipDC.top;
  1506. }
  1507. if (pDibInfoDst->rclBoundsTrim.right > pDibInfoDst->rclClipDC.right)
  1508. {
  1509. pDibInfoDst->rclBoundsTrim.right = pDibInfoDst->rclClipDC.right;
  1510. }
  1511. if (pDibInfoDst->rclBoundsTrim.bottom > pDibInfoDst->rclClipDC.bottom)
  1512. {
  1513. pDibInfoDst->rclBoundsTrim.bottom = pDibInfoDst->rclClipDC.bottom;
  1514. }
  1515. //
  1516. // set offset for gradient fill
  1517. //
  1518. pDibInfoDst->ptlGradOffset.x = 0;
  1519. pDibInfoDst->ptlGradOffset.y = 0;
  1520. //
  1521. // don't allocate surface for triangles at 8,4,1
  1522. // Must use internal palette routines
  1523. //
  1524. if (
  1525. (pDibInfoDst->pbmi->bmiHeader.biBitCount == 8) ||
  1526. (pDibInfoDst->pbmi->bmiHeader.biBitCount == 4) ||
  1527. (pDibInfoDst->pbmi->bmiHeader.biBitCount == 1)
  1528. )
  1529. {
  1530. *pbReadable = FALSE;
  1531. }
  1532. }
  1533. LONG DstCx = pDibInfoDst->rclBoundsTrim.right - pDibInfoDst->rclBoundsTrim.left;
  1534. LONG DstCy = pDibInfoDst->rclBoundsTrim.bottom - pDibInfoDst->rclBoundsTrim.top;
  1535. //
  1536. // make sure draswing rect lies within clip box
  1537. //
  1538. if (iRegionComplexity != NULLREGION)
  1539. {
  1540. //
  1541. // convert to NULLREGION if drawing rect inside clip box
  1542. //
  1543. if (iRegionComplexity == SIMPLEREGION)
  1544. {
  1545. if (
  1546. (pDibInfoDst->rclBoundsTrim.left >= rclClipBox.left) &&
  1547. (pDibInfoDst->rclBoundsTrim.top >= rclClipBox.top) &&
  1548. (pDibInfoDst->rclBoundsTrim.right <= rclClipBox.right) &&
  1549. (pDibInfoDst->rclBoundsTrim.bottom <= rclClipBox.bottom)
  1550. )
  1551. {
  1552. iRegionComplexity = NULLREGION;
  1553. }
  1554. }
  1555. }
  1556. //
  1557. // check for need to allocate temp dst surface
  1558. //
  1559. if ((*pbReadable == TRUE) && ((pDibInfoDst->pvBits == NULL) || (iRegionComplexity != NULLREGION)))
  1560. {
  1561. if (pDibInfoDst->rclBounds.left > 0)
  1562. {
  1563. pDibInfoDst->ptlGradOffset.x = pDibInfoDst->rclBounds.left;
  1564. }
  1565. if (pDibInfoDst->rclBounds.top > 0)
  1566. {
  1567. pDibInfoDst->ptlGradOffset.y = pDibInfoDst->rclBounds.top;
  1568. }
  1569. //
  1570. // allocate surface
  1571. //
  1572. HDC hdcTemp = CreateCompatibleDC (hdc);
  1573. if (hdcTemp)
  1574. {
  1575. HBITMAP hbm = CreateCompatibleDIB (hdcTemp,
  1576. DstCx,
  1577. DstCy,
  1578. &pDibInfoDst->pvBits,
  1579. pDibInfoDst->pbmi);
  1580. if (hbm != NULL)
  1581. {
  1582. pDibInfoDst->hDIB = hbm;
  1583. GetCompatibleDIBInfo (hbm, &pDibInfoDst->pvBase, &pDibInfoDst->stride);
  1584. HGDIOBJ hret = SelectObject(hdcTemp, hbm);
  1585. if (hret != NULL)
  1586. {
  1587. RECTL rclCopy;
  1588. rclCopy.left = 0;
  1589. rclCopy.right = DstCx;
  1590. rclCopy.top = 0;
  1591. rclCopy.bottom = DstCy;
  1592. //
  1593. // gradient rect does not need source bitmap data
  1594. //
  1595. if (flCopyMode != SOURCE_GRADIENT_RECT)
  1596. {
  1597. bRet = BitBlt(hdcTemp,
  1598. 0,
  1599. 0,
  1600. DstCx,
  1601. DstCy,
  1602. pDibInfoDst->hdc,
  1603. pDibInfoDst->rclBoundsTrim.left,
  1604. pDibInfoDst->rclBoundsTrim.top,
  1605. SRCCOPY);
  1606. }
  1607. //
  1608. // adjust dst rect
  1609. //
  1610. if (bRet)
  1611. {
  1612. pDibInfoDst->rclDIB = rclCopy;
  1613. }
  1614. }
  1615. else
  1616. {
  1617. bRet = NULL;
  1618. WARNING ("bGetDstDIBits -- fail to select compatible DIB\n");
  1619. }
  1620. *pbReadable = bRet;
  1621. }
  1622. else
  1623. {
  1624. bRet = FALSE;
  1625. }
  1626. DeleteDC (hdcTemp);
  1627. }
  1628. else
  1629. {
  1630. WARNING ("bGetDstDIBits -- fail to createcompatibledc\n");
  1631. bRet = FALSE;
  1632. }
  1633. }
  1634. else
  1635. {
  1636. pDibInfoDst->rclDIB = pDibInfoDst->rclBoundsTrim;
  1637. }
  1638. return(bRet);
  1639. }
  1640. /******************************Public*Routine******************************\
  1641. * bDIBGetSrcDIBits
  1642. *
  1643. * Create or get the source dib bits
  1644. *
  1645. * Returns:
  1646. * VOID.
  1647. *
  1648. * History:
  1649. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  1650. * Wrote it.
  1651. \**************************************************************************/
  1652. BOOL bDIBGetSrcDIBits (
  1653. PDIBINFO pDibInfoDst,
  1654. PDIBINFO pDibInfoSrc,
  1655. FLONG flSourceMode,
  1656. ULONG TransColor
  1657. )
  1658. {
  1659. if (pDibInfoSrc->iUsage == DIB_PAL_COLORS)
  1660. {
  1661. vMapPALtoRGB (pDibInfoDst, pDibInfoSrc, 0);
  1662. }
  1663. //pDibInfoSrc->rclDIB = pDibInfoSrc->rclClipDC;
  1664. return (bGetSrcDIBits(pDibInfoDst,pDibInfoSrc,flSourceMode, TransColor));
  1665. }
  1666. /******************************Public*Routine******************************\
  1667. * bDIBInitDIBINFO
  1668. *
  1669. * Returns:
  1670. * BOOLEAN.
  1671. *
  1672. * History:
  1673. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  1674. * Wrote it.
  1675. \**************************************************************************/
  1676. BOOL
  1677. bDIBInitDIBINFO(
  1678. PBITMAPINFO pbmi,
  1679. CONST VOID * pvBits,
  1680. int x,
  1681. int y,
  1682. int cx,
  1683. int cy,
  1684. PDIBINFO pDibInfo)
  1685. {
  1686. PVOID p;
  1687. ULONG cBytes = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
  1688. int bmWidthBytes;
  1689. POINT lpPoints[2];
  1690. p = LOCALALLOC(cBytes);
  1691. if (!p)
  1692. {
  1693. WARNING("fail to alloc mem\n");
  1694. return (FALSE);
  1695. }
  1696. ZeroMemory (p,cBytes);
  1697. //
  1698. // copy the input pbmi
  1699. //
  1700. vCopyBitmapInfo ((PBITMAPINFO)p, pbmi);
  1701. pDibInfo->pbmi = (PBITMAPINFO)p;
  1702. pDibInfo->hdc = NULL;
  1703. pDibInfo->rclBounds.left = x;
  1704. pDibInfo->rclBounds.top = y;
  1705. pDibInfo->rclBounds.right = x+cx;
  1706. pDibInfo->rclBounds.bottom = y+cy;
  1707. pDibInfo->rclBoundsTrim = pDibInfo->rclBounds;
  1708. pDibInfo->pvBits = (PVOID)pvBits;
  1709. pDibInfo->iUsage = DIB_RGB_COLORS;
  1710. //
  1711. // align width to WORD boundary
  1712. //
  1713. bmWidthBytes = ((pbmi->bmiHeader.biWidth*pbmi->bmiHeader.biBitCount + 15)>>4)<<1;
  1714. if (pbmi->bmiHeader.biHeight > 0)
  1715. {
  1716. pDibInfo->pvBase = (PBYTE)pDibInfo->pvBits + bmWidthBytes * (pbmi->bmiHeader.biHeight - 1);
  1717. pDibInfo->stride = (ULONG) (-bmWidthBytes);
  1718. }
  1719. else
  1720. {
  1721. pDibInfo->pvBase = pDibInfo->pvBits;
  1722. pDibInfo->stride = bmWidthBytes;
  1723. }
  1724. pDibInfo->hDIB = NULL;
  1725. pDibInfo->pdds = NULL;
  1726. pDibInfo->ddsd.dwSize = sizeof(DDSURFACEDESC);
  1727. return(TRUE);
  1728. }
  1729. /******************************Public*Routine******************************\
  1730. * bInitDIBINFO
  1731. *
  1732. * Returns:
  1733. * BOOLEAN.
  1734. *
  1735. * History:
  1736. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  1737. * Wrote it.
  1738. \**************************************************************************/
  1739. BOOL
  1740. bInitDIBINFO(
  1741. HDC hdc,
  1742. int x,
  1743. int y,
  1744. int cx,
  1745. int cy,
  1746. PDIBINFO pDibInfo)
  1747. {
  1748. ULONG cBytes;
  1749. PVOID p;
  1750. POINT lpPoints[2];
  1751. pDibInfo->hdc = hdc;
  1752. pDibInfo->rclBounds.left = x;
  1753. pDibInfo->rclBounds.top = y;
  1754. pDibInfo->rclBounds.right = x+cx;
  1755. pDibInfo->rclBounds.bottom = y+cy;
  1756. //
  1757. // setup rclBounds in device space
  1758. //
  1759. LPtoDP (hdc, (POINT *)&pDibInfo->rclBounds, 2);
  1760. //
  1761. // order rect
  1762. //
  1763. if (pDibInfo->rclBounds.left > pDibInfo->rclBounds.right)
  1764. {
  1765. LONG lTemp = pDibInfo->rclBounds.left;
  1766. pDibInfo->rclBounds.left = pDibInfo->rclBounds.right;
  1767. pDibInfo->rclBounds.right = lTemp;
  1768. }
  1769. if (pDibInfo->rclBounds.top > pDibInfo->rclBounds.bottom)
  1770. {
  1771. LONG lTemp = pDibInfo->rclBounds.top;
  1772. pDibInfo->rclBounds.top = pDibInfo->rclBounds.bottom;
  1773. pDibInfo->rclBounds.bottom = lTemp;
  1774. }
  1775. pDibInfo->rclBoundsTrim = pDibInfo->rclBounds;
  1776. //
  1777. // Now operate in MM_TEXT mode
  1778. //
  1779. SetViewportOrgEx(hdc, 0, 0, &pDibInfo->ViewportOrg);
  1780. SetViewportExtEx(hdc, 1, 1, &pDibInfo->ViewportExt);
  1781. SetWindowOrgEx(hdc, 0, 0, &pDibInfo->WindowOrg);
  1782. SetWindowExtEx(hdc, 1, 1, &pDibInfo->WindowExt);
  1783. pDibInfo->Mapmode = SetMapMode(hdc,MM_TEXT);
  1784. pDibInfo->pvBits = NULL;
  1785. pDibInfo->pvBase = NULL;
  1786. pDibInfo->hDIB = NULL;
  1787. pDibInfo->iUsage = DIB_RGB_COLORS;
  1788. pDibInfo->flag = 0;
  1789. cBytes = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
  1790. p = LOCALALLOC(cBytes);
  1791. if (!p)
  1792. {
  1793. WARNING("fail to alloc mem\n");
  1794. return (FALSE);
  1795. }
  1796. ZeroMemory (p,cBytes);
  1797. pDibInfo->pbmi = (PBITMAPINFO)p;
  1798. pDibInfo->pdds = NULL;
  1799. pDibInfo->ddsd.dwSize = sizeof(DDSURFACEDESC);
  1800. return(TRUE);
  1801. }
  1802. /******************************Public*Routine******************************\
  1803. * bSendDIBInfo
  1804. *
  1805. * Returns:
  1806. * BOOLEAN.
  1807. *
  1808. * History:
  1809. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  1810. * Wrote it.
  1811. \**************************************************************************/
  1812. BOOL
  1813. bSendDIBINFO(
  1814. HDC hdcDst,
  1815. PDIBINFO pDibInfo
  1816. )
  1817. {
  1818. BOOL bRet = TRUE;
  1819. if (pDibInfo->hDIB)
  1820. {
  1821. bRet = SetDIBitsToDevice(hdcDst,
  1822. pDibInfo->rclBoundsTrim.left,
  1823. pDibInfo->rclBoundsTrim.top,
  1824. pDibInfo->rclBoundsTrim.right - pDibInfo->rclBoundsTrim.left,
  1825. pDibInfo->rclBoundsTrim.bottom - pDibInfo->rclBoundsTrim.top,
  1826. 0,
  1827. 0,
  1828. 0,
  1829. pDibInfo->rclDIB.bottom - pDibInfo->rclDIB.top,
  1830. pDibInfo->pvBits,
  1831. pDibInfo->pbmi,
  1832. DIB_RGB_COLORS);
  1833. }
  1834. return (bRet);
  1835. }
  1836. /******************************Public*Routine******************************\
  1837. * vCleanupDIBInfo
  1838. *
  1839. * Returns:
  1840. * VOID.
  1841. *
  1842. * History:
  1843. * 09-Dec-1996 -by- Lingyun Wang [lingyunw]
  1844. * Wrote it.
  1845. \**************************************************************************/
  1846. VOID
  1847. vCleanupDIBINFO(
  1848. PDIBINFO pDibInfo)
  1849. {
  1850. //
  1851. // restore DC map modes
  1852. //
  1853. if (pDibInfo->hdc != NULL)
  1854. {
  1855. SetMapMode(pDibInfo->hdc,pDibInfo->Mapmode);
  1856. SetViewportOrgEx(pDibInfo->hdc, pDibInfo->ViewportOrg.x, pDibInfo->ViewportOrg.y, NULL);
  1857. SetViewportExtEx(pDibInfo->hdc, pDibInfo->ViewportExt.cx, pDibInfo->ViewportExt.cy, NULL);
  1858. SetWindowOrgEx(pDibInfo->hdc, pDibInfo->WindowOrg.x, pDibInfo->WindowOrg.y, NULL);
  1859. SetWindowExtEx(pDibInfo->hdc, pDibInfo->WindowExt.cx, pDibInfo->WindowExt.cy, NULL);
  1860. }
  1861. //
  1862. // free allocated DIB and memory buffers
  1863. //
  1864. if (pDibInfo->hDIB)
  1865. {
  1866. DeleteObject (pDibInfo->hDIB);
  1867. }
  1868. if (pDibInfo->pbmi)
  1869. {
  1870. LOCALFREE ((PVOID)pDibInfo->pbmi);
  1871. }
  1872. if (pDibInfo->pdds)
  1873. {
  1874. pDibInfo->pdds->Unlock(pDibInfo->ddsd.lpSurface);
  1875. }
  1876. }
  1877. #endif
  1878. /******************************Public*Routine******************************\
  1879. * VOID vSetDdrawflag
  1880. *
  1881. * Returns:
  1882. * private call by ddraw to set a flag to indicate it has loaded
  1883. *
  1884. * History:
  1885. * 29-April-1997 -by- Lingyun Wang [lingyunw]
  1886. * Wrote it.
  1887. \**************************************************************************/
  1888. VOID vSetDdrawflag ()
  1889. {
  1890. gbddrawSet = TRUE;
  1891. return;
  1892. }