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.

994 lines
25 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // gfx.c - Windows graphics functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include "gfx.h"
  28. #include "mem.h"
  29. #include "str.h"
  30. #include "trace.h"
  31. ////
  32. // public functions
  33. ////
  34. ////
  35. // bitmap routines
  36. ////
  37. // GfxBitmapBackfill - replace bitmap's white backg with curr backg color
  38. // <hBitmap> (i/o) bitmap handle
  39. // <crBkColor> (i) current background color
  40. // <wFlags> (i) option flags
  41. // 0 use default method
  42. // BF_EXTFLOODFILL use ExtFloodFill function
  43. // BF_GETSETPIXEL use GetPixel/SetPixel functions
  44. // NOTE: rarely, ExtFloodFill will GP the display device driver
  45. // return 0 if success
  46. //
  47. int DLLEXPORT WINAPI GfxBitmapBackfill(HBITMAP hBitmap, COLORREF crBkColor, WORD wFlags)
  48. {
  49. BOOL fSuccess = TRUE;
  50. BOOL fExtFloodFill = (BOOL) !(wFlags & BF_GETSETPIXEL);
  51. BITMAP Bitmap;
  52. HDC hdc = NULL;
  53. HDC hdcMem = NULL;
  54. HBITMAP hBitmapOld = NULL;
  55. HBRUSH hbr = NULL;
  56. HBRUSH hbrOld = NULL;
  57. COLORREF crMaskColor = RGB(255, 255, 255); // RGB_WHITE
  58. // need not continue if COLOR_WINDOW is white
  59. //
  60. if (crMaskColor == crBkColor)
  61. return 0;
  62. if (hBitmap == NULL)
  63. fSuccess = TraceFALSE(NULL);
  64. // get width and height of bitmap
  65. //
  66. else if (GetObject((HGDIOBJ) hBitmap, sizeof(BITMAP), &Bitmap) == 0)
  67. fSuccess = TraceFALSE(NULL);
  68. // get device context for screen
  69. //
  70. else if ((hdc = GetDC(NULL)) == NULL)
  71. fSuccess = TraceFALSE(NULL);
  72. // create a memory device context
  73. //
  74. else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  75. fSuccess = TraceFALSE(NULL);
  76. // select the bitmap into the memory device context
  77. //
  78. else if ((hBitmapOld = SelectObject(hdcMem, hBitmap)) == NULL)
  79. fSuccess = TraceFALSE(NULL);
  80. // create a brush with specified background color
  81. //
  82. else if ((hbr = CreateSolidBrush(crBkColor)) == NULL)
  83. fSuccess = TraceFALSE(NULL);
  84. // select the brush into the memory device context
  85. //
  86. else if ((hbrOld = SelectObject(hdcMem, hbr)) == NULL)
  87. fSuccess = TraceFALSE(NULL);
  88. else
  89. {
  90. int cx = Bitmap.bmWidth;
  91. int cy = Bitmap.bmHeight;
  92. if (fExtFloodFill)
  93. {
  94. ExtFloodFill(hdcMem, 0, 0, crMaskColor, FLOODFILLSURFACE);
  95. ExtFloodFill(hdcMem, cx - 1, 0, crMaskColor, FLOODFILLSURFACE);
  96. ExtFloodFill(hdcMem, 0, cy - 1, crMaskColor, FLOODFILLSURFACE);
  97. ExtFloodFill(hdcMem, cx - 1, cy - 1, crMaskColor, FLOODFILLSURFACE);
  98. }
  99. else
  100. {
  101. int x;
  102. int y;
  103. for (x = 0; x < cx; ++x)
  104. for (y = 0; y < cy; ++y)
  105. if (GetPixel(hdcMem, x, y) == crMaskColor)
  106. SetPixel(hdcMem, x, y, crBkColor);
  107. }
  108. }
  109. // restore old brush, if any
  110. //
  111. if (hbrOld != NULL)
  112. SelectObject(hdcMem, hbrOld);
  113. // delete new brush
  114. //
  115. if (hbr != NULL && !DeleteObject(hbr))
  116. fSuccess = TraceFALSE(NULL);
  117. // restore old bitmap, if any
  118. //
  119. if (hBitmapOld != NULL)
  120. SelectObject(hdcMem, hBitmapOld);
  121. // free the memory device context
  122. //
  123. if (hdcMem != NULL && !DeleteDC(hdcMem))
  124. fSuccess = TraceFALSE(NULL);
  125. // release the common device context
  126. //
  127. if (hdc != NULL && !ReleaseDC(NULL, hdc))
  128. fSuccess = TraceFALSE(NULL);
  129. return fSuccess ? 0 : -1;
  130. }
  131. // GfxBitmapDisplay - display specified bitmap
  132. // <hdc> (i) device context for destination window
  133. // <hBitmap> (i) bitmap handle for source bitmap
  134. // <x> (i) x coordinate for destination window
  135. // <y> (i) y coordinate for destination window
  136. // <fInvert> (i) display bitmap inverted
  137. // return 0 if success
  138. //
  139. int DLLEXPORT WINAPI GfxBitmapDisplay(HDC hdc, HBITMAP hBitmap, int x, int y, BOOL fInvert)
  140. {
  141. BOOL fSuccess = TRUE;
  142. HDC hdcMem = NULL;
  143. HBITMAP hBitmapOld = NULL;
  144. BITMAP Bitmap;
  145. if (hdc == NULL)
  146. fSuccess = TraceFALSE(NULL);
  147. else if (hBitmap == NULL)
  148. fSuccess = TraceFALSE(NULL);
  149. // get width and height of bitmap
  150. //
  151. else if (GetObject((HGDIOBJ) hBitmap, sizeof(BITMAP), &Bitmap) == 0)
  152. fSuccess = TraceFALSE(NULL);
  153. // create a memory device context
  154. //
  155. else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  156. fSuccess = TraceFALSE(NULL);
  157. // select the bitmap into the memory device context
  158. //
  159. else if ((hBitmapOld = SelectObject(hdcMem, hBitmap)) == NULL)
  160. fSuccess = TraceFALSE(NULL);
  161. // copy the bitmap from hdcMem to hdc, inverted if necessary
  162. //
  163. else if (!BitBlt(hdc, x, y, Bitmap.bmWidth, Bitmap.bmHeight,
  164. hdcMem, 0, 0, fInvert ? NOTSRCCOPY : SRCCOPY))
  165. fSuccess = TraceFALSE(NULL);
  166. // restore old bitmap, if any
  167. //
  168. if (hBitmapOld != NULL)
  169. SelectObject(hdcMem, hBitmapOld);
  170. // free the memory device context
  171. //
  172. if (hdcMem != NULL)
  173. DeleteDC(hdcMem);
  174. return fSuccess ? 0 : -1;
  175. }
  176. // GfxBitmapDrawTransparent - draw specified bitmap
  177. // <hdc> (i) device context for destination window
  178. // <hBitmap> (i) bitmap handle for source bitmap
  179. // <x> (i) x coordinate for destination window
  180. // <y> (i) y coordinate for destination window
  181. // <crTransparent> (i) transparent color
  182. // <dwFlags> (i) control flags
  183. // 0 reserved; must be zero
  184. // return 0 if success
  185. //
  186. #if 1
  187. int DLLEXPORT WINAPI GfxBitmapDrawTransparent(HDC hdc, HBITMAP hBitmap, int x, int y, COLORREF crTransparent, DWORD dwFlags)
  188. {
  189. BOOL fSuccess = TRUE;
  190. BITMAP bmp;
  191. int cx;
  192. int cy;
  193. HBITMAP hbmpMask = NULL;
  194. HDC hdcMem = NULL;
  195. HDC hdcMem2 = NULL;
  196. HBITMAP hbmpOld;
  197. HBITMAP hbmpOld2;
  198. COLORREF crBkOld;
  199. COLORREF crTextOld;
  200. if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0)
  201. fSuccess = TraceFALSE(NULL);
  202. else if (cx = bmp.bmWidth, cy = bmp.bmHeight, FALSE)
  203. ;
  204. else if ((hbmpMask = CreateBitmap(cx, cy, 1, 1, NULL)) == NULL)
  205. fSuccess = TraceFALSE(NULL);
  206. else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  207. fSuccess = TraceFALSE(NULL);
  208. else if ((hdcMem2 = CreateCompatibleDC(hdc)) == NULL)
  209. fSuccess = TraceFALSE(NULL);
  210. else if ((hbmpOld = SelectObject(hdcMem, hBitmap)), FALSE)
  211. ;
  212. else if ((hbmpOld2 = SelectObject(hdcMem2, hbmpMask)), FALSE)
  213. ;
  214. else if (SetBkColor(hdcMem, crTransparent), FALSE)
  215. ;
  216. else if (!BitBlt(hdcMem2, 0, 0, cx, cy, hdcMem, 0, 0, SRCCOPY))
  217. fSuccess = TraceFALSE(NULL);
  218. else if ((crBkOld = SetBkColor(hdc, RGB(255, 255, 255))) == CLR_INVALID)
  219. fSuccess = TraceFALSE(NULL);
  220. else if ((crTextOld = SetTextColor(hdc, RGB(0, 0, 0))) == CLR_INVALID)
  221. fSuccess = TraceFALSE(NULL);
  222. else if (!BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCINVERT))
  223. fSuccess = TraceFALSE(NULL);
  224. else if (!BitBlt(hdc, x, y, cx, cy, hdcMem2, 0, 0, SRCAND))
  225. fSuccess = TraceFALSE(NULL);
  226. else if (!BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCINVERT))
  227. fSuccess = TraceFALSE(NULL);
  228. else if (SetBkColor(hdc, crBkOld) == CLR_INVALID)
  229. fSuccess = TraceFALSE(NULL);
  230. else if (SetTextColor(hdc, crTextOld) == CLR_INVALID)
  231. fSuccess = TraceFALSE(NULL);
  232. else if (SelectObject(hdcMem, hbmpOld), FALSE)
  233. ;
  234. else if (SelectObject(hdcMem2, hbmpOld2), FALSE)
  235. ;
  236. if (hbmpMask != NULL && !DeleteObject(hbmpMask))
  237. fSuccess = TraceFALSE(NULL);
  238. else
  239. hbmpMask = NULL;
  240. if (hdcMem != NULL && !DeleteDC(hdcMem))
  241. fSuccess = TraceFALSE(NULL);
  242. else
  243. hdcMem = NULL;
  244. if (hdcMem2 != NULL && !DeleteDC(hdcMem2))
  245. fSuccess = TraceFALSE(NULL);
  246. else
  247. hdcMem2 = NULL;
  248. return 0;
  249. }
  250. #else
  251. int DLLEXPORT WINAPI GfxBitmapDrawTransparent(HDC hdc, HBITMAP hBitmap, int x, int y, COLORREF crTransparent, DWORD dwFlags)
  252. {
  253. BOOL fSuccess = TRUE;
  254. BITMAP bmp;
  255. POINT ptSize;
  256. COLORREF cr;
  257. HBITMAP hbmpAndBack = NULL;
  258. HBITMAP hbmpAndObject = NULL;
  259. HBITMAP hbmpAndMem = NULL;
  260. HBITMAP hbmpSave = NULL;
  261. HBITMAP hbmpBackOld = NULL;
  262. HBITMAP hbmpObjectOld = NULL;
  263. HBITMAP hbmpMemOld = NULL;
  264. HBITMAP hbmpSaveOld = NULL;
  265. HDC hdcTemp = NULL;
  266. HDC hdcBack = NULL;
  267. HDC hdcObject = NULL;
  268. HDC hdcMem = NULL;
  269. HDC hdcSave = NULL;
  270. // Select the bitmap
  271. //
  272. if ((hdcTemp = CreateCompatibleDC(hdc)) == NULL)
  273. fSuccess = TraceFALSE(NULL);
  274. else if (SelectObject(hdcTemp, hBitmap), FALSE)
  275. ;
  276. // Get dimensions of bitmap
  277. //
  278. else if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0)
  279. fSuccess = TraceFALSE(NULL);
  280. else if (ptSize.x = bmp.bmWidth, ptSize.y = bmp.bmHeight, FALSE)
  281. ;
  282. // Convert from device to logical points
  283. //
  284. else if (!DPtoLP(hdcTemp, &ptSize, 1))
  285. fSuccess = TraceFALSE(NULL);
  286. // Create some DCs to hold temporary data.
  287. //
  288. else if ((hdcBack = CreateCompatibleDC(hdc)) == NULL)
  289. fSuccess = TraceFALSE(NULL);
  290. else if ((hdcObject = CreateCompatibleDC(hdc)) == NULL)
  291. fSuccess = TraceFALSE(NULL);
  292. else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  293. fSuccess = TraceFALSE(NULL);
  294. else if ((hdcSave = CreateCompatibleDC(hdc)) == NULL)
  295. fSuccess = TraceFALSE(NULL);
  296. // Create a bitmap for each DC. DCs are required for a number of GDI functions.
  297. //
  298. else if ((hbmpAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL)) == NULL)
  299. fSuccess = TraceFALSE(NULL);
  300. else if ((hbmpAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL)) == NULL)
  301. fSuccess = TraceFALSE(NULL);
  302. else if ((hbmpAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL)
  303. fSuccess = TraceFALSE(NULL);
  304. else if ((hbmpSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL)
  305. fSuccess = TraceFALSE(NULL);
  306. // Each DC must select a bitmap object to store pixel data.
  307. //
  308. else if ((hbmpBackOld = SelectObject(hdcBack, hbmpAndBack)) == NULL)
  309. fSuccess = TraceFALSE(NULL);
  310. else if ((hbmpObjectOld = SelectObject(hdcObject, hbmpAndObject)) == NULL)
  311. fSuccess = TraceFALSE(NULL);
  312. else if ((hbmpMemOld = SelectObject(hdcMem, hbmpAndMem)) == NULL)
  313. fSuccess = TraceFALSE(NULL);
  314. else if ((hbmpSaveOld = SelectObject(hdcSave, hbmpSave)) == NULL)
  315. fSuccess = TraceFALSE(NULL);
  316. // Set proper mapping mode.
  317. //
  318. else if (SetMapMode(hdcTemp, GetMapMode(hdc)) == 0)
  319. fSuccess = TraceFALSE(NULL);
  320. // Save the bitmap sent here, because it will be overwritten.
  321. //
  322. else if (!BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY))
  323. fSuccess = TraceFALSE(NULL);
  324. // Set the background color of the source DC to the color.
  325. // contained in the parts of the bitmap that should be transparent
  326. //
  327. else if ((cr = SetBkColor(hdcTemp, crTransparent)) == CLR_INVALID)
  328. fSuccess = TraceFALSE(NULL);
  329. // Create the object mask for the bitmap by performing a BitBlt
  330. // from the source bitmap to a monochrome bitmap.
  331. //
  332. else if (!BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY))
  333. fSuccess = TraceFALSE(NULL);
  334. // Set the background color of the source DC back to original color.
  335. //
  336. else if (SetBkColor(hdcTemp, cr) == CLR_INVALID)
  337. fSuccess = TraceFALSE(NULL);
  338. // Create the inverse of the object mask.
  339. //
  340. else if (!BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY))
  341. fSuccess = TraceFALSE(NULL);
  342. // Copy the background of the main DC to the destination.
  343. //
  344. else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, x, y, SRCCOPY))
  345. fSuccess = TraceFALSE(NULL);
  346. // Mask out the places where the bitmap will be placed.
  347. //
  348. else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND))
  349. fSuccess = TraceFALSE(NULL);
  350. // Mask out the transparent colored pixels on the bitmap.
  351. //
  352. else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND))
  353. fSuccess = TraceFALSE(NULL);
  354. // XOR the bitmap with the background on the destination DC.
  355. //
  356. else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT))
  357. fSuccess = TraceFALSE(NULL);
  358. // Copy the destination to the screen.
  359. //
  360. else if (!BitBlt(hdc, x, y, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY))
  361. fSuccess = TraceFALSE(NULL);
  362. // Place the original bitmap back into the bitmap sent here.
  363. //
  364. else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY))
  365. fSuccess = TraceFALSE(NULL);
  366. // restore old bitmaps
  367. //
  368. if (hdcBack != NULL && hbmpBackOld != NULL &&
  369. SelectObject(hdcBack, hbmpBackOld) == NULL)
  370. fSuccess = TraceFALSE(NULL);
  371. if (hdcObject != NULL && hbmpObjectOld != NULL &&
  372. SelectObject(hdcObject, hbmpObjectOld) == NULL)
  373. fSuccess = TraceFALSE(NULL);
  374. if (hdcMem != NULL && hbmpMemOld != NULL &&
  375. SelectObject(hdcMem, hbmpMemOld) == NULL)
  376. fSuccess = TraceFALSE(NULL);
  377. if (hdcSave != NULL && hbmpSaveOld != NULL &&
  378. SelectObject(hdcSave, hbmpSaveOld) == NULL)
  379. fSuccess = TraceFALSE(NULL);
  380. // Delete the memory bitmaps.
  381. //
  382. if (hbmpAndBack != NULL && !DeleteObject(hbmpAndBack))
  383. fSuccess = TraceFALSE(NULL);
  384. if (hbmpAndObject != NULL && !DeleteObject(hbmpAndObject))
  385. fSuccess = TraceFALSE(NULL);
  386. if (hbmpAndMem != NULL && !DeleteObject(hbmpAndMem))
  387. fSuccess = TraceFALSE(NULL);
  388. if (hbmpSave != NULL && !DeleteObject(hbmpSave))
  389. fSuccess = TraceFALSE(NULL);
  390. // Delete the memory DCs.
  391. //
  392. if (hdcBack != NULL && !DeleteDC(hdcBack))
  393. fSuccess = TraceFALSE(NULL);
  394. if (hdcObject != NULL && !DeleteDC(hdcObject))
  395. fSuccess = TraceFALSE(NULL);
  396. if (hdcMem != NULL && !DeleteDC(hdcMem))
  397. fSuccess = TraceFALSE(NULL);
  398. if (hdcSave != NULL && !DeleteDC(hdcSave))
  399. fSuccess = TraceFALSE(NULL);
  400. if (hdcTemp != NULL && !DeleteDC(hdcTemp))
  401. fSuccess = TraceFALSE(NULL);
  402. return fSuccess ? 0 : -1;
  403. }
  404. #endif
  405. // GfxBitmapScroll - scroll specified bitmap
  406. // <hdc> (i) device context for destination window
  407. // <hBitmap> (i) bitmap handle for source bitmap
  408. // <dx> (i) amt of horizontal scroll (cx < 0 scrolls left)
  409. // <dy> (i) amt of vertical scroll (cx < 0 scrolls up)
  410. // <dwFlags> (i) control flags
  411. // BS_ROTATE rotate bitmap
  412. // return 0 if success
  413. //
  414. int DLLEXPORT WINAPI GfxBitmapScroll(HDC hdc, HBITMAP hBitmap, int dx, int dy, DWORD dwFlags)
  415. {
  416. BOOL fSuccess = TRUE;
  417. BITMAP bmp;
  418. POINT ptSize;
  419. HDC hdcMem = NULL;
  420. HDC hdcTemp = NULL;
  421. HBITMAP hbmpTemp = NULL;
  422. HBITMAP hbmpSave = NULL;
  423. int dxAbs;
  424. int dyAbs;
  425. // Get dimensions of bitmap
  426. //
  427. if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0)
  428. fSuccess = TraceFALSE(NULL);
  429. else if (ptSize.x = bmp.bmWidth, ptSize.y = bmp.bmHeight, FALSE)
  430. ;
  431. else if (dx = dx % ptSize.x, dy = dy % ptSize.y, FALSE)
  432. ;
  433. else if (dxAbs = abs(dx), dyAbs = abs(dy), FALSE)
  434. ;
  435. // prepare mem dc
  436. //
  437. else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  438. fSuccess = TraceFALSE(NULL);
  439. else if (!DPtoLP(hdcMem, &ptSize, 1))
  440. fSuccess = TraceFALSE(NULL);
  441. else if (SelectObject(hdcMem, hBitmap), FALSE)
  442. ;
  443. // Set proper mapping mode.
  444. //
  445. else if (SetMapMode(hdcMem, GetMapMode(hdc)) == 0)
  446. fSuccess = TraceFALSE(NULL);
  447. // prepare temp copy
  448. //
  449. else if (dwFlags & BS_ROTATE)
  450. {
  451. if ((hdcTemp = CreateCompatibleDC(hdc)) == NULL)
  452. fSuccess = TraceFALSE(NULL);
  453. else if ((hbmpTemp = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL)
  454. fSuccess = TraceFALSE(NULL);
  455. else if ((hbmpSave = SelectObject(hdcTemp, hbmpTemp)), FALSE)
  456. ;
  457. else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY))
  458. fSuccess = TraceFALSE(NULL);
  459. }
  460. // scroll (rotate if specified)
  461. //
  462. if (fSuccess && dx < 0)
  463. {
  464. if (!BitBlt(hdcMem,
  465. 0, 0,
  466. ptSize.x - dxAbs, ptSize.y,
  467. hdcMem,
  468. dxAbs, 0,
  469. SRCCOPY))
  470. fSuccess = TraceFALSE(NULL);
  471. else if ((dwFlags & BS_ROTATE) &&
  472. !BitBlt(hdcMem,
  473. ptSize.x - dxAbs, 0,
  474. dxAbs, ptSize.y,
  475. hdcTemp,
  476. 0, 0,
  477. SRCCOPY))
  478. fSuccess = TraceFALSE(NULL);
  479. }
  480. if (fSuccess && dx > 0)
  481. {
  482. if (!BitBlt(hdcMem,
  483. dxAbs, 0,
  484. ptSize.x - dxAbs, ptSize.y,
  485. hdcMem,
  486. 0, 0,
  487. SRCCOPY))
  488. fSuccess = TraceFALSE(NULL);
  489. else if ((dwFlags & BS_ROTATE) &&
  490. !BitBlt(hdcMem,
  491. 0, 0,
  492. dxAbs, ptSize.y,
  493. hdcTemp,
  494. ptSize.x - dxAbs, 0,
  495. SRCCOPY))
  496. fSuccess = TraceFALSE(NULL);
  497. }
  498. if (fSuccess && dy < 0)
  499. {
  500. if ((dwFlags & BS_ROTATE) && dx != 0 &&
  501. !BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY))
  502. fSuccess = TraceFALSE(NULL);
  503. else if (!BitBlt(hdcMem,
  504. 0, 0,
  505. ptSize.x, ptSize.y - dyAbs,
  506. hdcMem,
  507. 0, dyAbs,
  508. SRCCOPY))
  509. fSuccess = TraceFALSE(NULL);
  510. else if ((dwFlags & BS_ROTATE) &&
  511. !BitBlt(hdcMem,
  512. 0, ptSize.y - dyAbs,
  513. ptSize.x, dyAbs,
  514. hdcTemp,
  515. 0, 0,
  516. SRCCOPY))
  517. fSuccess = TraceFALSE(NULL);
  518. }
  519. if (fSuccess && dy > 0)
  520. {
  521. if ((dwFlags & BS_ROTATE) && dx != 0 &&
  522. !BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY))
  523. fSuccess = TraceFALSE(NULL);
  524. else if (!BitBlt(hdcMem,
  525. 0, dyAbs,
  526. ptSize.x, ptSize.y - dyAbs,
  527. hdcMem,
  528. 0, 0,
  529. SRCCOPY))
  530. fSuccess = TraceFALSE(NULL);
  531. else if ((dwFlags & BS_ROTATE) &&
  532. !BitBlt(hdcMem,
  533. 0, 0,
  534. ptSize.x, dyAbs,
  535. hdcTemp,
  536. 0, ptSize.y - dyAbs,
  537. SRCCOPY))
  538. fSuccess = TraceFALSE(NULL);
  539. }
  540. if (!fSuccess)
  541. ;
  542. // copy back to original bitmap
  543. //
  544. else if (!BitBlt(hdc, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY))
  545. fSuccess = TraceFALSE(NULL);
  546. // clean up
  547. //
  548. if (hdcTemp != NULL)
  549. SelectObject(hdcTemp, hbmpSave);
  550. if (hdcMem != NULL && !DeleteDC(hdcMem))
  551. fSuccess = TraceFALSE(NULL);
  552. if (hbmpTemp != NULL && !DeleteObject(hbmpTemp))
  553. fSuccess = TraceFALSE(NULL);
  554. if (hdcTemp != NULL && !DeleteDC(hdcTemp))
  555. fSuccess = TraceFALSE(NULL);
  556. return fSuccess ? 0 : -1;
  557. }
  558. // GfxLoadBitmapEx - load specified bitmap resource, get palette
  559. // <hInstance> (i) handle of module to load resource from
  560. // NULL load pre-defined Windows bitmap
  561. // <lpszBitmap> (i) name of bitmap resource
  562. // or MAKEINTRESOURCE(idBitmap)
  563. // or <OBM_xxx> if hInstance is NULL
  564. // <lphPalette> (o) palette is returned here
  565. // NULL do not return palette
  566. // return bitmap handle if success, otherwise NULL
  567. // NOTE: see documentation for LoadBitmap function
  568. // NOTE: call DeleteObject() to free returned bitmap and palette handles
  569. //
  570. HBITMAP DLLEXPORT WINAPI GfxLoadBitmapEx(HINSTANCE hInstance,
  571. LPCTSTR lpszBitmap, HPALETTE FAR *lphPalette)
  572. {
  573. BOOL fSuccess = TRUE;
  574. HRSRC hRsrc = NULL;
  575. HGLOBAL hGlobal = NULL;
  576. LPBITMAPINFOHEADER lpbi = NULL;
  577. HDC hdc = NULL;
  578. HPALETTE hPalette = NULL;
  579. HBITMAP hBitmap = NULL;
  580. int nColors;
  581. if ((hRsrc = FindResource(hInstance, lpszBitmap, RT_BITMAP)) == NULL)
  582. fSuccess = TraceFALSE(NULL);
  583. else if ((hGlobal = LoadResource(hInstance, hRsrc)) == NULL)
  584. fSuccess = TraceFALSE(NULL);
  585. else if ((lpbi = (LPBITMAPINFOHEADER) LockResource(hGlobal)) == NULL)
  586. fSuccess = TraceFALSE(NULL);
  587. else if ((hdc = GetDC(NULL)) == NULL)
  588. fSuccess = TraceFALSE(NULL);
  589. else if ((hPalette = CreateDIBPalette((LPBITMAPINFO)lpbi, &nColors)) == NULL)
  590. fSuccess = TraceFALSE(NULL);
  591. else if (SelectPalette(hdc, hPalette, FALSE), FALSE)
  592. ;
  593. else if (RealizePalette(hdc) == GDI_ERROR)
  594. fSuccess = TraceFALSE(NULL);
  595. else if ((hBitmap = CreateDIBitmap(hdc,
  596. (LPBITMAPINFOHEADER) lpbi, (LONG) CBM_INIT,
  597. (LPSTR)lpbi + lpbi->biSize + nColors * sizeof(RGBQUAD),
  598. (LPBITMAPINFO) lpbi, DIB_RGB_COLORS)) == NULL)
  599. {
  600. fSuccess = TraceFALSE(NULL);
  601. }
  602. // clean up
  603. //
  604. #ifndef _WIN32
  605. if (hGlobal != NULL)
  606. {
  607. UnlockResource(hGlobal);
  608. FreeResource(hGlobal);
  609. }
  610. #endif
  611. if (hdc != NULL)
  612. ReleaseDC(NULL, hdc);
  613. if (!fSuccess || lphPalette == NULL)
  614. {
  615. if (hPalette != NULL && !DeleteObject(hPalette))
  616. fSuccess = TraceFALSE(NULL);
  617. }
  618. // return palette handle here
  619. //
  620. if (fSuccess && lphPalette != NULL)
  621. *lphPalette = hPalette;
  622. // return bitmap handle here
  623. //
  624. return fSuccess ? hBitmap : NULL;
  625. }
  626. // GfxCreateDIBPalette - create palette
  627. // <lpbmi> (i) ptr to BITMAPINFO struct, describes DIB
  628. // <lpnColors> (o) number of colors is returned here
  629. // return new palette handle if success, otherwise NULL
  630. //
  631. HPALETTE DLLEXPORT WINAPI CreateDIBPalette (LPBITMAPINFO lpbmi, LPINT lpnColors)
  632. {
  633. BOOL fSuccess = TRUE;
  634. LPBITMAPINFOHEADER lpbi;
  635. LPLOGPALETTE lpPal = NULL;
  636. HPALETTE hPal = NULL;
  637. int nColors;
  638. if ((lpbi = (LPBITMAPINFOHEADER) lpbmi) == NULL)
  639. fSuccess = TraceFALSE(NULL);
  640. else
  641. {
  642. // calculate color table size
  643. //
  644. if (lpbi->biBitCount <= 8)
  645. nColors = (1 << lpbi->biBitCount);
  646. else
  647. nColors = 0; // No palette needed for 24 BPP DIB
  648. if (lpbi->biClrUsed > 0)
  649. nColors = lpbi->biClrUsed; // Use biClrUsed
  650. if (nColors <= 0)
  651. fSuccess = TraceFALSE(NULL);
  652. }
  653. if (fSuccess)
  654. {
  655. if ((lpPal = (LPLOGPALETTE) MemAlloc(NULL, sizeof(LOGPALETTE) +
  656. sizeof(PALETTEENTRY) * nColors, 0)) == NULL)
  657. fSuccess = TraceFALSE(NULL);
  658. else
  659. {
  660. int i;
  661. //
  662. // We have to initalize the memory allocated with MemAlloc
  663. //
  664. memset( lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nColors);
  665. lpPal->palVersion = 0x300;
  666. lpPal->palNumEntries = (unsigned short) nColors;
  667. for (i = 0; i < nColors; i++)
  668. {
  669. lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
  670. lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  671. lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
  672. lpPal->palPalEntry[i].peFlags = 0;
  673. }
  674. if ((hPal = CreatePalette(lpPal)) == NULL)
  675. fSuccess = TraceFALSE(NULL);
  676. if ((lpPal = MemFree(NULL, lpPal)) != NULL)
  677. {
  678. //
  679. // We should delete hPal resource
  680. //
  681. DeleteObject( hPal );
  682. hPal = NULL;
  683. fSuccess = TraceFALSE(NULL);
  684. }
  685. }
  686. }
  687. // return number of colors here
  688. //
  689. if (fSuccess && lpnColors != NULL)
  690. *lpnColors = nColors;
  691. // return new palette here
  692. //
  693. return fSuccess ? hPal : NULL;
  694. }
  695. ////
  696. // text routines
  697. ////
  698. // GfxTextExtentTruncate - truncate string if too long
  699. // <lpsz> (i/o) string to truncate
  700. // <hdc> (i) current device context
  701. // <cxMax> (i) maximum string width in logical units
  702. // return new length of string (0 if error)
  703. //
  704. int DLLEXPORT WINAPI GfxTextExtentTruncate(LPTSTR lpsz, HDC hdc, int cxMax)
  705. {
  706. BOOL fSuccess = TRUE;
  707. int cbString;
  708. if (hdc == NULL)
  709. fSuccess = TraceFALSE(NULL);
  710. else if (lpsz == NULL)
  711. fSuccess = TraceFALSE(NULL);
  712. else
  713. {
  714. // calculate how many chars in string will fit within cxMax
  715. //
  716. cbString = StrLen(lpsz);
  717. while (fSuccess && cbString > 0)
  718. {
  719. SIZE size;
  720. if (!GetTextExtentPoint(hdc, lpsz, cbString, &size))
  721. fSuccess = TraceFALSE(NULL);
  722. else if (size.cx <= cxMax)
  723. break;
  724. else
  725. --cbString;
  726. }
  727. // truncate string so it fits
  728. //
  729. *(lpsz + cbString) = '\0';
  730. }
  731. return fSuccess ? cbString : 0;
  732. }
  733. ////
  734. // cursor routines
  735. ////
  736. // GfxShowHourglass - show the hourglass cursor
  737. // <hwndCapture> (i) window to capture mouse input during hourglass
  738. // return old cursor (NULL if error or none)
  739. //
  740. HCURSOR DLLEXPORT WINAPI GfxShowHourglass(HWND hwnd)
  741. {
  742. BOOL fSuccess = TRUE;
  743. HCURSOR hCursorSave;
  744. HCURSOR hCursorHourglass;
  745. // get predefined hourglass cursor handle
  746. //
  747. if ((hCursorHourglass = LoadCursor(NULL, IDC_WAIT)) == NULL)
  748. fSuccess = TraceFALSE(NULL);
  749. else
  750. {
  751. // capture all mouse input to specified window
  752. //
  753. SetCapture(hwnd);
  754. // replace previous cursor with hourglass
  755. //
  756. hCursorSave = SetCursor(hCursorHourglass);
  757. }
  758. return fSuccess ? hCursorSave : NULL;
  759. }
  760. // GfxHideHourglass - hide the hourglass cursor
  761. // <hCursorRestore> (i) cursor handle returned from GfxShowHourglass
  762. // NULL replace cursor with IDC_ARROW
  763. // return 0 if success
  764. //
  765. int DLLEXPORT WINAPI GfxHideHourglass(HCURSOR hCursorRestore)
  766. {
  767. BOOL fSuccess = TRUE;
  768. // get predefined arrow cursor handle if necessary
  769. //
  770. if (hCursorRestore == NULL)
  771. hCursorRestore = LoadCursor(NULL, IDC_ARROW);
  772. // replace hourglass with previous cursor
  773. //
  774. if (SetCursor(hCursorRestore) == NULL)
  775. fSuccess = TraceFALSE(NULL);
  776. // restore normal mouse input processing
  777. //
  778. ReleaseCapture();
  779. return fSuccess ? 0 : -1;
  780. }
  781. // GfxDeviceIsMono - determine if device context is monochrome
  782. // <hdc> (i) device context
  783. // NULL use screen device context
  784. // return TRUE if monochrome, FALSE if color
  785. //
  786. BOOL DLLEXPORT WINAPI GfxDeviceIsMono(HDC hdc)
  787. {
  788. BOOL fSuccess = TRUE;
  789. BOOL fMono;
  790. HDC hdcScreen = NULL;
  791. // get screen device context if none specified
  792. //
  793. if (hdc == NULL && (hdc = hdcScreen = GetDC(NULL)) == NULL)
  794. fSuccess = TraceFALSE(NULL);
  795. else
  796. {
  797. int nColors = GetDeviceCaps(hdc, NUMCOLORS);
  798. fMono = (BOOL) (nColors >= 0 && nColors <= 2);
  799. // release screen device context if necessary
  800. //
  801. if (hdcScreen != NULL && !ReleaseDC(NULL, hdcScreen))
  802. fSuccess = TraceFALSE(NULL);
  803. }
  804. return fSuccess ? fMono : TRUE;
  805. }