提交 4393ad17 编写于 作者: A alexsch

8033534: [macosx] Get MultiResolution image from native system

Reviewed-by: serb, pchelko
上级 fb6c2de6
...@@ -32,6 +32,7 @@ import java.awt.image.*; ...@@ -32,6 +32,7 @@ import java.awt.image.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import sun.awt.image.MultiResolutionImage; import sun.awt.image.MultiResolutionImage;
import sun.awt.image.MultiResolutionBufferedImage;
import sun.awt.image.SunWritableRaster; import sun.awt.image.SunWritableRaster;
...@@ -42,10 +43,11 @@ public class CImage extends CFRetainedResource { ...@@ -42,10 +43,11 @@ public class CImage extends CFRetainedResource {
private static native long nativeCreateNSImageOfFileFromLaunchServices(String file); private static native long nativeCreateNSImageOfFileFromLaunchServices(String file);
private static native long nativeCreateNSImageFromImageName(String name); private static native long nativeCreateNSImageFromImageName(String name);
private static native long nativeCreateNSImageFromIconSelector(int selector); 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 Dimension2D nativeGetNSImageSize(long image);
private static native void nativeSetNSImageSize(long image, double w, double h); 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 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 creator = new Creator();
static Creator getCreator() { static Creator getCreator() {
...@@ -210,18 +212,43 @@ public class CImage extends CFRetainedResource { ...@@ -210,18 +212,43 @@ public class CImage extends CFRetainedResource {
super(nsImagePtr, true); super(nsImagePtr, true);
} }
/** @return A BufferedImage created from nsImagePtr, or null. */ /** @return A MultiResolution image created from nsImagePtr, or null. */
public BufferedImage toImage() { private BufferedImage toImage() {
if (ptr == 0) return null; if (ptr == 0) return null;
final Dimension2D size = nativeGetNSImageSize(ptr); final Dimension2D size = nativeGetNSImageSize(ptr);
final int w = (int)size.getWidth(); final int w = (int)size.getWidth();
final int h = (int)size.getHeight(); 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(BufferedImage.TYPE_INT_ARGB_PRE,
currentImageIndex, images);
}
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 DataBufferInt dbi = (DataBufferInt)bimg.getRaster().getDataBuffer();
final int[] buffer = SunWritableRaster.stealData(dbi, 0); final int[] buffer = SunWritableRaster.stealData(dbi, 0);
nativeCopyNSImageIntoArray(ptr, buffer, w, h); nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight);
SunWritableRaster.markDirty(dbi); SunWritableRaster.markDirty(dbi);
return bimg; return bimg;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
#import "jni_util.h"
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h> #import <JavaNativeFoundation/JavaNativeFoundation.h>
...@@ -52,18 +53,21 @@ static void CImage_CopyArrayIntoNSImageRep ...@@ -52,18 +53,21 @@ static void CImage_CopyArrayIntoNSImageRep
} }
static void CImage_CopyNSImageIntoArray static void CImage_CopyNSImageIntoArray
(NSImage *srcImage, jint *dstPixels, int width, int height) (NSImage *srcImage, jint *dstPixels, NSRect fromRect, NSRect toRect)
{ {
int width = toRect.size.width;
int height = toRect.size.height;
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgRef = CGBitmapContextCreate(dstPixels, width, height, 8, width * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); CGContextRef cgRef = CGBitmapContextCreate(dstPixels, width, height,
8, width * 4, colorspace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
CGColorSpaceRelease(colorspace); CGColorSpaceRelease(colorspace);
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:cgRef flipped:NO]; NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:cgRef flipped:NO];
CGContextRelease(cgRef); CGContextRelease(cgRef);
NSGraphicsContext *oldContext = [[NSGraphicsContext currentContext] retain]; NSGraphicsContext *oldContext = [[NSGraphicsContext currentContext] retain];
[NSGraphicsContext setCurrentContext:context]; [NSGraphicsContext setCurrentContext:context];
NSRect rect = NSMakeRect(0, 0, width, height); [srcImage drawInRect:toRect
[srcImage drawInRect:rect fromRect:fromRect
fromRect:rect
operation:NSCompositeSourceOver operation:NSCompositeSourceOver
fraction:1.0]; fraction:1.0];
[NSGraphicsContext setCurrentContext:oldContext]; [NSGraphicsContext setCurrentContext:oldContext];
...@@ -266,17 +270,20 @@ JNF_COCOA_EXIT(env); ...@@ -266,17 +270,20 @@ JNF_COCOA_EXIT(env);
/* /*
* Class: sun_lwawt_macosx_CImage * Class: sun_lwawt_macosx_CImage
* Method: nativeCopyNSImageIntoArray * Method: nativeCopyNSImageIntoArray
* Signature: (J[III)V * Signature: (J[IIIII)V
*/ */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray
(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint w, jint h) (JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint sw, jint sh,
jint dw, jint dh)
{ {
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr); NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr);
jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL); jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
if (dst) { if (dst) {
CImage_CopyNSImageIntoArray(img, dst, w, h); NSRect fromRect = NSMakeRect(0, 0, sw, sh);
NSRect toRect = NSMakeRect(0, 0, dw, dh);
CImage_CopyNSImageIntoArray(img, dst, fromRect, toRect);
(*env)->ReleasePrimitiveArrayCritical(env, buffer, dst, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, buffer, dst, JNI_ABORT);
} }
...@@ -343,3 +350,87 @@ JNF_COCOA_ENTER(env); ...@@ -343,3 +350,87 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
} }
NSComparisonResult getOrder(BOOL order){
return (NSComparisonResult) (order ? NSOrderedAscending : NSOrderedDescending);
}
/*
* Class: sun_lwawt_macosx_CImage
* Method: nativeGetNSImageRepresentationsCount
* Signature: (JDD)[Ljava/awt/geom/Dimension2D;
*/
JNIEXPORT jobjectArray JNICALL
Java_sun_lwawt_macosx_CImage_nativeGetNSImageRepresentationSizes
(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)
{
if (!image) return NULL;
jobjectArray jreturnArray = NULL;
NSImage *img = (NSImage *)jlong_to_ptr(image);
JNF_COCOA_ENTER(env);
NSArray *imageRepresentations = [img representations];
if([imageRepresentations count] == 0){
return NULL;
}
NSArray *sortedImageRepresentations = [imageRepresentations
sortedArrayUsingComparator: ^(id obj1, id obj2) {
NSImageRep *imageRep1 = (NSImageRep *) obj1;
NSImageRep *imageRep2 = (NSImageRep *) obj2;
NSSize size1 = [imageRep1 size];
NSSize size2 = [imageRep2 size];
if (NSEqualSizes(size1, size2)) {
return getOrder([imageRep1 pixelsWide] <= [imageRep2 pixelsWide] &&
[imageRep1 pixelsHigh] <= [imageRep2 pixelsHigh]);
}
return getOrder(size1.width <= size2.width && size1.height <= size2.height);
}];
NSMutableArray *sortedPixelSizes = [[NSMutableArray alloc] init];
NSSize lastSize = [[sortedImageRepresentations lastObject] size];
NSUInteger i = [sortedImageRepresentations indexOfObjectPassingTest:
^BOOL(id obj, NSUInteger idx, BOOL *stop) {
NSSize imageRepSize = [obj size];
return (w <= imageRepSize.width && h <= imageRepSize.height)
|| NSEqualSizes(imageRepSize, lastSize);
}];
NSUInteger count = [sortedImageRepresentations count];
i = (i == NSNotFound) ? count - 1 : i;
NSSize bestFitSize = [[sortedImageRepresentations objectAtIndex: i] size];
for(; i < count; i++){
NSImageRep *imageRep = [sortedImageRepresentations objectAtIndex: i];
if (!NSEqualSizes([imageRep size], bestFitSize)) {
break;
}
NSSize pixelSize = NSMakeSize(
[imageRep pixelsWide], [imageRep pixelsHigh]);
[sortedPixelSizes addObject: [NSValue valueWithSize: pixelSize]];
}
count = [sortedPixelSizes count];
static JNF_CLASS_CACHE(jc_Dimension, "java/awt/Dimension");
jreturnArray = JNFNewObjectArray(env, &jc_Dimension, count);
CHECK_NULL_RETURN(jreturnArray, NULL);
for(i = 0; i < count; i++){
NSSize pixelSize = [[sortedPixelSizes objectAtIndex: i] sizeValue];
(*env)->SetObjectArrayElement(env, jreturnArray, i,
NSToJavaSize(env, pixelSize));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
}
JNF_COCOA_EXIT(env);
return jreturnArray;
}
\ No newline at end of file
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Image;
import java.awt.Toolkit;
import sun.awt.OSInfo;
import sun.awt.image.MultiResolutionImage;
/*
* @test
* @bug 8033534
* @summary [macosx] Get MultiResolution image from native system
* @author Alexander Scherbatiy
* @run main NSImageToMultiResolutionImageTest
*/
public class NSImageToMultiResolutionImageTest {
public static void main(String[] args) throws Exception {
if (OSInfo.getOSType() != OSInfo.OSType.MACOSX) {
return;
}
String icon = "NSImage://NSApplicationIcon";
final Image image = Toolkit.getDefaultToolkit().getImage(icon);
if (!(image instanceof MultiResolutionImage)) {
throw new RuntimeException("Icon does not have resolution variants!");
}
MultiResolutionImage multiResolutionImage = (MultiResolutionImage) image;
int width = 0;
int height = 0;
for (Image resolutionVariant : multiResolutionImage.getResolutionVariants()) {
int rvWidth = resolutionVariant.getWidth(null);
int rvHeight = resolutionVariant.getHeight(null);
if (rvWidth < width || rvHeight < height) {
throw new RuntimeException("Resolution variants are not sorted!");
}
width = rvWidth;
height = rvHeight;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册