src/macosx/classes/sun/lwawt/macosx/CImage.java

Print this page

        

@@ -40,14 +40,15 @@
     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);
     private static native long nativeCreateNSImageFromIconSelector(int selector);
-    private static native void nativeCopyNSImageIntoArray(long image, int[] buffer, int w, int h);
+    private static native void nativeCopyNSImageIntoArray(long image, int[] buffer, int sw, int sh, int dw, int dh);
     private static native Dimension2D nativeGetNSImageSize(long image);
     private static native void nativeSetNSImageSize(long image, double w, double h);
     private static native void nativeResizeNSImageRepresentations(long image, double w, double h);
+    private static native Dimension2D[] nativeGetNSImageRepresentationSizes(long image, double w, double h);
 
     static Creator creator = new Creator();
     static Creator getCreator() {
         return creator;
     }

@@ -208,22 +209,46 @@
 
     CImage(long nsImagePtr) {
         super(nsImagePtr, true);
     }
 
-    /** @return A BufferedImage created from nsImagePtr, or null. */
-    public BufferedImage toImage() {
+    /** @return A MultiResolution image created from nsImagePtr, or null. */
+    private BufferedImage toImage() {
         if (ptr == 0) return null;
 
         final Dimension2D size = nativeGetNSImageSize(ptr);
-        final int w = (int)size.getWidth();
-        final int h = (int)size.getHeight();
+        final int w = (int) size.getWidth();
+        final int h = (int) size.getHeight();
 
-        final BufferedImage bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
+        Dimension2D[] sizes =
+                nativeGetNSImageRepresentationSizes(ptr,
+                        size.getWidth(), size.getHeight());
+
+        if (sizes == null || sizes.length < 2) {
+            return toImage(w, h, w, h);
+        }
+
+        BufferedImage[] images = new BufferedImage[sizes.length];
+        int currentImageIndex = 0;
+
+        for (int i = 0; i < sizes.length; i++) {
+            int imageRepWidth = (int) sizes[i].getWidth();
+            int imageRepHeight = (int) sizes[i].getHeight();
+
+            if(imageRepHeight <= w && imageRepHeight <= h){
+                currentImageIndex = i;
+            }
+            images[i] = toImage(w, h, imageRepWidth, imageRepHeight);
+        }
+        return new MultiResolutionBufferedImage(images, currentImageIndex);
+    }
+
+    private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
+        final BufferedImage bimg = new BufferedImage(dstWidth, dstHeight, BufferedImage.TYPE_INT_ARGB_PRE);
         final DataBufferInt dbi = (DataBufferInt)bimg.getRaster().getDataBuffer();
         final int[] buffer = SunWritableRaster.stealData(dbi, 0);
-        nativeCopyNSImageIntoArray(ptr, buffer, w, h);
+        nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight);
         SunWritableRaster.markDirty(dbi);
         return bimg;
     }
 
     /** If nsImagePtr != 0 then scale this NSImage. @return *this* */

@@ -233,6 +258,37 @@
     }
 
     void resizeRepresentations(double w, double h) {
         if (ptr != 0) nativeResizeNSImageRepresentations(ptr, w, h);
     }
+
+    private static class MultiResolutionBufferedImage extends BufferedImage
+            implements MultiResolutionImage {
+
+        BufferedImage[] resolutionVariants;
+
+        public MultiResolutionBufferedImage(BufferedImage[] images, int baseIndex) {
+            super(images[baseIndex].getWidth(), images[baseIndex].getHeight(),
+                    images[baseIndex].getType());
+            this.resolutionVariants = images;
+            Graphics g = getGraphics();
+            g.drawImage(images[baseIndex], 0, 0, null);
+            g.dispose();
+            images[baseIndex] = this;
+        }
+
+        @Override
+        public Image getResolutionVariant(int width, int height) {
+            for (BufferedImage image : resolutionVariants) {
+                if (width <= image.getWidth() && height <= image.getHeight()) {
+                    return image;
+                }
+            }
+            return this;
+        }
+
+        @Override
+        public List<Image> getResolutionVariants() {
+            return Arrays.asList(resolutionVariants);
+        }
+    }
 }