diff --git a/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java b/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java index 8473fdee764..4d3e04425f6 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java @@ -25,10 +25,12 @@ package sun.awt; import java.awt.*; import java.awt.color.*; +import java.awt.geom.AffineTransform; import java.awt.image.*; import sun.awt.image.ToolkitImage; import sun.awt.image.ImageRepresentation; import java.util.Arrays; +import sun.java2d.pipe.Region; public class IconInfo { /** @@ -101,7 +103,7 @@ public class IconInfo { } this.scaledWidth = width; this.scaledHeight = height; - this.rawLength = width * height + 2; + this.rawLength = getScaledRawLength(); } /* @@ -110,7 +112,27 @@ public class IconInfo { public void setScaledSize(int width, int height) { this.scaledWidth = width; this.scaledHeight = height; - this.rawLength = width * height + 2; + this.rawLength = getScaledRawLength(); + } + + /* + * returns scaled raw length. + */ + private int getScaledRawLength() { + int scaledWidthAndHeight[] = getScaledWidthAndHeight(width, height); + return scaledWidthAndHeight[0] * scaledWidthAndHeight[1] + 2; + } + + /* + * returns the scaled width and height. + */ + private static int[] getScaledWidthAndHeight(int width, int height) { + AffineTransform tx = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(). + getDefaultTransform(); + int w = Region.clipScale(width, tx.getScaleX()); + int h = Region.clipScale(height, tx.getScaleY()); + return new int[]{w, h}; } public boolean isValid() { @@ -215,6 +237,9 @@ public class IconInfo { new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, false, DataBuffer.TYPE_INT); + int scaledWidthAndHeight[] = getScaledWidthAndHeight(width, height); + width = scaledWidthAndHeight[0]; + height = scaledWidthAndHeight[1]; DataBufferInt buffer = new DataBufferInt(width * height); WritableRaster raster = Raster.createPackedRaster(buffer, width, height, diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/IconTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/IconTest.java new file mode 100644 index 00000000000..985041f6a1c --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/IconTest.java @@ -0,0 +1,163 @@ +/** + * Copyright (c) 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 + * 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. + */ + +/** + * @test + * @bug 8147648 + * @summary [hidpi] multiresolution image: wrong resolution variant is used as + * icon in the Unity panel + * @run main/othervm -Dsun.java2d.uiScale=2 IconTest + */ +import java.awt.Color; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import java.util.concurrent.CountDownLatch; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +public class IconTest { + + private final static int SZ = 8; + private static GridBagLayout layout; + private static JPanel mainControlPanel; + private static JPanel resultButtonPanel; + private static JLabel instructionText; + private static JButton passButton; + private static JButton failButton; + private static JButton testButton; + private static JFrame f; + private static CountDownLatch latch; + + private static BufferedImage generateImage(int scale, Color c) { + int x = SZ * scale; + BufferedImage img = new BufferedImage(x, x, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + try { + if (g != null) { + g.setColor(c); + g.fillRect(0, 0, x, x); + g.setColor(Color.YELLOW); + g.drawRect(0, 0, x-1, x-1); + } + } finally { + g.dispose(); + } + return img; + } + + + private static void createUI() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + f = new JFrame("TrayIcon Test"); + + final BaseMultiResolutionImage IMG = new BaseMultiResolutionImage( + new BufferedImage[]{generateImage(1, Color.RED), generateImage(2, Color.BLUE)}); + layout = new GridBagLayout(); + mainControlPanel = new JPanel(layout); + resultButtonPanel = new JPanel(layout); + f.setIconImage(IMG); + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = "INSTRUCTIONS:
" + + "Check if test button and unity icons are both blue with yellow border.

" + + "If Icon color is blue press pass" + + " else press fail.

"; + + instructionText = new JLabel(); + instructionText.setText(instructions); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionText, gbc); + testButton = new JButton("Test"); + testButton.setActionCommand("Test"); + mainControlPanel.add(testButton, gbc); + + testButton.setIcon(new ImageIcon(IMG)); + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(testButton, gbc); + + passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener((ActionEvent e) -> { + latch.countDown(); + f.dispose(); + }); + failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + latch.countDown(); + f.dispose(); + throw new RuntimeException("Test Failed"); + } + }); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 2; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(resultButtonPanel, gbc); + + f.add(mainControlPanel); + f.setSize(400, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + + f.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + latch.countDown(); + f.dispose(); + } + }); + } + }); + } + + public static void main(String[] args) throws Exception { + latch = new CountDownLatch(1); + createUI(); + latch.await(); + } +} +