--- old/src/share/bin/java.c 2014-06-17 14:39:04.634960600 +0400 +++ new/src/share/bin/java.c 2014-06-17 14:39:03.778851800 +0400 @@ -1816,17 +1816,43 @@ const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY); const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY); int data_size; - void *image_data; - if (jar_name) { - image_data = JLI_JarUnpackFile(jar_name, file_name, &data_size); - if (image_data) { + void *image_data = NULL; + float scale_factor = 1; + char *scaled_splash_name = NULL; + + if (file_name) { + scaled_splash_name = DoSplashGetScaledImageName( + jar_name, file_name, &scale_factor); + if (jar_name) { + + if (scaled_splash_name) { + image_data = JLI_JarUnpackFile( + jar_name, scaled_splash_name, &data_size); + } + + if (!image_data) { + scale_factor = 1; + image_data = JLI_JarUnpackFile( + jar_name, file_name, &data_size); + } + if (image_data) { + DoSplashInit(); + DoSplashSetScaleFactor(scale_factor); + DoSplashLoadMemory(image_data, data_size); + JLI_MemFree(image_data); + } + } else { DoSplashInit(); - DoSplashLoadMemory(image_data, data_size); - JLI_MemFree(image_data); + if(scaled_splash_name){ + DoSplashSetScaleFactor(scale_factor); + DoSplashLoadFile(scaled_splash_name); + } else { + DoSplashLoadFile(file_name); + } + } + if(scaled_splash_name){ + JLI_MemFree(scaled_splash_name); } - } else if (file_name) { - DoSplashInit(); - DoSplashLoadFile(file_name); } else { return; } --- old/src/share/bin/splashscreen.h 2014-06-17 14:39:10.875753000 +0400 +++ new/src/share/bin/splashscreen.h 2014-06-17 14:39:10.150661000 +0400 @@ -29,3 +29,6 @@ void DoSplashInit(void); void DoSplashClose(void); void DoSplashSetFileJarName(const char* fileName, const char* jarName); +void DoSplashSetScaleFactor(float scaleFactor); +char* DoSplashGetScaledImageName(const char* jarName, const char* fileName, + float* scaleFactor); --- old/src/share/bin/splashscreen_stubs.c 2014-06-17 14:39:14.603726400 +0400 +++ new/src/share/bin/splashscreen_stubs.c 2014-06-17 14:39:13.880634600 +0400 @@ -37,6 +37,9 @@ typedef void (*SplashClose_t)(void); typedef void (*SplashSetFileJarName_t)(const char* fileName, const char* jarName); +typedef void (*SplashSetScaleFactor_t)(float scaleFactor); +typedef char* (*SplashGetScaledImageName_t)(const char* fileName, + const char* jarName, float* scaleFactor); /* * This macro invokes a function from the shared lib. @@ -76,3 +79,12 @@ void DoSplashSetFileJarName(const char* fileName, const char* jarName) { INVOKEV(SplashSetFileJarName)(fileName, jarName); } + +void DoSplashSetScaleFactor(float scaleFactor) { + INVOKEV(SplashSetScaleFactor)(scaleFactor); +} + +char* DoSplashGetScaledImageName(const char* fileName, const char* jarName, + float* scaleFactor) { + INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor); +} \ No newline at end of file --- old/src/share/native/sun/awt/splashscreen/splashscreen_impl.h 2014-06-17 14:39:18.452215100 +0400 +++ new/src/share/native/sun/awt/splashscreen/splashscreen_impl.h 2014-06-17 14:39:17.682617400 +0400 @@ -35,6 +35,9 @@ SPLASHEXPORT void SplashInit(void); SPLASHEXPORT void SplashClose(void); +SPLASHEXPORT void SplashSetScaleFactor(float); +SPLASHEXPORT char* SplashGetScaledImageName(const char*, const char*, float*); + SPLASHEXPORT void SplashSetFileJarName(const char* fileName, const char* jarName); @@ -79,6 +82,7 @@ int fileNameLen; char* jarName; /* stored in 16-bit unicode (jchars) */ int jarNameLen; + float scaleFactor; #if defined(WITH_WIN32) BOOL isLayered; HWND hWnd; @@ -115,6 +119,8 @@ unsigned SplashTime(); char* SplashConvertStringAlloc(const char* in, int *size); +char* SplashGetScaledImageName(const char* jarName, + const char* fileName, float *scaleFactor); void SplashLock(Splash * splash); void SplashUnlock(Splash * splash); @@ -138,6 +144,7 @@ void SplashUpdateScreenData(Splash * splash); void SplashCleanup(Splash * splash); +void SplashSetScaleFactor(float scaleFactor); typedef struct SplashStream { --- old/src/share/native/sun/awt/splashscreen/splashscreen_impl.c 2014-06-17 14:39:22.409217600 +0400 +++ new/src/share/native/sun/awt/splashscreen/splashscreen_impl.c 2014-06-17 14:39:21.628118400 +0400 @@ -59,6 +59,7 @@ memset(splash, 0, sizeof(Splash)); splash->currentFrame = -1; + splash->scaleFactor = 1; initFormat(&splash->imageFormat, QUAD_RED_MASK, QUAD_GREEN_MASK, QUAD_BLUE_MASK, QUAD_ALPHA_MASK); SplashInitPlatform(splash); @@ -101,6 +102,13 @@ SplashSetFileJarName(NULL, NULL); } +SPLASHEXPORT void +SplashSetScaleFactor(float scaleFactor) +{ + Splash *splash = SplashGetInstance(); + splash->scaleFactor = scaleFactor; +} + void SplashDone(Splash * splash) { @@ -365,7 +373,7 @@ static void closeMem(void* pStream) { } -int SplashStreamInitFile(SplashStream * pStream, const char* filename) { +int SplashStreamInitFile(SplashStream * pStream, const char* filename) { pStream->arg.stdio.f = fopen(filename, "rb"); pStream->read = readFile; pStream->peek = peekFile; --- old/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c 2014-06-17 14:39:26.319214100 +0400 +++ new/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c 2014-06-17 14:39:25.564118200 +0400 @@ -563,3 +563,11 @@ { PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0); } + +SPLASHEXPORT char* +SplashGetScaledImageName(const char* jarName, const char* fileName, + float *scaleFactor) +{ + *scaleFactor=1; + return NULL; +} \ No newline at end of file --- old/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c 2014-06-17 14:39:30.230710800 +0400 +++ new/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c 2014-06-17 14:39:29.465113600 +0400 @@ -794,3 +794,11 @@ SplashReconfigure(Splash * splash) { sendctl(splash, SPLASHCTL_RECONFIGURE); } + +SPLASHEXPORT char* +SplashGetScaledImageName(const char* jarName, const char* fileName, + float *scaleFactor) +{ + *scaleFactor=1; + return NULL; +} --- old/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m 2014-06-17 14:39:34.148708300 +0400 +++ new/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m 2014-06-17 14:39:33.411114700 +0400 @@ -125,6 +125,36 @@ return buf; } +char* SplashGetScaledImageName(const char* jar, const char* file, + float *scaleFactor) { + NSString *fileName = [[[NSString alloc] initWithUTF8String: file] + autorelease]; + NSUInteger length = [fileName length]; + *scaleFactor = 1; + float screenScaleFactor = [[NSScreen mainScreen] backingScaleFactor]; + + if (1 < screenScaleFactor) { + NSRange range = [fileName rangeOfString: @"." + options:NSBackwardsSearch]; + int index = range.location; + + if (index != NSNotFound && index != 0 && index != length-1) { + NSString *fileName2x = [fileName substringToIndex: index]; + fileName2x = [fileName2x stringByAppendingString: @"@2x"]; + fileName2x = [fileName2x stringByAppendingString: + [fileName substringFromIndex: index]]; + + if (!jar && ![[NSFileManager defaultManager] + fileExistsAtPath: fileName2x]){ + return nil; + } + + *scaleFactor = 2; + return strdup([fileName2x UTF8String]); + } + } + return nil; +} void SplashInitPlatform(Splash * splash) { @@ -132,7 +162,7 @@ splash->maskRequired = 0; - + //TODO: the following is too much of a hack but should work in 90% cases. // besides we don't use device-dependant drawing, so probably // that's very fine indeed @@ -225,7 +255,15 @@ [image setBackgroundColor: [NSColor clearColor]]; [image addRepresentation: rep]; - + float scaleFactor = splash->scaleFactor; + if (scaleFactor != 1) { + [image setScalesWhenResized:YES]; + NSSize size = [image size]; + size.width /= scaleFactor; + size.height /= scaleFactor; + [image setSize: size]; + } + NSImageView * view = [[NSImageView alloc] init]; [view setImage: image]; --- old/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c 2014-06-17 14:39:38.030201200 +0400 +++ new/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c 2014-06-17 14:39:37.282106200 +0400 @@ -1,222 +1,237 @@ -/* - * Copyright (c) 2005, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include "splashscreen_impl.h" -#include -#include -#include -#include - -JNIEXPORT jint JNICALL -JNI_OnLoad(JavaVM * vm, void *reserved) -{ - return JNI_VERSION_1_2; -} - -/* FIXME: safe_ExceptionOccured, why and how? */ - -/* -* Class: java_awt_SplashScreen -* Method: _update -* Signature: (J[IIIIII)V -*/ -JNIEXPORT void JNICALL -Java_java_awt_SplashScreen__1update(JNIEnv * env, jclass thisClass, - jlong jsplash, jintArray data, - jint x, jint y, jint width, jint height, - jint stride) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - int dataSize; - - if (!splash) { - return; - } - SplashLock(splash); - dataSize = (*env)->GetArrayLength(env, data); - if (splash->overlayData) { - free(splash->overlayData); - } - splash->overlayData = SAFE_SIZE_ARRAY_ALLOC(malloc, dataSize, sizeof(rgbquad_t)); - if (splash->overlayData) { - /* we need a copy anyway, so we'll be using GetIntArrayRegion */ - (*env)->GetIntArrayRegion(env, data, 0, dataSize, - (jint *) splash->overlayData); - initFormat(&splash->overlayFormat, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); - initRect(&splash->overlayRect, x, y, width, height, 1, - stride * sizeof(rgbquad_t), splash->overlayData, - &splash->overlayFormat); - SplashUpdate(splash); - } - SplashUnlock(splash); -} - - -/* -* Class: java_awt_SplashScreen -* Method: _isVisible -* Signature: (J)Z -*/ -JNIEXPORT jboolean JNICALL -Java_java_awt_SplashScreen__1isVisible(JNIEnv * env, jclass thisClass, - jlong jsplash) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - - if (!splash) { - return JNI_FALSE; - } - return splash->isVisible>0 ? JNI_TRUE : JNI_FALSE; -} - -/* -* Class: java_awt_SplashScreen -* Method: _getBounds -* Signature: (J)Ljava/awt/Rectangle; -*/ -JNIEXPORT jobject JNICALL -Java_java_awt_SplashScreen__1getBounds(JNIEnv * env, jclass thisClass, - jlong jsplash) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - static jclass clazz = NULL; - static jmethodID mid = NULL; - jobject bounds = NULL; - - if (!splash) { - return NULL; - } - SplashLock(splash); - if (!clazz) { - clazz = (*env)->FindClass(env, "java/awt/Rectangle"); - if (clazz) { - clazz = (*env)->NewGlobalRef(env, clazz); - } - } - if (clazz && !mid) { - mid = (*env)->GetMethodID(env, clazz, "", "(IIII)V"); - } - if (clazz && mid) { - bounds = (*env)->NewObject(env, clazz, mid, splash->x, splash->y, - splash->width, splash->height); - if ((*env)->ExceptionOccurred(env)) { - bounds = NULL; - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - } - } - SplashUnlock(splash); - return bounds; -} - -/* -* Class: java_awt_SplashScreen -* Method: _getInstance -* Signature: ()J -*/ -JNIEXPORT jlong JNICALL -Java_java_awt_SplashScreen__1getInstance(JNIEnv * env, jclass thisClass) -{ - return ptr_to_jlong(SplashGetInstance()); -} - -/* -* Class: java_awt_SplashScreen -* Method: _close -* Signature: (J)V -*/ -JNIEXPORT void JNICALL -Java_java_awt_SplashScreen__1close(JNIEnv * env, jclass thisClass, - jlong jsplash) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - - if (!splash) { - return; - } - SplashLock(splash); - SplashClosePlatform(splash); - SplashUnlock(splash); -} - -/* - * Class: java_awt_SplashScreen - * Method: _getImageFileName - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_java_awt_SplashScreen__1getImageFileName - (JNIEnv * env, jclass thisClass, jlong jsplash) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - - - if (!splash || !splash->fileName) { - return NULL; - } - /* splash->fileName is of type char*, but in fact it contains jchars */ - return (*env)->NewString(env, (const jchar*)splash->fileName, - splash->fileNameLen); -} - -/* - * Class: java_awt_SplashScreen - * Method: _getImageJarName - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_java_awt_SplashScreen__1getImageJarName - (JNIEnv * env, jclass thisClass, jlong jsplash) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - - if (!splash || !splash->jarName) { - return NULL; - } - /* splash->jarName is of type char*, but in fact it contains jchars */ - return (*env)->NewString(env, (const jchar*)splash->jarName, - splash->jarNameLen); -} - -/* - * Class: java_awt_SplashScreen - * Method: _setImageData - * Signature: (J[B)Z - */ -JNIEXPORT jboolean JNICALL Java_java_awt_SplashScreen__1setImageData - (JNIEnv * env, jclass thisClass, jlong jsplash, jbyteArray data) -{ - Splash *splash = (Splash *) jlong_to_ptr(jsplash); - int size, rc; - jbyte* pBytes; - - if (!splash) { - return JNI_FALSE; - } - pBytes = (*env)->GetByteArrayElements(env, data, NULL); - CHECK_NULL_RETURN(pBytes, JNI_FALSE); - size = (*env)->GetArrayLength(env, data); - rc = SplashLoadMemory(pBytes, size); - (*env)->ReleaseByteArrayElements(env, data, pBytes, JNI_ABORT); - return rc ? JNI_TRUE : JNI_FALSE; -} +/* + * Copyright (c) 2005, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include "splashscreen_impl.h" +#include +#include +#include +#include + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM * vm, void *reserved) +{ + return JNI_VERSION_1_2; +} + +/* FIXME: safe_ExceptionOccured, why and how? */ + +/* +* Class: java_awt_SplashScreen +* Method: _update +* Signature: (J[IIIIII)V +*/ +JNIEXPORT void JNICALL +Java_java_awt_SplashScreen__1update(JNIEnv * env, jclass thisClass, + jlong jsplash, jintArray data, + jint x, jint y, jint width, jint height, + jint stride) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + int dataSize; + + if (!splash) { + return; + } + SplashLock(splash); + dataSize = (*env)->GetArrayLength(env, data); + if (splash->overlayData) { + free(splash->overlayData); + } + splash->overlayData = SAFE_SIZE_ARRAY_ALLOC(malloc, dataSize, sizeof(rgbquad_t)); + if (splash->overlayData) { + /* we need a copy anyway, so we'll be using GetIntArrayRegion */ + (*env)->GetIntArrayRegion(env, data, 0, dataSize, + (jint *) splash->overlayData); + initFormat(&splash->overlayFormat, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); + initRect(&splash->overlayRect, x, y, width, height, 1, + stride * sizeof(rgbquad_t), splash->overlayData, + &splash->overlayFormat); + SplashUpdate(splash); + } + SplashUnlock(splash); +} + + +/* +* Class: java_awt_SplashScreen +* Method: _isVisible +* Signature: (J)Z +*/ +JNIEXPORT jboolean JNICALL +Java_java_awt_SplashScreen__1isVisible(JNIEnv * env, jclass thisClass, + jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + + if (!splash) { + return JNI_FALSE; + } + return splash->isVisible>0 ? JNI_TRUE : JNI_FALSE; +} + +/* +* Class: java_awt_SplashScreen +* Method: _getBounds +* Signature: (J)Ljava/awt/Rectangle; +*/ +JNIEXPORT jobject JNICALL +Java_java_awt_SplashScreen__1getBounds(JNIEnv * env, jclass thisClass, + jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + static jclass clazz = NULL; + static jmethodID mid = NULL; + jobject bounds = NULL; + + if (!splash) { + return NULL; + } + SplashLock(splash); + if (!clazz) { + clazz = (*env)->FindClass(env, "java/awt/Rectangle"); + if (clazz) { + clazz = (*env)->NewGlobalRef(env, clazz); + } + } + if (clazz && !mid) { + mid = (*env)->GetMethodID(env, clazz, "", "(IIII)V"); + } + if (clazz && mid) { + bounds = (*env)->NewObject(env, clazz, mid, splash->x, splash->y, + splash->width, splash->height); + if ((*env)->ExceptionOccurred(env)) { + bounds = NULL; + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + } + } + SplashUnlock(splash); + return bounds; +} + +/* +* Class: java_awt_SplashScreen +* Method: _getInstance +* Signature: ()J +*/ +JNIEXPORT jlong JNICALL +Java_java_awt_SplashScreen__1getInstance(JNIEnv * env, jclass thisClass) +{ + return ptr_to_jlong(SplashGetInstance()); +} + +/* +* Class: java_awt_SplashScreen +* Method: _close +* Signature: (J)V +*/ +JNIEXPORT void JNICALL +Java_java_awt_SplashScreen__1close(JNIEnv * env, jclass thisClass, + jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + + if (!splash) { + return; + } + SplashLock(splash); + SplashClosePlatform(splash); + SplashUnlock(splash); +} + +/* + * Class: java_awt_SplashScreen + * Method: _getImageFileName + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_java_awt_SplashScreen__1getImageFileName + (JNIEnv * env, jclass thisClass, jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + + + if (!splash || !splash->fileName) { + return NULL; + } + /* splash->fileName is of type char*, but in fact it contains jchars */ + return (*env)->NewString(env, (const jchar*)splash->fileName, + splash->fileNameLen); +} + +/* + * Class: java_awt_SplashScreen + * Method: _getImageJarName + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_java_awt_SplashScreen__1getImageJarName + (JNIEnv * env, jclass thisClass, jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + + if (!splash || !splash->jarName) { + return NULL; + } + /* splash->jarName is of type char*, but in fact it contains jchars */ + return (*env)->NewString(env, (const jchar*)splash->jarName, + splash->jarNameLen); +} + +/* + * Class: java_awt_SplashScreen + * Method: _setImageData + * Signature: (J[B)Z + */ +JNIEXPORT jboolean JNICALL Java_java_awt_SplashScreen__1setImageData + (JNIEnv * env, jclass thisClass, jlong jsplash, jbyteArray data) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + int size, rc; + jbyte* pBytes; + + if (!splash) { + return JNI_FALSE; + } + pBytes = (*env)->GetByteArrayElements(env, data, NULL); + CHECK_NULL_RETURN(pBytes, JNI_FALSE); + size = (*env)->GetArrayLength(env, data); + rc = SplashLoadMemory(pBytes, size); + (*env)->ReleaseByteArrayElements(env, data, pBytes, JNI_ABORT); + return rc ? JNI_TRUE : JNI_FALSE; +} + +/* + * Class: java_awt_SplashScreen + * Method: _getScaleFactor + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_java_awt_SplashScreen__1getScaleFactor +(JNIEnv *env, jclass thisClass, jlong jsplash) +{ + Splash *splash = (Splash *) jlong_to_ptr(jsplash); + if (!splash) { + return 1; + } + return splash->scaleFactor; +} \ No newline at end of file --- old/make/mapfiles/libsplashscreen/mapfile-vers 2014-06-17 14:39:41.876689700 +0400 +++ new/make/mapfiles/libsplashscreen/mapfile-vers 2014-06-17 14:39:41.143096500 +0400 @@ -35,6 +35,7 @@ Java_java_awt_SplashScreen__1getImageFileName; Java_java_awt_SplashScreen__1getImageJarName; Java_java_awt_SplashScreen__1setImageData; + Java_java_awt_SplashScreen__1getScaleFactor; SplashLoadMemory; SplashLoadFile; --- old/src/share/classes/java/awt/SplashScreen.java 2014-06-17 14:39:45.690674000 +0400 +++ new/src/share/classes/java/awt/SplashScreen.java 2014-06-17 14:39:44.970082500 +0400 @@ -245,7 +245,13 @@ public Rectangle getBounds() throws IllegalStateException { synchronized (SplashScreen.class) { checkVisible(); - return _getBounds(splashPtr); + float scale = _getScaleFactor(splashPtr); + Rectangle bounds = _getBounds(splashPtr); + if (scale != 1) { + bounds.setSize((int) (bounds.getWidth() / scale), + (int) (bounds.getWidth() / scale)); + } + return bounds; } } @@ -287,10 +293,15 @@ public Graphics2D createGraphics() throws IllegalStateException { synchronized (SplashScreen.class) { if (image==null) { - Dimension dim = getSize(); - image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB); + // get unscaled splash image size + Dimension dim = _getBounds(splashPtr).getSize(); + image = new BufferedImage(dim.width, dim.height, + BufferedImage.TYPE_INT_ARGB); } - return image.createGraphics(); + float scale = _getScaleFactor(splashPtr); + Graphics2D g = image.createGraphics(); + g.scale(scale, scale); + return g; } } @@ -401,5 +412,6 @@ private native static String _getImageFileName(long splashPtr); private native static String _getImageJarName(long SplashPtr); private native static boolean _setImageData(long SplashPtr, byte[] data); + private native static float _getScaleFactor(long SplashPtr); }; --- /dev/null 2014-06-17 14:39:49.000000000 +0400 +++ new/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java 2014-06-17 14:39:48.922584400 +0400 @@ -0,0 +1,141 @@ +/* + * 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.Color; +import java.awt.Dialog; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.SplashScreen; +import java.awt.Window; +import java.awt.image.BufferedImage; +import java.io.File; +import javax.imageio.ImageIO; +import sun.java2d.SunGraphics2D; + +/** + * @test + * @bug 8043869 + * @author Alexander Scherbatiy + * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina + * support + * @run main MultiResolutionSplashTest GENERATE_IMAGES + * @run main/othervm -splash:image.png MultiResolutionSplashTest TEST_SPLASH + */ +public class MultiResolutionSplashTest { + + private static final int IMAGE_WIDTH = 300; + private static final int IMAGE_HEIGHT = 200; + private static final Color COLOR_1X = Color.GREEN; + private static final Color COLOR_2X = Color.BLUE; + private static final String IMAGE_NAME_1X = "image.png"; + private static final String IMAGE_NAME_2X = "image@2x.png"; + + public static void main(String[] args) throws Exception { + + String test = args[0]; + + switch (test) { + case "GENERATE_IMAGES": + generateImages(); + break; + case "TEST_SPLASH": + testSplash(); + break; + default: + throw new RuntimeException("Unknown test: " + test); + } + } + + static void testSplash() throws Exception { + SplashScreen splashScreen = SplashScreen.getSplashScreen(); + + if (splashScreen == null) { + throw new RuntimeException("Splash screen is not shown!"); + } + + Graphics2D g = splashScreen.createGraphics(); + Rectangle splashBounds = splashScreen.getBounds(); + int screenX = (int) splashBounds.getCenterX(); + int screenY = (int) splashBounds.getCenterY(); + + Robot robot = new Robot(); + Color splashScreenColor = robot.getPixelColor(screenX, screenY); + + float scaleFactor = getScaleFactor(); + Color testColor = (1 < scaleFactor) ? COLOR_2X : COLOR_1X; + + if (!testColor.equals(splashScreenColor)) { + throw new RuntimeException( + "Image with wrong resolution is used for splash screen!"); + } + } + + static float getScaleFactor() { + + final Dialog dialog = new Dialog((Window) null); + dialog.setSize(100, 100); + dialog.setModal(true); + final float[] scaleFactors = new float[1]; + Panel panel = new Panel() { + + @Override + public void paint(Graphics g) { + float scaleFactor = 1; + if (g instanceof SunGraphics2D) { + scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale(); + } + scaleFactors[0] = scaleFactor; + dialog.setVisible(false); + } + }; + + dialog.add(panel); + dialog.setVisible(true); + dialog.dispose(); + + return scaleFactors[0]; + } + + static void generateImages() throws Exception { + if (!new File(IMAGE_NAME_1X).exists()) { + generateImage(1); + } + + if (!new File(IMAGE_NAME_2X).exists()) { + generateImage(2); + } + } + + static void generateImage(int scale) throws Exception { + BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT, + BufferedImage.TYPE_INT_RGB); + Graphics g = image.getGraphics(); + g.setColor(scale == 1 ? COLOR_1X : COLOR_2X); + g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT); + File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X); + ImageIO.write(image, "png", file); + } +}