Jacek Caban : user32: Factor out create_icon_frame.

Alexandre Julliard julliard at winehq.org
Tue Feb 22 16:06:51 CST 2022


Module: wine
Branch: master
Commit: 8ce4c07f507984bd948d2f525c5a3825824e4eab
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8ce4c07f507984bd948d2f525c5a3825824e4eab

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb 22 13:41:01 2022 +0100

user32: Factor out create_icon_frame.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
 }
 
 




More information about the wine-cvs mailing list