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.

295 lines
8.5 KiB

  1. /***************************************************************************\
  2. * Module Name: wmicon.c
  3. *
  4. * Icon Drawing Routines
  5. *
  6. * Copyright (c) 1985 - 1999, Microsoft Corporation
  7. *
  8. * 22-Jan-1991 MikeKe from win30
  9. * 13-Jan-1994 JohnL rewrote from Chicago (m5)
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #define GetCWidth(cxOrg, lrF, cxDes) \
  14. (cxOrg ? cxOrg : ((lrF & DI_DEFAULTSIZE) ? SYSMET(CXICON) : cxDes))
  15. #define GetCHeight(cyOrg, lrF, cyDes) \
  16. (cyOrg ? cyOrg : ((lrF & DI_DEFAULTSIZE) ? SYSMET(CYICON) : cyDes))
  17. /***************************************************************************\
  18. * BltIcon
  19. *
  20. * Note: We use the following DI flags to indicate what bitmap to draw:
  21. * DI_IMAGE - render the color image bits (also known as XOR image)
  22. * DI_MASK - render the mask bits (also known and AND image)
  23. * DI_NORMAL - even though this is normally used to indicate that both the
  24. * mask and the image pieces of the icon should be rendered, it
  25. * is used here to indicate that the alpha channel should be
  26. * rendered. See _DrawIconEx.
  27. \***************************************************************************/
  28. BOOL BltIcon(
  29. HDC hdc,
  30. int x,
  31. int y,
  32. int cx,
  33. int cy,
  34. HDC hdcSrc,
  35. PCURSOR pcur,
  36. UINT diFlag,
  37. LONG rop)
  38. {
  39. HBITMAP hbmpSave;
  40. HBITMAP hbmpUse;
  41. LONG rgbText;
  42. LONG rgbBk;
  43. int nMode;
  44. int yBlt = 0;
  45. /*
  46. * Setup the DC for drawing
  47. */
  48. switch (diFlag) {
  49. default:
  50. case DI_IMAGE:
  51. hbmpUse = pcur->hbmColor;
  52. /*
  53. * If there isn't an explicit color bitmap, it is encoded
  54. * along with the mask, but in the second half.
  55. */
  56. if (NULL == hbmpUse) {
  57. hbmpUse = pcur->hbmMask;
  58. yBlt = pcur->cy / 2;
  59. }
  60. break;
  61. case DI_MASK:
  62. hbmpUse = pcur->hbmMask;
  63. break;
  64. case DI_NORMAL:
  65. UserAssert(pcur->hbmUserAlpha != NULL);
  66. hbmpUse = pcur->hbmUserAlpha;
  67. break;
  68. }
  69. rgbBk = GreSetBkColor(hdc, 0x00FFFFFFL);
  70. rgbText = GreSetTextColor(hdc, 0x00000000L);
  71. nMode = SetBestStretchMode(hdc, pcur->bpp, FALSE);
  72. hbmpSave = GreSelectBitmap(hdcSrc, hbmpUse);
  73. if (diFlag == DI_NORMAL) {
  74. BLENDFUNCTION bf;
  75. bf.BlendOp = AC_SRC_OVER;
  76. bf.BlendFlags = AC_MIRRORBITMAP;
  77. bf.SourceConstantAlpha = 0xFF;
  78. bf.AlphaFormat = AC_SRC_ALPHA;
  79. GreAlphaBlend(hdc,
  80. x,
  81. y,
  82. cx,
  83. cy,
  84. hdcSrc,
  85. 0,
  86. yBlt,
  87. pcur->cx,
  88. pcur->cy / 2,
  89. bf,
  90. NULL);
  91. }
  92. else {
  93. /*
  94. * Do the output to the surface. By passing in (-1) as the background
  95. * color, we are telling GDI to use the background-color already set
  96. * in the DC.
  97. */
  98. GreStretchBlt(hdc,
  99. x,
  100. y,
  101. cx,
  102. cy,
  103. hdcSrc,
  104. 0,
  105. yBlt,
  106. pcur->cx,
  107. pcur->cy / 2,
  108. rop,
  109. (COLORREF)-1);
  110. }
  111. GreSetStretchBltMode(hdc, nMode);
  112. GreSetTextColor(hdc, rgbText);
  113. GreSetBkColor(hdc, rgbBk);
  114. GreSelectBitmap(hdcSrc, hbmpSave);
  115. return TRUE;
  116. }
  117. /***************************************************************************\
  118. * DrawIconEx
  119. *
  120. * Draws icon in desired size.
  121. *
  122. \***************************************************************************/
  123. BOOL _DrawIconEx(
  124. HDC hdc,
  125. int x,
  126. int y,
  127. PCURSOR pcur,
  128. int cx,
  129. int cy,
  130. UINT istepIfAniCur,
  131. HBRUSH hbr,
  132. UINT diFlags)
  133. {
  134. BOOL fSuccess = FALSE;
  135. BOOL fAlpha = FALSE;
  136. LONG rop = (diFlags & DI_NOMIRROR) ? NOMIRRORBITMAP : 0;
  137. /*
  138. * If this is an animated cursor, just grab the ith frame and use it
  139. * for drawing.
  140. */
  141. if (pcur->CURSORF_flags & CURSORF_ACON) {
  142. if ((int)istepIfAniCur >= ((PACON)pcur)->cicur) {
  143. RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "DrawIconEx, icon step out of range.");
  144. goto Done;
  145. }
  146. pcur = ((PACON)pcur)->aspcur[((PACON)pcur)->aicur[istepIfAniCur]];
  147. }
  148. /*
  149. * We really want to draw an alpha icon if we can. But we need to
  150. * respect the user's request to draw only the image or only the
  151. * mask. We decide if we are, or are not, going to draw the icon
  152. * with alpha information here.
  153. */
  154. if (pcur->hbmUserAlpha != NULL && ((diFlags & DI_NORMAL) == DI_NORMAL)) {
  155. fAlpha = TRUE;
  156. }
  157. /*
  158. * Setup defaults.
  159. */
  160. cx = GetCWidth(cx, diFlags, pcur->cx);
  161. cy = GetCHeight(cy, diFlags, (pcur->cy / 2));
  162. if (hbr) {
  163. HBITMAP hbmpT = NULL;
  164. HDC hdcT;
  165. HBITMAP hbmpOld;
  166. POLYPATBLT PolyData;
  167. if (hdcT = GreCreateCompatibleDC(hdc)) {
  168. if (hbmpT = GreCreateCompatibleBitmap(hdc, cx, cy)) {
  169. POINT pt;
  170. BOOL bRet;
  171. hbmpOld = GreSelectBitmap(hdcT, hbmpT);
  172. /*
  173. * Set new dc's brush origin in same relative
  174. * location as passed-in dc's.
  175. */
  176. bRet = GreGetBrushOrg(hdc, &pt);
  177. /*
  178. * Bug 292396 - joejo
  179. * Stop overactive asserts by replacing with RIPMSG.
  180. */
  181. if (bRet != TRUE) {
  182. RIPMSG0(RIP_WARNING, "DrawIconEx, GreGetBrushOrg failed.");
  183. }
  184. bRet = GreSetBrushOrg(hdcT, pt.x, pt.y, NULL);
  185. if (bRet != TRUE) {
  186. RIPMSG0(RIP_WARNING, "DrawIconEx, GreSetBrushOrg failed.");
  187. }
  188. PolyData.x = 0;
  189. PolyData.y = 0;
  190. PolyData.cx = cx;
  191. PolyData.cy = cy;
  192. PolyData.BrClr.hbr = hbr;
  193. bRet = GrePolyPatBlt(hdcT, PATCOPY, &PolyData, 1, PPB_BRUSH);
  194. if (bRet != TRUE) {
  195. RIPMSG0(RIP_WARNING, "DrawIconEx, GrePolyPatBlt failed.");
  196. }
  197. /*
  198. * Output the image to the temporary memoryDC.
  199. */
  200. if (fAlpha) {
  201. BltIcon(hdcT, 0, 0, cx, cy, ghdcMem, pcur, DI_NORMAL, rop | SRCCOPY);
  202. }
  203. else {
  204. BltIcon(hdcT, 0, 0, cx, cy, ghdcMem, pcur, DI_MASK, rop | SRCAND);
  205. BltIcon(hdcT, 0, 0, cx, cy, ghdcMem, pcur, DI_IMAGE, rop | SRCINVERT);
  206. }
  207. /*
  208. * Blt the bitmap to the original DC.
  209. */
  210. GreBitBlt(hdc, x, y, cx, cy, hdcT, 0, 0, SRCCOPY, (COLORREF)-1);
  211. GreSelectBitmap(hdcT, hbmpOld);
  212. bRet = GreDeleteObject(hbmpT);
  213. if (bRet != TRUE) {
  214. RIPMSG0(RIP_WARNING, "DrawIconEx, GreDeleteObject failed. Possible Leak");
  215. }
  216. fSuccess = TRUE;
  217. }
  218. GreDeleteDC(hdcT);
  219. }
  220. } else {
  221. if (fAlpha) {
  222. BltIcon(hdc, x, y, cx, cy, ghdcMem, pcur, DI_NORMAL, rop | SRCCOPY);
  223. } else {
  224. if (diFlags & DI_MASK) {
  225. BltIcon(hdc,
  226. x,
  227. y,
  228. cx,
  229. cy,
  230. ghdcMem,
  231. pcur,
  232. DI_MASK,
  233. ((diFlags & DI_IMAGE) ? rop | SRCAND : rop | SRCCOPY));
  234. }
  235. if (diFlags & DI_IMAGE) {
  236. BltIcon(hdc,
  237. x,
  238. y,
  239. cx,
  240. cy,
  241. ghdcMem,
  242. pcur,
  243. DI_IMAGE,
  244. ((diFlags & DI_MASK) ? rop | SRCINVERT : rop | SRCCOPY));
  245. }
  246. }
  247. fSuccess = TRUE;
  248. }
  249. Done:
  250. return fSuccess;
  251. }