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