7148275: [macosx] setIconImages() not working correctly (distorted icon when minimized)
authoranthony
Fri, 06 Apr 2012 17:20:49 +0400
changeset 12403 50b3f2982b59
parent 12402 f3903de3fd9e
child 12404 de0c1d3ed1c5
7148275: [macosx] setIconImages() not working correctly (distorted icon when minimized) Summary: Pass all images provided by user code to the system and let it do the right thing Reviewed-by: art, swingler
jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/awt/CImage.m
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java	Fri Apr 06 17:15:09 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java	Fri Apr 06 17:20:49 2012 +0400
@@ -29,10 +29,14 @@
 import java.awt.geom.Dimension2D;
 import java.awt.image.*;
 
+import java.util.Arrays;
+import java.util.List;
+
 import sun.awt.image.SunWritableRaster;
 
 public class CImage extends CFRetainedResource {
     private static native long nativeCreateNSImageFromArray(int[] buffer, int w, int h);
+    private static native long nativeCreateNSImageFromArrays(int[][] buffers, int w[], int h[]);
     private static native long nativeCreateNSImageFromFileContents(String file);
     private static native long nativeCreateNSImageOfFileFromLaunchServices(String file);
     private static native long nativeCreateNSImageFromImageName(String name);
@@ -93,8 +97,7 @@
             return createImageUsingNativeSize(nativeCreateNSImageFromImageName(name));
         }
 
-        // This is used to create a CImage from a Image
-        public CImage createFromImage(final Image image) {
+        private static int[] imageToArray(Image image) {
             if (image == null) return null;
 
             MediaTracker mt = new MediaTracker(new Label());
@@ -117,8 +120,50 @@
             g2.setComposite(AlphaComposite.Src);
             g2.drawImage(image, 0, 0, null);
             g2.dispose();
-            int[] buffer = ((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
-            return new CImage(nativeCreateNSImageFromArray(buffer, w, h));
+            return ((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
+        }
+
+        // This is used to create a CImage from a Image
+        public CImage createFromImage(final Image image) {
+            int[] buffer = imageToArray(image);
+            if (buffer == null) {
+                return null;
+            }
+            return new CImage(nativeCreateNSImageFromArray(buffer, image.getWidth(null), image.getHeight(null)));
+        }
+
+        public CImage createFromImages(List<Image> images) {
+            if (images == null || images.isEmpty()) {
+                return null;
+            }
+
+            int num = images.size();
+
+            int[][] buffers = new int[num][];
+            int[] w = new int[num];
+            int[] h = new int[num];
+
+            num = 0;
+
+            for (Image img : images) {
+                buffers[num] = imageToArray(img);
+                if (buffers[num] == null) {
+                    // Unable to process the image
+                    continue;
+                }
+                w[num] = img.getWidth(null);
+                h[num] = img.getHeight(null);
+                num++;
+            }
+
+            if (num == 0) {
+                return null;
+            }
+
+            return new CImage(nativeCreateNSImageFromArrays(
+                        Arrays.copyOf(buffers, num),
+                        Arrays.copyOf(w, num),
+                        Arrays.copyOf(h, num)));
         }
 
         static int getSelectorAsInt(final String fromString) {
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 06 17:15:09 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 06 17:20:49 2012 +0400
@@ -810,11 +810,7 @@
         if (icons == null || icons.size() == 0) {
             return null;
         }
-
-        // TODO: need a walk-through to find the best image.
-        // The best mean with higher resolution. Otherwise an icon looks bad.
-        final Image image = icons.get(0);
-        return CImage.getCreator().createFromImage(image);
+        return CImage.getCreator().createFromImages(icons);
     }
 
     /*
--- a/jdk/src/macosx/native/sun/awt/CImage.m	Fri Apr 06 17:15:09 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/CImage.m	Fri Apr 06 17:20:49 2012 +0400
@@ -70,19 +70,8 @@
     [oldContext release];
 }
 
-/*
- * Class:     sun_lwawt_macosx_CImage
- * Method:    nativeCreateNSImageFromArray
- * Signature: ([III)J
- */
-JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArray
-(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)
+static NSBitmapImageRep* CImage_CreateImageRep(JNIEnv *env, jintArray buffer, jint width, jint height)
 {
-    jlong result = 0L;
-
-JNF_COCOA_ENTER(env);
-AWT_ASSERT_ANY_THREAD;
-
     NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                          pixelsWide:width
                                                                          pixelsHigh:height
@@ -105,15 +94,83 @@
 
     (*env)->ReleasePrimitiveArrayCritical(env, buffer, src, JNI_ABORT);
 
-    NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
-    [nsImage addRepresentation:imageRep];
-    [imageRep release];
+    return imageRep;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CImage
+ * Method:    nativeCreateNSImageFromArray
+ * Signature: ([III)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArray
+(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)
+{
+    jlong result = 0L;
 
-    if (nsImage != nil) {
-        CFRetain(nsImage); // GC
+JNF_COCOA_ENTER(env);
+AWT_ASSERT_ANY_THREAD;
+
+    NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height);
+    if (imageRep) {
+        NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
+        [nsImage addRepresentation:imageRep];
+        [imageRep release];
+
+        if (nsImage != nil) {
+            CFRetain(nsImage); // GC
+        }
+
+        result = ptr_to_jlong(nsImage);
     }
 
-    result = ptr_to_jlong(nsImage);
+JNF_COCOA_EXIT(env);
+
+    return result;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CImage
+ * Method:    nativeCreateNSImageFromArrays
+ * Signature: ([[I[I[I)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArrays
+(JNIEnv *env, jclass klass, jobjectArray buffers, jintArray widths, jintArray heights)
+{
+    jlong result = 0L;
+
+JNF_COCOA_ENTER(env);
+AWT_ASSERT_ANY_THREAD;
+
+    jsize num = (*env)->GetArrayLength(env, buffers);
+    NSMutableArray * reps = [NSMutableArray arrayWithCapacity: num];
+
+    jint * ws = (*env)->GetIntArrayElements(env, widths, NULL);
+    jint * hs = (*env)->GetIntArrayElements(env, heights, NULL);
+
+    jsize i;
+    for (i = 0; i < num; i++) {
+        jintArray buffer = (*env)->GetObjectArrayElement(env, buffers, i);
+
+        NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, ws[i], hs[i]);
+        if (imageRep) {
+            [reps addObject: imageRep];
+        }
+    }
+
+    (*env)->ReleaseIntArrayElements(env, heights, hs, JNI_ABORT);
+    (*env)->ReleaseIntArrayElements(env, widths, ws, JNI_ABORT);
+
+    if ([reps count]) {
+        NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0, 0)];
+        [nsImage addRepresentations: reps];
+        [reps release];
+
+        if (nsImage != nil) {
+            CFRetain(nsImage); // GC
+        }
+
+        result = ptr_to_jlong(nsImage);
+    }
 
 JNF_COCOA_EXIT(env);