8151787: Unify the HiDPI splash screen image naming convention

Reviewed-by: prr, alexsch, ksrini
This commit is contained in:
Rajeev Chamyal 2016-10-06 14:31:12 +05:30 committed by Rajeev Chamyal
parent c365ea61b5
commit 5e40c7ba0e
10 changed files with 211 additions and 150 deletions

View File

@ -44,6 +44,7 @@ SUNWprivate_1.1 {
SplashSetFileJarName;
SplashSetScaleFactor;
SplashGetScaledImageName;
SplashGetScaledImgNameMaxPstfixLen;
local:
*;
};

View File

@ -95,6 +95,12 @@ java.launcher.opt.footer =\ -cp <class search path of directories and zip
\ load Java programming language agent, see java.lang.instrument\n\
\ -splash:<imagepath>\n\
\ show splash screen with specified image\n\
\ HiDPI scaled images are automatically supported and used\n\
\ if available. The unscaled image filename, e.g. image.ext,\n\
\ should always be passed as the argument to the -splash option.\n\
\ The most appropriate scaled image provided will be picked up\n\
\ automatically.\n\
\ See the SplashScreen API documentation for more information.\n\
\ @<filepath> read options from the specified file\n\
\To specify an argument for a long option, you can use --<name>=<value> or\n\
\--<name> <value>.\n\

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, 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
@ -47,6 +47,10 @@
#include <sizecalc.h>
#import "ThreadUtilities.h"
NSString* findScaledImageName(NSString *fileName,
NSUInteger dotIndex,
NSString *strToAppend);
static NSScreen* SplashNSScreen()
{
return [[NSScreen screens] objectAtIndex: 0];
@ -134,8 +138,8 @@ BOOL isSWTRunning() {
}
jboolean SplashGetScaledImageName(const char* jar, const char* file,
float *scaleFactor, char *scaledFile,
const size_t scaledImageLength) {
float *scaleFactor, char *scaledFile,
const size_t scaledImageLength) {
*scaleFactor = 1;
if(isSWTRunning()){
@ -158,18 +162,14 @@ jboolean SplashGetScaledImageName(const char* jar, const char* file,
options:NSBackwardsSearch];
NSUInteger dotIndex = range.location;
NSString *fileName2x = nil;
if (dotIndex == NSNotFound) {
fileName2x = [fileName stringByAppendingString: @"@2x"];
} else {
fileName2x = [fileName substringToIndex: dotIndex];
fileName2x = [fileName2x stringByAppendingString: @"@2x"];
fileName2x = [fileName2x stringByAppendingString:
[fileName substringFromIndex: dotIndex]];
fileName2x = findScaledImageName(fileName, dotIndex, @"@2x");
if(![[NSFileManager defaultManager]
fileExistsAtPath: fileName2x]) {
fileName2x = findScaledImageName(fileName, dotIndex, @"@200pct");
}
if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
fileExistsAtPath: fileName2x])){
if (jar || [[NSFileManager defaultManager]
fileExistsAtPath: fileName2x]){
if (strlen([fileName2x UTF8String]) > scaledImageLength) {
[pool drain];
return JNI_FALSE;
@ -458,3 +458,16 @@ SplashReconfigure(Splash * splash) {
sendctl(splash, SPLASHCTL_RECONFIGURE);
}
NSString* findScaledImageName(NSString *fileName, NSUInteger dotIndex, NSString *strToAppend) {
NSString *fileName2x = nil;
if (dotIndex == NSNotFound) {
fileName2x = [fileName stringByAppendingString: strToAppend];
} else {
fileName2x = [fileName substringToIndex: dotIndex];
fileName2x = [fileName2x stringByAppendingString: strToAppend];
fileName2x = [fileName2x stringByAppendingString:
[fileName substringFromIndex: dotIndex]];
}
return fileName2x;
}

View File

@ -65,6 +65,16 @@ import sun.awt.image.SunWritableRaster;
* <PRE>
* java -splash:filename.gif Test
* </PRE>
* HiDPI scaled image is also supported.
* Unscaled image name i.e. filename.gif should be passed in
* {@code manifest.mf}/{@code -splash:} option for all image types irrespective of
* HiDPI and Non-HiDPI.
* Following is the naming convention for scaled images.
* Screen scale 1.25: filename@125pct.gif
* Screen scale 1.50: filename@150pct.gif
* Screen scale 2: filename@200pct.gif and filename@2x.gif both are supported
* Screen scale 2.50: filename@250pct.gif
* Screen scale 3: filename@300pct.gif and filename@3x.gif both are supported
* The command line interface has higher precedence over the manifest
* setting.
* <p>

View File

@ -25,7 +25,12 @@
#include "splashscreen_impl.h"
#include "splashscreen_gfx_impl.h"
#define BUFF_SIZE 1024
#ifdef _MSC_VER
# ifndef snprintf
# define snprintf _snprintf
# endif
#endif
int splashIsVisible = 0;
Splash *
@ -392,5 +397,101 @@ int SplashStreamInitMemory(SplashStream * pStream, void* pData, int size) {
SPLASHEXPORT int
SplashGetScaledImgNameMaxPstfixLen(const char *fileName){
return strlen(fileName) + strlen(".java-scale-200") + 1;
return strlen(fileName) + strlen("@100pct") + 1;
}
jboolean GetScaledImageName(const char *fileName, char *scaleImageName,
float *scaleFactor, const size_t scaledImageLength) {
if (*scaleFactor > 1.0) {
FILE *fp = NULL;
char scaledImgPct[BUFF_SIZE];
char scaledImgX[BUFF_SIZE];
char *scaledImageXName = NULL;
char *scaledImagePctName = malloc(scaledImageLength);
char *dupFileName = strdup(fileName);
char *fileExtension = strrchr(dupFileName, '.');
size_t lengthPct = 0;
size_t lengthX = 0;
int retValPct = 0;
int retValX = 0;
jboolean isPctScaledImage = (*scaleFactor * 100) != ((int) (*scaleFactor)) *100;
snprintf(scaledImgPct, BUFF_SIZE, "%s%d%s", "@",
(int) (*scaleFactor * 100), "pct");
if (!isPctScaledImage) {
scaledImageXName = malloc(scaledImageLength);
snprintf(scaledImgX, BUFF_SIZE, "%s%d%s", "@", (int) (*scaleFactor), "x");
}
/*File is missing extension */
if (fileExtension == NULL) {
lengthPct = strlen(dupFileName) +
strlen(scaledImgPct) + 1;
if (!isPctScaledImage) {
lengthX = strlen(dupFileName) +
strlen(scaledImgX) + 1;
}
if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
return JNI_FALSE;
}
retValPct = snprintf(scaledImagePctName, lengthPct, "%s%s", dupFileName,
scaledImgPct);
if (!isPctScaledImage) {
retValX = snprintf(scaledImageXName, lengthX, "%s%s", dupFileName,
scaledImgX);
}
if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
(retValX < 0 || (retValX > lengthX - 1))) {
cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
return JNI_FALSE;
}
} else {
int length_Without_Ext = fileExtension - dupFileName;
lengthPct = length_Without_Ext + strlen(scaledImgPct) +
strlen(fileExtension) + 1;
if (!isPctScaledImage) {
lengthX = length_Without_Ext + strlen(scaledImgX) +
strlen(fileExtension) + 1;
}
if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
return JNI_FALSE;
}
retValPct = snprintf(scaledImagePctName, lengthPct, "%.*s%s%s",
length_Without_Ext, dupFileName, scaledImgPct, fileExtension);
if (!isPctScaledImage) {
retValX = snprintf(scaledImageXName, lengthX, "%.*s%s%s",
length_Without_Ext, dupFileName, scaledImgX, fileExtension);
}
if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
(retValX < 0 || (retValX > lengthX - 1))) {
cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
return JNI_FALSE;
}
}
free(dupFileName);
if (!(fp = fopen(scaledImagePctName, "r"))) {
if (!isPctScaledImage && (fp = fopen(scaledImageXName, "r"))) {
fclose(fp);
strcpy(scaleImageName, scaledImageXName);
free(scaledImageXName);
free(scaledImagePctName);
return JNI_TRUE;
}
cleanUp(NULL, scaledImageXName, scaledImagePctName, scaleFactor);
return JNI_FALSE;
}
fclose(fp);
strcpy(scaleImageName, scaledImagePctName);
free(scaledImageXName);
free(scaledImagePctName);
return JNI_TRUE;
}
return JNI_FALSE;
}
void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor) {
*scaleFactor = 1;
free(fName);
free(xName);
free(pctName);
}

