Author: gadamopoulos
Date: Sun Feb 22 20:59:08 2015
New Revision: 66418
URL:
http://svn.reactos.org/svn/reactos?rev=66418&view=rev
Log:
[COMCTL32]
- Implement ILS_SATURATE in our image list implementation
- Use ILS_SATURATE when showing icons of disabled buttons in the toolbar
Patch Ismael Ferreras Morezuelas aka swyter
CORE-8916
Modified:
trunk/reactos/dll/win32/comctl32/imagelist.c
trunk/reactos/dll/win32/comctl32/toolbar.c
trunk/reactos/include/psdk/wingdi.h
Modified: trunk/reactos/dll/win32/comctl32/imagelist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/comctl32/imageli…
==============================================================================
--- trunk/reactos/dll/win32/comctl32/imagelist.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/comctl32/imagelist.c [iso-8859-1] Sun Feb 22 20:59:08 2015
@@ -33,7 +33,7 @@
*
* TODO:
* - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE
- * - Add support for ILS_GLOW, ILS_SHADOW, ILS_SATURATE
+ * - Add support for ILS_GLOW, ILS_SHADOW
* - Thread-safe locking
*/
@@ -1227,7 +1227,7 @@
}
-static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
+static BOOL alpha_blend_image( HIMAGELIST himl, HDC srce_dc, HDC dest_dc, int dest_x, int
dest_y,
int src_x, int src_y, int cx, int cy, BLENDFUNCTION func,
UINT style, COLORREF blend_col )
{
@@ -1252,9 +1252,9 @@
info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrUsed = 0;
info->bmiHeader.biClrImportant = 0;
- if (!(bmp = CreateDIBSection( himl->hdcImage, info, DIB_RGB_COLORS, &bits, 0,
0 ))) goto done;
+ if (!(bmp = CreateDIBSection( srce_dc, info, DIB_RGB_COLORS, &bits, 0, 0 ))) goto
done;
SelectObject( hdc, bmp );
- BitBlt( hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY );
+ BitBlt( hdc, 0, 0, cx, cy, srce_dc, src_x, src_y, SRCCOPY );
if (blend_col != CLR_NONE)
{
@@ -1327,6 +1327,66 @@
return ret;
}
+HDC saturate_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
+ int src_x, int src_y, int cx, int cy, COLORREF rgbFg)
+{
+ HDC hdc = NULL;
+ HBITMAP bmp = 0;
+ BITMAPINFO *info;
+
+ unsigned int *ptr;
+ void *bits;
+ int i;
+
+ /* create a dc and its device independent bitmap for doing the work,
+ shamelessly copied from the alpha-blending function above */
+ if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE;
+ if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256]
)))) goto done;
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biWidth = cx;
+ info->bmiHeader.biHeight = cy;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = 32;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = cx * cy * 4;
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+ if (!(bmp = CreateDIBSection(himl->hdcImage, info, DIB_RGB_COLORS, &bits, 0, 0
))) goto done;
+
+ /* bind both surfaces */
+ SelectObject(hdc, bmp);
+
+ /* copy into our dc the section that covers just the icon we we're asked for */
+ BitBlt(hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY);
+
+ /* loop every pixel of the bitmap */
+ for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
+ {
+ COLORREF orig_color = *ptr;
+
+ /* calculate the effective luminance using the constants from here, adapted to
the human eye:
+ <http://bobpowell.net/grayscale.aspx> */
+ float mixed_color = (GetRValue(orig_color) * .30 +
+ GetGValue(orig_color) * .59 +
+ GetBValue(orig_color) * .11);
+
+ *ptr = RGBA(mixed_color, mixed_color, mixed_color, GetAValue(orig_color));
+ }
+
+done:
+
+ if (bmp)
+ DeleteObject(bmp);
+
+ if (info)
+ HeapFree(GetProcessHeap(), 0, info);
+
+ /* return the handle to our desaturated dc, that will substitute its original
counterpart in the next calls */
+ return hdc;
+}
+
/*************************************************************************
* ImageList_DrawIndirect [COMCTL32.@]
*
@@ -1403,6 +1463,21 @@
oldImageFg = SetTextColor( hImageDC, RGB( 0, 0, 0 ) );
oldImageBk = SetBkColor( hImageDC, RGB( 0xff, 0xff, 0xff ) );
+ /*
+ * If the ILS_SATURATE bit is enabled we should multiply the
+ * RGB colors of the original image by the contents of rgbFg.
+ */
+ if (fState & ILS_SATURATE)
+ {
+ hImageListDC = saturate_image(himl, pimldp->hdcDst, pimldp->x,
pimldp->y,
+ pt.x, pt.y, cx, cy, pimldp->rgbFg);
+
+ /* shitty way of getting subroutines to blit at the right place (top left
corner),
+ as our modified imagelist only contains a single image for performance reasons
*/
+ pt.x = 0;
+ pt.y = 0;
+ }
+
has_alpha = (himl->has_alpha && himl->has_alpha[pimldp->i]);
if (!bMask && (has_alpha || (fState & ILS_ALPHA)))
{
@@ -1423,7 +1498,7 @@
if (bIsTransparent)
{
- bResult = alpha_blend_image( himl, pimldp->hdcDst, pimldp->x,
pimldp->y,
+ bResult = alpha_blend_image( himl, hImageListDC, pimldp->hdcDst,
pimldp->x, pimldp->y,
pt.x, pt.y, cx, cy, func, fStyle, blend_col );
goto end;
}
@@ -1433,7 +1508,7 @@
hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
- alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func, fStyle,
blend_col );
+ alpha_blend_image( himl, hImageListDC, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func,
fStyle, blend_col );
DeleteObject (SelectObject (hImageDC, hOldBrush));
bResult = BitBlt( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
hImageDC, 0, 0, SRCCOPY );
goto end;
@@ -1527,7 +1602,6 @@
}
}
- if (fState & ILS_SATURATE) FIXME("ILS_SATURATE: unimplemented!\n");
if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n");
if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n");
Modified: trunk/reactos/dll/win32/comctl32/toolbar.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/comctl32/toolbar…
==============================================================================
--- trunk/reactos/dll/win32/comctl32/toolbar.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/comctl32/toolbar.c [iso-8859-1] Sun Feb 22 20:59:08 2015
@@ -696,10 +696,12 @@
const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag)
{
HIMAGELIST himl = NULL;
- BOOL draw_masked = FALSE;
+ BOOL draw_masked = FALSE, draw_desaturated = FALSE;
INT index;
INT offset = 0;
UINT draw_flags = ILD_TRANSPARENT;
+ IMAGEINFO info = {0};
+ BITMAP bm = {0};
if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
{
@@ -707,7 +709,18 @@
if (!himl)
{
himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT,
&index);
- draw_masked = TRUE;
+
+ ImageList_GetImageInfo(himl, index, &info);
+ GetObjectW(info.hbmImage, sizeof(bm), &bm);
+
+ if (bm.bmBitsPixel == 32)
+ {
+ draw_desaturated = TRUE;
+ }
+ else
+ {
+ draw_masked = TRUE;
+ }
}
}
else if (tbcd->nmcd.uItemState & CDIS_CHECKED ||
@@ -738,9 +751,34 @@
index, himl, left, top, offset);
if (draw_masked)
+ {
+ /* code path for drawing flat disabled icons without alpha channel */
TOOLBAR_DrawMasked (himl, index, tbcd->nmcd.hdc, left + offset, top + offset,
draw_flags);
+ }
+ else if (draw_desaturated)
+ {
+ /* code path for drawing disabled, alpha-blended (32bpp) icons */
+ IMAGELISTDRAWPARAMS imldp = {0};
+
+ imldp.cbSize = sizeof(imldp);
+ imldp.himl = himl;
+ imldp.i = index;
+ imldp.hdcDst = tbcd->nmcd.hdc,
+ imldp.x = offset + left;
+ imldp.y = offset + top;
+ imldp.rgbBk = CLR_NONE;
+ imldp.rgbFg = CLR_DEFAULT;
+ imldp.fStyle = ILD_TRANSPARENT;
+ imldp.fState = ILS_ALPHA | ILS_SATURATE;
+ imldp.Frame = 192;
+
+ ImageList_DrawIndirect (&imldp);
+ }
else
+ {
+ /* code path for drawing standard icons as-is */
ImageList_Draw (himl, index, tbcd->nmcd.hdc, left + offset, top + offset,
draw_flags);
+ }
}
/* draws a blank frame for a toolbar button */
Modified: trunk/reactos/include/psdk/wingdi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/wingdi.h?rev=…
==============================================================================
--- trunk/reactos/include/psdk/wingdi.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/wingdi.h [iso-8859-1] Sun Feb 22 20:59:08 2015
@@ -2902,8 +2902,10 @@
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
+#define GetAValue(rgb) ((BYTE)((rgb)>>24))
#define RGB(r,g,b)
((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+#define RGBA(r,g,b,a) ((COLORREF)((((DWORD)(BYTE)(a))<<24) | RGB(r,g,b)))
#define PALETTERGB(r,g,b) (0x02000000 | RGB(r,g,b))
#define PALETTEINDEX(i) ((COLORREF)(0x01000000 | (DWORD)(WORD)(i)))