https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e31031f603f54cf1751f0501d9aaab1e50b02c01

commit e31031f603f54cf1751f0501d9aaab1e50b02c01
Author:     Ethan Rodensky <splitwi...@gmail.com>
AuthorDate: Sun Aug 6 18:14:51 2023 -0400
Commit:     Stanislav Motylkov <x86co...@gmail.com>
CommitDate: Thu Aug 31 20:42:03 2023 +0300

    [UXTHEME] Allow PNG images in visual styles (#5540)
    
    This is prerequisite to supporting Vista+ iteration of the msstyles format,
    and also for implementing GetThemeStream() later.
    
    Visual styles compiled for Vista+ can now use PNG images in the IMAGE group.
    This does not affect the ability to use BMP images, they can be mixed now.
---
 dll/win32/uxtheme/CMakeLists.txt | 13 +++++-
 dll/win32/uxtheme/msstyles.c     | 11 +++++
 dll/win32/uxtheme/pngsup.cpp     | 94 ++++++++++++++++++++++++++++++++++++++++
 dll/win32/uxtheme/uxthemep.h     | 14 ++++++
 4 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/dll/win32/uxtheme/CMakeLists.txt b/dll/win32/uxtheme/CMakeLists.txt
index 37fefc5b7fa..3124014046b 100644
--- a/dll/win32/uxtheme/CMakeLists.txt
+++ b/dll/win32/uxtheme/CMakeLists.txt
@@ -19,6 +19,13 @@ list(APPEND SOURCE
     uxthemep.h
     ${CMAKE_CURRENT_BINARY_DIR}/uxtheme_stubs.c)
 
+if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600)
+    add_definitions(-DENABLE_PNG_SUPPORT)
+
+    list(APPEND SOURCE
+        pngsup.cpp)
+endif()
+
 add_library(uxtheme MODULE
     ${SOURCE}
     version.rc
@@ -27,6 +34,10 @@ add_library(uxtheme MODULE
 set_module_type(uxtheme win32dll)
 target_link_libraries(uxtheme wine)
 add_delay_importlibs(uxtheme msimg32)
-add_importlibs(uxtheme user32 advapi32 gdi32 msvcrt kernel32 ntdll)
+if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600)
+    add_importlibs(uxtheme user32 advapi32 gdiplus gdi32 shlwapi msvcrt 
kernel32 ntdll)
+else()
+    add_importlibs(uxtheme user32 advapi32 gdi32 msvcrt kernel32 ntdll)
+endif()
 add_pch(uxtheme uxthemep.h SOURCE)
 add_cd_file(TARGET uxtheme DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/uxtheme/msstyles.c b/dll/win32/uxtheme/msstyles.c
index 866d96effd0..1507d3dd405 100644
--- a/dll/win32/uxtheme/msstyles.c
+++ b/dll/win32/uxtheme/msstyles.c
@@ -920,8 +920,19 @@ HBITMAP MSSTYLES_LoadBitmap (PTHEME_CLASS tc, LPCWSTR 
lpFilename, BOOL* hasAlpha
     }
     /* Not found? Load from resources */
     img = HeapAlloc (GetProcessHeap(), 0, sizeof (THEME_IMAGE));
+#ifdef ENABLE_PNG_SUPPORT
+    if (MSSTYLES_TryLoadPng(tc->hTheme, szFile, TEXT(L"IMAGE"), &img->image)) 
// ...as PNG...
+    {
+        prepare_png_alpha(img->image, hasAlpha);
+    }
+    else // ...or, failing that, as BMP
+    {
+#endif /* ENABLE_PNG_SUPPORT */
     img->image = LoadImageW(tc->hTheme, szFile, IMAGE_BITMAP, 0, 0, 
LR_CREATEDIBSECTION);
     prepare_alpha (img->image, hasAlpha);
+#ifdef ENABLE_PNG_SUPPORT
+    }
+#endif /* ENABLE_PNG_SUPPORT */
     img->hasAlpha = *hasAlpha;
     /* ...and stow away for later reuse. */
     lstrcpyW (img->name, szFile);
diff --git a/dll/win32/uxtheme/pngsup.cpp b/dll/win32/uxtheme/pngsup.cpp
new file mode 100644
index 00000000000..25f53abdae7
--- /dev/null
+++ b/dll/win32/uxtheme/pngsup.cpp
@@ -0,0 +1,94 @@
+/*
+ * PROJECT:     ReactOS uxtheme.dll
+ * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE:     Support for PNG images in visual styles
+ * COPYRIGHT:   Copyright 2023 Ethan Rodensky <splitwi...@gmail.com>
+ */
+
+#include "uxthemep.h"
+
+#include <ole2.h>
+#include <objidl.h>
+#include <gdiplus.h>
+#include <gdipluscolor.h>
+#include <winreg.h>
+#include <shlwapi.h>
+
+BOOL
+MSSTYLES_TryLoadPng(
+    _In_ HINSTANCE hTheme,
+    _In_ LPCWSTR szFile,
+    _In_ LPCWSTR type,
+    _Out_ HBITMAP *phBitmap)
+{
+    BOOL ret = FALSE;
+
+    HRSRC hRes = FindResourceW(hTheme, szFile, type);
+    if (!hRes)
+        return FALSE;
+
+    HGLOBAL hAlloc = LoadResource(hTheme, hRes);
+    if (!hAlloc)
+        return FALSE;
+
+    DWORD dwSize = SizeofResource(hTheme, hRes);
+    LPVOID pData = LockResource(hAlloc);
+    if ((!pData) || (dwSize <= 0))
+    {
+        FreeResource(hAlloc);
+        return FALSE;
+    }
+
+    IStream* stream = SHCreateMemStream((BYTE*)pData, dwSize);
+    if (stream)
+    {
+        Gdiplus::Bitmap* gdipBitmap = Gdiplus::Bitmap::FromStream(stream, 
FALSE);
+        stream->Release();
+        if (gdipBitmap)
+        {
+            ret = gdipBitmap->GetHBITMAP(Gdiplus::Color(0, 0, 0, 0), phBitmap) 
== Gdiplus::Ok;
+            delete gdipBitmap;
+        }
+    }
+
+    UnlockResource(pData);
+    FreeResource(hAlloc);
+    return ret;
+}
+
+BOOL
+prepare_png_alpha(
+    _In_ HBITMAP png,
+    _Out_ BOOL* hasAlpha)
+{
+    DIBSECTION dib;
+    int n;
+    BYTE* p;
+
+    *hasAlpha = FALSE;
+
+    if (!png || GetObjectW( png, sizeof(dib), &dib ) != sizeof(dib))
+        return FALSE;
+
+    if (dib.dsBm.bmBitsPixel != 32)
+        /* nothing to do */
+        return TRUE;
+
+    p = (BYTE*)dib.dsBm.bmBits;
+    n = dib.dsBmih.biHeight * dib.dsBmih.biWidth;
+    while (n-- > 0)
+    {
+        int a = p[3] + 1;
+        if (a < 256)
+        {
+            p[0] = MulDiv(p[0], 256, a);
+            p[1] = MulDiv(p[1], 256, a);
+            p[2] = MulDiv(p[2], 256, a);
+
+            *hasAlpha = TRUE;
+        }
+        p += 4;
+    }
+
+    return TRUE;
+}
diff --git a/dll/win32/uxtheme/uxthemep.h b/dll/win32/uxtheme/uxthemep.h
index b721510ca32..af1ffd31a3d 100644
--- a/dll/win32/uxtheme/uxthemep.h
+++ b/dll/win32/uxtheme/uxthemep.h
@@ -115,6 +115,20 @@ PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf);
 PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int 
iStateId, PTHEME_CLASS *tcNext);
 PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int 
iStateId, int iPropertyPrimitive, int iPropertyId);
 PTHEME_PROPERTY MSSTYLES_FindMetric(PTHEME_FILE tf, int iPropertyPrimitive, 
int iPropertyId);
+#ifdef ENABLE_PNG_SUPPORT
+EXTERN_C
+BOOL
+MSSTYLES_TryLoadPng(
+    _In_ HINSTANCE hTheme,
+    _In_ LPCWSTR szFile,
+    _In_ LPCWSTR type,
+    _Out_ HBITMAP *phBitmap);
+EXTERN_C
+BOOL
+prepare_png_alpha(
+    _In_ HBITMAP png,
+    _Out_ BOOL* hasAlpha);
+#endif /* ENABLE_PNG_SUPPORT */
 HBITMAP MSSTYLES_LoadBitmap(PTHEME_CLASS tc, LPCWSTR lpFilename, BOOL* 
hasAlpha);
 
 HRESULT MSSTYLES_GetPropertyBool(PTHEME_PROPERTY tp, BOOL *pfVal);

Reply via email to