< prev index next >

src/windows/native/sun/windows/ShellFolder2.cpp

Print this page

        

@@ -910,23 +910,47 @@
 }
 
 /*
  * Class:     sun_awt_shell_Win32ShellFolder2
  * Method:    getIconBits
- * Signature: (JI)[I
+ * Signature: (J)[I
  */
 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
-    (JNIEnv* env, jclass cls, jlong hicon, jint iconSize)
+    (JNIEnv* env, jclass cls, jlong hicon)
 {
+    const int MAX_ICON_SIZE = 128;
+    int iconSize = 0;
     jintArray iconBits = NULL;
 
+    BITMAP bmp;
+    memset(&bmp, 0, sizeof(BITMAP));
+
     // Get the icon info
     ICONINFO iconInfo;
     if (fn_GetIconInfo((HICON)hicon, &iconInfo)) {
         // Get the screen DC
         HDC dc = GetDC(NULL);
         if (dc != NULL) {
+            // find out the icon size in order to deal with different sizes
+            // delivered depending on HiDPI mode or SD DPI mode.
+            if (iconInfo.hbmColor) {
+                const int nWrittenBytes = GetObject(iconInfo.hbmColor, sizeof(bmp), &bmp);
+                if(nWrittenBytes > 0) {
+                    iconSize = bmp.bmWidth;
+                }
+            } else if (iconInfo.hbmMask) {
+                // Icon has no color plane, image data stored in mask
+                const int nWrittenBytes = GetObject(iconInfo.hbmMask, sizeof(bmp), &bmp);
+                if (nWrittenBytes > 0) {
+                    iconSize = bmp.bmWidth;
+                }
+            }
+            // limit iconSize to MAX_ICON_SIZE, so that the colorBits and maskBits
+            // arrays are big enough.
+            // (logic: rather show bad icons than overrun the array size)
+            iconSize = iconSize > MAX_ICON_SIZE ? MAX_ICON_SIZE : iconSize;
+
             // Set up BITMAPINFO
             BITMAPINFO bmi;
             memset(&bmi, 0, sizeof(BITMAPINFO));
             bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
             bmi.bmiHeader.biWidth = iconSize;

@@ -934,11 +958,11 @@
             bmi.bmiHeader.biPlanes = 1;
             bmi.bmiHeader.biBitCount = 32;
             bmi.bmiHeader.biCompression = BI_RGB;
             // Extract the color bitmap
             int nBits = iconSize * iconSize;
-            long colorBits[1024];
+            long colorBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
             GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS);
             // XP supports alpha in some icons, and depending on device.
             // This should take precedence over the icon mask bits.
             BOOL hasAlpha = FALSE;
             if (IS_WINXP) {

@@ -949,11 +973,11 @@
                     }
                 }
             }
             if (!hasAlpha) {
                 // Extract the mask bitmap
-                long maskBits[1024];
+                long maskBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
                 GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS);
                 // Copy the mask alphas into the color bits
                 for (int i = 0; i < nBits; i++) {
                     if (maskBits[i] == 0) {
                         colorBits[i] |= 0xff000000;

@@ -1002,11 +1026,11 @@
 
         if (hImageList != NULL) {
             HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
 
             if (hIcon != NULL) {
-                result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16);
+                result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon));
 
                 DestroyIcon(hIcon);
             }
 
             ImageList_Destroy(hImageList);
< prev index next >