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);