From 178c0f6d7414618ca8bd41edc43ab7d78dc44947 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 3 Dec 2018 08:51:29 +1100 Subject: [PATCH] Added shell32-IconCache patchset --- patches/patchinstall.sh | 19 +++ ...Generate-icons-from-available-icons-.patch | 117 ++++++++++++++++++ patches/shell32-IconCache/definition | 1 + 3 files changed, 137 insertions(+) create mode 100644 patches/shell32-IconCache/0001-shell32-iconcache-Generate-icons-from-available-icons-.patch create mode 100644 patches/shell32-IconCache/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 42582157..428dbe0b 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -287,6 +287,7 @@ patch_enable_all () enable_shdocvw_ParseURLFromOutsideSource_Tests="$1" enable_shell32_ACE_Viewer="$1" enable_shell32_Context_Menu="$1" + enable_shell32_IconCache="$1" enable_shell32_NewMenu_Interface="$1" enable_shell32_Progress_Dialog="$1" enable_shell32_SFGAO_HASSUBFOLDER="$1" @@ -1018,6 +1019,9 @@ patch_enable () shell32-Context_Menu) enable_shell32_Context_Menu="$2" ;; + shell32-IconCache) + enable_shell32_IconCache="$2" + ;; shell32-NewMenu_Interface) enable_shell32_NewMenu_Interface="$2" ;; @@ -6041,6 +6045,21 @@ if test "$enable_shell32_Context_Menu" -eq 1; then ) >> "$patchlist" fi +# Patchset shell32-IconCache +# | +# | This patchset fixes the following Wine bugs: +# | * [#45696] shell32: Generate icons from available icons if required. +# | +# | Modified files: +# | * dlls/shell32/iconcache.c +# | +if test "$enable_shell32_IconCache" -eq 1; then + patch_apply shell32-IconCache/0001-shell32-iconcache-Generate-icons-from-available-icons-.patch + ( + printf '%s\n' '+ { "Gabriel Ivăncescu", "shell32/iconcache: Generate icons from available icons if some icon sizes failed to load.", 1 },'; + ) >> "$patchlist" +fi + # Patchset shell32-NewMenu_Interface # | # | This patchset fixes the following Wine bugs: diff --git a/patches/shell32-IconCache/0001-shell32-iconcache-Generate-icons-from-available-icons-.patch b/patches/shell32-IconCache/0001-shell32-iconcache-Generate-icons-from-available-icons-.patch new file mode 100644 index 00000000..174caa13 --- /dev/null +++ b/patches/shell32-IconCache/0001-shell32-iconcache-Generate-icons-from-available-icons-.patch @@ -0,0 +1,117 @@ +From e42e76b1a48a1a523f8405c85a2baf9df9e4dabb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= +Date: Fri, 30 Nov 2018 12:20:40 +0200 +Subject: [PATCH] shell32/iconcache: Generate icons from available icons if + some icon sizes failed to load +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For icon sizes that fail to load, create them from another icon that +succeeded by resizing it, favoring icons that are the closest and larger +(to reduce pixelation artefacts) and with the closest aspect ratio as the +source of this operation (to be as generic as possible). For example, if +the icon that needs to be created must be 16x16, an 18x18 icon would get +picked over either a 32x32 (it's further from 16x16) or a 15x15 (icons +larger than 16x16 are favored since they're larger than the result, so +smaller icons are only picked if no other available icon is larger). + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45696 +Signed-off-by: Gabriel Ivăncescu +--- + dlls/shell32/iconcache.c | 67 +++++++++++++++++++++++++++++++++------- + 1 file changed, 56 insertions(+), 11 deletions(-) + +diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c +index 44422ab..5ffb293 100644 +--- a/dlls/shell32/iconcache.c ++++ b/dlls/shell32/iconcache.c +@@ -345,13 +345,6 @@ static INT SIC_IconAppend (const WCHAR *sourcefile, INT src_index, HICON *hicons + return ret; + } + +-static BOOL get_imagelist_icon_size(int list, SIZE *size) +-{ +- if (list < 0 || list >= ARRAY_SIZE(shell_imagelists)) return FALSE; +- +- return ImageList_GetIconSize( shell_imagelists[list], &size->cx, &size->cy ); +-} +- + /**************************************************************************** + * SIC_LoadIcon [internal] + * +@@ -362,15 +355,67 @@ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags) + { + HICON hicons[ARRAY_SIZE(shell_imagelists)] = { 0 }; + HICON hshortcuts[ARRAY_SIZE(hicons)] = { 0 }; ++ SIZE size[ARRAY_SIZE(shell_imagelists)]; + unsigned int i; +- SIZE size; + INT ret = -1; + ++ /* Keep track of the sizes in case any icon fails to get extracted */ ++ for (i = 0; i < ARRAY_SIZE(hicons); i++) ++ { ++ ImageList_GetIconSize(shell_imagelists[i], &size[i].cx, &size[i].cy); ++ PrivateExtractIconsW(sourcefile, index, size[i].cx, size[i].cy, &hicons[i], 0, 1, 0); ++ } ++ ++ /* Fill any icon handles that failed to get extracted, by resizing ++ another icon handle that succeeded and creating the icon from it. ++ Use a dumb O(n^2) algorithm since ARRAY_SIZE(hicons) is small */ + for (i = 0; i < ARRAY_SIZE(hicons); i++) + { +- get_imagelist_icon_size( i, &size ); +- if (!PrivateExtractIconsW( sourcefile, index, size.cx, size.cy, &hicons[i], 0, 1, 0 )) +- WARN("Failed to load icon %d from %s.\n", index, debugstr_w(sourcefile)); ++ unsigned int k, ix, iy; ++ BOOL failed = TRUE; ++ if (hicons[i]) continue; ++ ++ for (k = 0; k < ARRAY_SIZE(hicons); k++) ++ { ++ if (hicons[k]) ++ { ++ ix = iy = k; ++ failed = FALSE; ++ break; ++ } ++ } ++ if (failed) goto fail; ++ ++ for (k++; k < ARRAY_SIZE(hicons); k++) ++ { ++ if (!hicons[k]) continue; ++ ++ /* Find closest-sized icon, but favor larger icons to resize from */ ++ if (size[k].cx >= size[i].cx) ++ ix = (size[ix].cx < size[i].cx || size[ix].cx > size[k].cx) ? k : ix; ++ else ++ ix = (size[ix].cx < size[i].cx && size[ix].cx < size[k].cx) ? k : ix; ++ ++ if (size[k].cy >= size[i].cy) ++ iy = (size[iy].cy < size[i].cy || size[iy].cy > size[k].cy) ? k : iy; ++ else ++ iy = (size[iy].cy < size[i].cy && size[iy].cy < size[k].cy) ? k : iy; ++ } ++ ++ /* Use the closest icon in aspect ratio if ix and iy differ */ ++ if (ix != iy) ++ { ++ float i_ratio, ix_ratio, iy_ratio; ++ i_ratio = (float)size[i].cx / (float)size[i].cy; ++ ix_ratio = (float)size[ix].cx / (float)size[ix].cy; ++ iy_ratio = (float)size[iy].cx / (float)size[iy].cy; ++ if (fabsf(ix_ratio - i_ratio) > fabsf(iy_ratio - i_ratio)) ++ ix = iy; ++ } ++ ++ /* If this fails, we have to abort to prevent the image lists from ++ becoming out of sync and completely screwing the icons up */ ++ hicons[i] = CopyImage(hicons[ix], IMAGE_ICON, size[i].cx, size[i].cy, 0); + if (!hicons[i]) goto fail; + } + +-- +2.19.1 + diff --git a/patches/shell32-IconCache/definition b/patches/shell32-IconCache/definition new file mode 100644 index 00000000..3a015e80 --- /dev/null +++ b/patches/shell32-IconCache/definition @@ -0,0 +1 @@ +Fixes: [45696] shell32: Generate icons from available icons if required.