View File

@ -150,7 +150,9 @@ void SplashUpdateScreenData(Splash * splash);
void SplashCleanup(Splash * splash);
void SplashSetScaleFactor(float scaleFactor);
int SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor);
jboolean GetScaledImageName(const char *fileName, char *scaledImgName,
float *scaleFactor, const size_t scaledImageLength);
typedef struct SplashStream {
int (*read)(void* pStream, void* pData, int nBytes);
int (*peek)(void* pStream);

View File

@ -753,6 +753,9 @@ SplashScreenThread(void *param) {
XMapRaised(splash->display, splash->window);
SplashUpdateShape(splash);
SplashRedrawWindow(splash);
//map the splash co-ordinates as per system scale
splash->x /= splash->scaleFactor;
splash->y /= splash->scaleFactor;
SplashEventLoop(splash);
}
SplashUnlock(splash);
@ -807,50 +810,6 @@ SplashGetScaledImageName(const char* jarName, const char* fileName,
return JNI_FALSE;
#endif
*scaleFactor = getNativeScaleFactor(NULL);
if (*scaleFactor == 2.0) {
size_t length = 0;
char *stringToAppend = ".java-scale2x";
char *dupFileName = strdup(fileName);
char *fileExtension = strrchr(dupFileName, '.');
if (fileExtension == NULL) {
length = strlen(dupFileName) + strlen(stringToAppend) + 1;
if (length > scaledImageNameLength) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
int retVal = snprintf(scaledImgName, length, "%s%s",
dupFileName, stringToAppend);
if (retVal < 0 || (retVal != length - 1)) {
free(dupFileName);
*scaleFactor = 1;
return JNI_FALSE;
}
} else {
int length_without_ext = fileExtension - dupFileName;
length = length_without_ext +
strlen(stringToAppend) + strlen(fileExtension) + 1;
if (length > scaledImageNameLength) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
int retVal = snprintf(scaledImgName, length, "%.*s%s%s",
length_without_ext, dupFileName, stringToAppend, fileExtension);
if (retVal < 0 || retVal != length - 1) {
free(dupFileName);
*scaleFactor = 1;
return JNI_FALSE;
}
}
free(dupFileName);
FILE *fp;
if (!(fp = fopen(scaledImgName, "r"))) {
*scaleFactor = 1;
return JNI_FALSE;
}
fclose(fp);
return JNI_TRUE;
}
return JNI_FALSE;
return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
}

View File

@ -535,6 +535,9 @@ SplashScreenThread(LPVOID param)
splash->hWnd = SplashCreateWindow(splash);
if (splash->hWnd) {
SplashRedrawWindow(splash);
//map the splash co-ordinates as per system scale
splash->x /= splash->scaleFactor;
splash->y /= splash->scaleFactor;
SplashUnlock(splash);
SplashMessagePump();
SplashLock(splash);
@ -582,55 +585,7 @@ SplashGetScaledImageName(const char* jarName, const char* fileName,
*scaleFactor = 1.0;
GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY);
*scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor;
if (*scaleFactor > 1.0) {
char strDpi[BUFF_SIZE];
char *dupFileName = strdup(fileName);
char *fileExtension = strrchr(dupFileName, '.');
char *nameToAppend = ".scale-";
size_t length = 0;
int retVal = 0;
_snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX);
/*File is missing extension */
if (fileExtension == NULL) {
length = strlen(dupFileName) + strlen(nameToAppend) +
strlen(strDpi) + 1;
if (length > scaledImageLength) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName,
nameToAppend, strDpi);
if (retVal < 0 || (retVal != length - 1)) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
}
else {
size_t length_Without_Ext = fileExtension - dupFileName;
length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) +
strlen(fileExtension) + 1;
if (length > scaledImageLength) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s",
length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension);
if (retVal < 0 || (retVal != length - 1)) {
*scaleFactor = 1;
free(dupFileName);
return JNI_FALSE;
}
}
free(dupFileName);
if (!(fp = fopen(scaleImageName, "r"))) {
*scaleFactor = 1;
return JNI_FALSE;
}
fclose(fp);
return JNI_TRUE;
}
return JNI_FALSE;
return GetScaledImageName(fileName, scaleImageName,
scaleFactor, scaledImageLength);
}

