Module: wine Branch: master Commit: 8ce4c07f507984bd948d2f525c5a3825824e4eab URL: https://source.winehq.org/git/wine.git/?a=commit;h=8ce4c07f507984bd948d2f525...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Feb 22 13:41:01 2022 +0100
user32: Factor out create_icon_frame.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/cursoricon.c | 134 ++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 70 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index d2739278f21..b629e1412ae 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -173,6 +173,13 @@ static UINT get_icon_steps( struct cursoricon_object *obj ) return obj->is_ani ? obj->ani.num_steps : 1; }
+static void free_icon_frame( struct cursoricon_frame *frame ) +{ + if (frame->color) DeleteObject( frame->color ); + if (frame->alpha) DeleteObject( frame->alpha ); + if (frame->mask) DeleteObject( frame->mask ); +} + static BOOL free_icon_handle( HICON handle ) { struct cursoricon_object *obj = free_user_handle( handle, NTUSER_OBJ_ICON ); @@ -187,12 +194,7 @@ static BOOL free_icon_handle( HICON handle )
if (!obj->is_ani) { - struct cursoricon_frame *frame = get_icon_frame( obj, 0 ); - - if (frame->alpha) DeleteObject( frame->alpha ); - if (frame->color) DeleteObject( frame->color ); - DeleteObject( frame->mask ); - release_icon_frame( obj, frame ); + free_icon_frame( &obj->frame ); } else { @@ -984,54 +986,42 @@ done: return alpha; }
- -/*********************************************************************** - * create_icon_from_bmi - * - * Create an icon from its BITMAPINFO. - */ -static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE module, LPCWSTR resname, - HRSRC rsrc, POINT hotspot, BOOL bIcon, INT width, INT height, - UINT cFlag ) +static BOOL create_icon_frame( const BITMAPINFO *bmi, DWORD maxsize, POINT hotspot, BOOL is_icon, + INT width, INT height, UINT flags, struct cursoricon_frame *frame ) { - DWORD size, color_size, mask_size; - HBITMAP color = 0, mask = 0, alpha = 0; + DWORD size, color_size, mask_size, compr; const void *color_bits, *mask_bits; void *alpha_mask_bits = NULL; + LONG bmi_width, bmi_height; BITMAPINFO *bmi_copy; - BOOL ret = FALSE; BOOL do_stretch; - HICON hObj = 0; HDC hdc = 0; - LONG bmi_width, bmi_height; WORD bpp; - DWORD compr; + BOOL ret = FALSE; + + memset( frame, 0, sizeof(*frame) );
/* Check bitmap header */
if (bmi->bmiHeader.biSize == PNG_SIGN) { - BITMAPINFO *bmi_png = load_png( (const char *)bmi, &maxsize ); + BITMAPINFO *bmi_png;
- if (bmi_png) - { - hObj = create_icon_from_bmi( bmi_png, maxsize, module, resname, - rsrc, hotspot, bIcon, width, height, cFlag ); - HeapFree( GetProcessHeap(), 0, bmi_png ); - return hObj; - } - return 0; + if (!(bmi_png = load_png( (const char *)bmi, &maxsize ))) return FALSE; + ret = create_icon_frame( bmi_png, maxsize, hotspot, is_icon, width, height, flags, frame ); + HeapFree( GetProcessHeap(), 0, bmi_png ); + return ret; }
if (maxsize < sizeof(BITMAPCOREHEADER)) { WARN( "invalid size %u\n", maxsize ); - return 0; + return FALSE; } if (maxsize < bmi->bmiHeader.biSize) { WARN( "invalid header size %u\n", bmi->bmiHeader.biSize ); - return 0; + return FALSE; } if ( (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) && (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) || @@ -1039,7 +1029,7 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE bmi->bmiHeader.biCompression != BI_BITFIELDS)) ) { WARN( "invalid bitmap header %u\n", bmi->bmiHeader.biSize ); - return 0; + return FALSE; }
size = bitmap_info_size( bmi, DIB_RGB_COLORS ); @@ -1054,21 +1044,20 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE } if (mask_size > maxsize - size - color_size) mask_size = 0; /* no mask */
- if (cFlag & LR_DEFAULTSIZE) + if (flags & LR_DEFAULTSIZE) { - if (!width) width = GetSystemMetrics( bIcon ? SM_CXICON : SM_CXCURSOR ); - if (!height) height = GetSystemMetrics( bIcon ? SM_CYICON : SM_CYCURSOR ); + if (!width) width = GetSystemMetrics( is_icon ? SM_CXICON : SM_CXCURSOR ); + if (!height) height = GetSystemMetrics( is_icon ? SM_CYICON : SM_CYCURSOR ); } else { if (!width) width = bmi_width; if (!height) height = bmi_height/2; } - do_stretch = (bmi_height/2 != height) || - (bmi_width != width); + do_stretch = (bmi_height/2 != height) || (bmi_width != width);
/* Scale the hotspot */ - if (bIcon) + if (is_icon) { hotspot.x = width / 2; hotspot.y = height / 2; @@ -1093,34 +1082,28 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE color_bits = (const char*)bmi + size; mask_bits = (const char*)color_bits + color_size;
- alpha = 0; if (is_dib_monochrome( bmi )) { - if (!(mask = CreateBitmap( width, height * 2, 1, 1, NULL ))) goto done; - color = 0; + if (!(frame->mask = CreateBitmap( width, height * 2, 1, 1, NULL ))) goto done;
/* copy color data into second half of mask bitmap */ - SelectObject( hdc, mask ); + SelectObject( hdc, frame->mask ); StretchDIBits( hdc, 0, height, width, height, 0, 0, bmi_width, bmi_height, color_bits, bmi_copy, DIB_RGB_COLORS, SRCCOPY ); } else { - if (!(mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done; - if (!(color = create_color_bitmap( width, height ))) - { - DeleteObject( mask ); - goto done; - } - SelectObject( hdc, color ); + if (!(frame->mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done; + if (!(frame->color = create_color_bitmap( width, height ))) goto done; + SelectObject( hdc, frame->color ); StretchDIBits( hdc, 0, 0, width, height, 0, 0, bmi_width, bmi_height, color_bits, bmi_copy, DIB_RGB_COLORS, SRCCOPY );
if (bmi_has_alpha( bmi_copy, color_bits )) { - alpha = create_alpha_bitmap( color, bmi_copy, color_bits ); + frame->alpha = create_alpha_bitmap( frame->color, bmi_copy, color_bits ); if (!mask_size) /* generate mask from alpha */ { LONG x, y, dst_stride = ((bmi_width + 31) / 8) & ~3; @@ -1164,35 +1147,48 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE
if (mask_size) { - SelectObject( hdc, mask ); + SelectObject( hdc, frame->mask ); StretchDIBits( hdc, 0, 0, width, height, 0, 0, bmi_width, bmi_height, mask_bits, bmi_copy, DIB_RGB_COLORS, SRCCOPY ); } + + frame->delay = ~0; + frame->width = width; + frame->height = height; + frame->hotspot = hotspot; ret = TRUE;
done: + if (!ret) free_icon_frame( frame ); DeleteDC( hdc ); HeapFree( GetProcessHeap(), 0, bmi_copy ); HeapFree( GetProcessHeap(), 0, alpha_mask_bits ); + return ret; +} + +/*********************************************************************** + * create_icon_from_bmi + * + * Create an icon from its BITMAPINFO. + */ +static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE module, LPCWSTR resname, + HRSRC rsrc, POINT hotspot, BOOL bIcon, INT width, INT height, + UINT flags ) +{ + struct cursoricon_frame frame; + HICON ret;
+ if (!create_icon_frame( bmi, maxsize, hotspot, bIcon, width, height, flags, &frame )) return 0; + + ret = alloc_icon_handle( FALSE, 0 ); if (ret) - hObj = alloc_icon_handle( FALSE, 0 ); - if (hObj) { - struct cursoricon_object *info = get_icon_ptr( hObj ); - struct cursoricon_frame *frame; + struct cursoricon_object *info = get_icon_ptr( ret );
info->is_icon = bIcon; - frame = get_icon_frame( info, 0 ); - frame->delay = ~0; - frame->width = width; - frame->height = height; - frame->color = color; - frame->mask = mask; - frame->alpha = alpha; - frame->hotspot = hotspot; - release_icon_frame( info, frame ); + info->frame = frame; + if (!IS_INTRESOURCE(resname)) { info->resname = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(resname) + 1) * sizeof(WCHAR) ); @@ -1213,7 +1209,7 @@ done: } }
- if (cFlag & LR_SHARED) + if (flags & LR_SHARED) { info->is_shared = TRUE; if (module) @@ -1226,11 +1222,9 @@ done: } else { - DeleteObject( color ); - DeleteObject( alpha ); - DeleteObject( mask ); + free_icon_frame( &frame ); } - return hObj; + return ret; }