mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[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 svn path=/trunk/; revision=66418
This commit is contained in:
parent
1990bd1af2
commit
8370f15813
3 changed files with 123 additions and 9 deletions
|
@ -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 @@ ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y,
|
|||
}
|
||||
|
||||
|
||||
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 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
|
|||
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 @@ done:
|
|||
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 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
|
|||
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 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
|
|||
|
||||
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 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
|
|||
|
||||
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 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
|
|||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
|
|
|
@ -696,10 +696,12 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
|
|||
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 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
|
|||
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 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
|
|||
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 */
|
||||
|
|
|
@ -2902,8 +2902,10 @@ typedef DWORD (CALLBACK *LPFNDEVCAPS)(LPSTR,LPSTR,UINT,LPSTR,LPDEVMODEA);
|
|||
#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)))
|
||||
|
||||
|
|
Loading…
Reference in a new issue