View File

@ -43,7 +43,7 @@ import sun.java2d.SunGraphics2D;
/**
* @test
* @key headful
* @bug 8043869 8075244 8078082 8145173
* @bug 8043869 8075244 8078082 8145173 8151787
* @summary Tests the HiDPI splash screen support for windows and MAC
* @modules java.desktop/sun.java2d
* @run main MultiResolutionSplashTest GENERATE_IMAGES
@ -56,27 +56,20 @@ public class MultiResolutionSplashTest {
private static final int IMAGE_WIDTH = 300;
private static final int IMAGE_HEIGHT = 200;
private static boolean isMac;
private static final ImageInfo[] macTests = {
static {
isMac = System.getProperty("os.name").contains("OS X");
}
private static final ImageInfo[] tests = {
new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
};
private static final ImageInfo[] windowsTests = {
new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED)
};
private static ImageInfo[] tests;
public static void main(String[] args) throws Exception {
String test = args[0];
tests = windowsTests;
String osName = System.getProperty("os.name");
if (osName.contains("OS X")) {
tests = macTests;
}
switch (test) {
case "GENERATE_IMAGES":
generateImages();
@ -104,12 +97,10 @@ public class MultiResolutionSplashTest {
Rectangle splashBounds = splashScreen.getBounds();
int screenX = (int) splashBounds.getCenterX();
int screenY = (int) splashBounds.getCenterY();
if (splashBounds.width != IMAGE_WIDTH) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong width");
}
if (splashBounds.height != IMAGE_HEIGHT) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong height");
@ -117,7 +108,6 @@ public class MultiResolutionSplashTest {
Robot robot = new Robot();
Color splashScreenColor = robot.getPixelColor(screenX, screenY);
float scaleFactor = getScaleFactor();
Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
@ -129,7 +119,6 @@ public class MultiResolutionSplashTest {
static void testFocus() throws Exception {
System.out.println("Focus Test!");
Robot robot = new Robot();
robot.setAutoDelay(50);
@ -150,18 +139,18 @@ public class MultiResolutionSplashTest {
frame.dispose();
if(!textField.getText().equals("ab")){
if (!textField.getText().equals("ab")) {
throw new RuntimeException("Focus is lost!");
}
}
static boolean compare(Color c1, Color c2){
static boolean compare(Color c1, Color c2) {
return compare(c1.getRed(), c2.getRed())
&& compare(c1.getGreen(), c2.getGreen())
&& compare(c1.getBlue(), c2.getBlue());
}
static boolean compare(int n, int m){
static boolean compare(int n, int m) {
return Math.abs(n - m) <= 50;
}
@ -177,10 +166,7 @@ public class MultiResolutionSplashTest {
public void paint(Graphics g) {
float scaleFactor = 1;
if (g instanceof SunGraphics2D) {
scaleFactor = (float)GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().
getDefaultTransform().getScaleX();
scaleFactor = getScreenScaleFactor();
}
scaleFactors[0] = scaleFactor;
dialog.setVisible(false);
@ -197,23 +183,30 @@ public class MultiResolutionSplashTest {
static void generateImages() throws Exception {
for (ImageInfo test : tests) {
generateImage(test.name1x, test.color1x, 1);
generateImage(test.name2x, test.color2x, 2);
generateImage(test.name2x, test.color2x, getScreenScaleFactor());
}
}
static void generateImage(String name, Color color, int scale) throws Exception {
static void generateImage(String name, Color color, float scale) throws Exception {
File file = new File(name);
if (file.exists()) {
return;
}
BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
BufferedImage.TYPE_INT_RGB);
BufferedImage image = new BufferedImage((int) (scale * IMAGE_WIDTH),
(int) (scale * IMAGE_HEIGHT), BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(color);
g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
g.fillRect(0, 0, (int) (scale * IMAGE_WIDTH), (int) (scale * IMAGE_HEIGHT));
ImageIO.write(image, "png", file);
}
static float getScreenScaleFactor() {
return (float) GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().
getDefaultTransform().getScaleX();
}
static class ImageInfo {
final String name1x;
@ -223,9 +216,32 @@ public class MultiResolutionSplashTest {
public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) {
this.name1x = name1x;
this.name2x = name2x;
if (!isMac) {
float scale = getScreenScaleFactor();
StringBuffer buff = new StringBuffer();
if (scale - (int) scale > 0) {
buff.append("@").append((int) (scale * 100)).append("pct");
} else {
buff.append("@").append((int) scale).append("x");
}
StringBuffer buffer = new StringBuffer();
String[] splitStr = name1x.split("\\.");
if (splitStr.length == 2) {
this.name2x = buffer.append(splitStr[0]).append(buff)
.append(".").append(splitStr[1]).toString();
} else {
if (name1x.indexOf(".") > 0) {
this.name2x = buffer.append(splitStr[0]).append(buff).append(".").toString();
} else {
this.name2x = buffer.append(splitStr[0]).append(buff).toString();
}
}
} else {
this.name2x = name2x;
}
this.color1x = color1x;
this.color2x = color2x;
}
}
}

View File

@ -44,7 +44,7 @@ import java.util.Map;
import javax.imageio.ImageIO;
/**
* @test @bug 8145174
* @test @bug 8145174 8151787
* @summary HiDPI splash screen support on Linux
* @modules java.desktop/sun.java2d
* @run main UnixMultiResolutionSplashTest
@ -55,9 +55,9 @@ public class UnixMultiResolutionSplashTest {
private static final int IMAGE_HEIGHT = 200;
private static int inx = 0;
private static final ImageInfo[] tests = {
new ImageInfo("splash1.png", "splash1.java-scale2x.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2.java-scale2x", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3.java-scale2x.", Color.YELLOW, Color.RED)
new ImageInfo("splash1.png", "splash1@200pct.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3@200pct.", Color.YELLOW, Color.RED)
};
public static void main(String[] args) throws Exception {
@ -96,8 +96,6 @@ public class UnixMultiResolutionSplashTest {
Rectangle splashBounds = splashScreen.getBounds();
int screenX = (int) splashBounds.getCenterX();
int screenY = (int) splashBounds.getCenterY();
System.out.println(screenX);
System.out.println(screenY);
Robot robot = new Robot();
Color splashScreenColor = robot.getPixelColor(screenX, screenY);