Workaround for icon stretching. Makes icons in title bar and taskbar display
properly.
Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c

Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c
--- trunk/reactos/subsys/win32k/ntuser/cursoricon.c	2005-10-24 21:54:26 UTC (rev 18762)
+++ trunk/reactos/subsys/win32k/ntuser/cursoricon.c	2005-10-24 21:57:32 UTC (rev 18763)
@@ -1269,7 +1269,82 @@
 }
 
 
-#define CANSTRETCHBLT 0
+#define STRETCH_CAN_SRCCOPY_ONLY
+
+#ifdef STRETCH_CAN_SRCCOPY_ONLY
+void
+FASTCALL
+DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest,
+             HDC DcSrc, int XSrc, int YSrc, int WidthSrc, int HeightSrc,
+             DWORD Rop3, BOOL Color)
+{
+   HDC DcStretched;
+   HBITMAP BitmapStretched;
+   HBITMAP OldBitmap;
+
+   if (WidthDest == WidthSrc && HeightDest == HeightSrc)
+   {
+      NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
+                  DcSrc, XSrc, YSrc, Rop3);
+   }
+   else if (SRCCOPY == Rop3)
+   {
+      NtGdiStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
+                      DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
+                      Rop3);
+   }
+   else
+   {
+      DcStretched = NtGdiCreateCompatibleDC(DcSrc);
+      if (NULL == DcStretched)
+      {
+         DPRINT1("Failed to create compatible DC\n");
+         return;
+      }
+      if (Color)
+      {
+         BitmapStretched = NtGdiCreateCompatibleBitmap(DcDest, WidthDest,
+                                                       HeightDest);
+      }
+      else
+      {
+         BitmapStretched = NtGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
+      }
+      if (NULL == BitmapStretched)
+      {
+         NtGdiDeleteDC(DcStretched);
+         DPRINT1("Failed to create temporary bitmap\n");
+         return;
+      }
+      OldBitmap = NtGdiSelectObject(DcStretched, BitmapStretched);
+      if (NULL == OldBitmap)
+      {
+         NtGdiDeleteObject(BitmapStretched);
+         NtGdiDeleteDC(DcStretched);
+         DPRINT1("Failed to create temporary bitmap\n");
+         return;
+      }
+      if (! NtGdiStretchBlt(DcStretched, 0, 0, WidthDest, HeightDest,
+                            DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
+                            SRCCOPY) ||
+          ! NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
+                        DcStretched, 0, 0, Rop3))
+      {
+         DPRINT1("Failed to blt\n");
+      }
+      NtGdiSelectObject(DcStretched, OldBitmap);
+      NtGdiDeleteObject(BitmapStretched);
+      NtGdiDeleteDC(DcStretched);
+   }
+}
+#else
+#define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \
+                     DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \
+        NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \
+                        (DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \
+                        (Rop3))
+#endif /* STRETCH_CAN_SRCCOPY_ONLY */
+
 /*
  * @implemented
  */
@@ -1281,7 +1356,7 @@
    int yTop,
    HICON hIcon,
    int cxWidth,
-   int cyWidth,
+   int cyHeight,
    UINT istepIfAniCur,
    HBRUSH hbrFlickerFreeDraw,
    UINT diFlags,
@@ -1299,10 +1374,7 @@
    HBITMAP hbmOff = (HBITMAP)0;
    HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem;
    BOOL Ret = FALSE;
-#if CANSTRETCHBLT
-
    INT nStretchMode;
-#endif
 
    DECLARE_RETURN(BOOL);
 
@@ -1349,8 +1421,8 @@
 
    if(!cxWidth)
       cxWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
-   if(!cyWidth)
-      cyWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
+   if(!cyHeight)
+      cyHeight = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
 
    DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
 
@@ -1358,13 +1430,13 @@
    {
       RECT r;
       r.right = cxWidth;
-      r.bottom = cyWidth;
+      r.bottom = cyHeight;
 
       hdcOff = NtGdiCreateCompatibleDC(hdc);
       if(!hdcOff)
          goto done;
 
-      hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyWidth);
+      hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight);
       if(!hbmOff)
       {
          NtGdiDeleteDC(hdcOff);
@@ -1383,10 +1455,7 @@
    if(!DoFlickerFree)
       hdcOff = hdc;
 
-#if CANSTRETCHBLT
-
    nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
-#endif
 
    oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
    oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
@@ -1394,28 +1463,19 @@
    if(diFlags & DI_MASK)
    {
       hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
-#if CANSTRETCHBLT
 
-      NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                      cxWidth, cyWidth, hdcMem, 0, 0, IconSize.cx, IconSize.cy,
-                      ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY));
-#else
+      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                   0, 0, IconSize.cx, IconSize.cy,
+                   ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
 
-      NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                  cxWidth, cyWidth, hdcMem, 0, 0, ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY));
-#endif
-
       if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) && (diFlags & DI_IMAGE))
       {
-#if CANSTRETCHBLT
-         NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                         cxWidth, cyWidth, hdcMem, 0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT);
-#else
+         DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                      (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                      0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT,
+                      FALSE);
 
-         NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                     cxWidth, cyWidth, hdcMem, 0, IconSize.cy, SRCINVERT);
-#endif
-
          diFlags &= ~DI_IMAGE;
       }
       NtGdiSelectObject(hdcMem, hOldMem);
@@ -1424,30 +1484,23 @@
    if(diFlags & DI_IMAGE)
    {
       hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
-#if CANSTRETCHBLT
 
-      NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                      cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy),
-                      IconSize.cx, IconSize.cy, ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY));
-#else
+      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                   0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy,
+                   ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
+                   NULL != hbmColor);
 
-      NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
-                  cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy),
-                  ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY));
-#endif
-
       NtGdiSelectObject(hdcMem, hOldMem);
    }
 
    if(DoFlickerFree)
-      NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyWidth, hdcOff, 0, 0, SRCCOPY);
+      NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY);
 
    NtGdiSetTextColor(hdcOff, oldFg);
    NtGdiSetBkColor(hdcOff, oldBg);
-#if CANSTRETCHBLT
 
-   SetStretchBltMode(hdcOff, nStretchMode);
-#endif
+   NtGdiSetStretchBltMode(hdcOff, nStretchMode);
 
    Ret = TRUE;