1 /*
2  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.awt.Color;
25 import java.awt.Graphics;
26 import java.awt.Graphics2D;
27 import java.awt.Image;
28 import java.awt.RenderingHints;
29 import java.awt.image.BufferedImage;
30 import sun.awt.SunHints;
31 import java.awt.geom.AffineTransform;
32 import java.util.Arrays;
33 import java.util.List;
34 import java.awt.image.MultiResolutionImage;
35 
36 /**
37  * @test
38  * @bug 8011059
39  * @author Alexander Scherbatiy
40  * @summary Test MultiResolution image loading and painting with various scaling
41  *          combinations
42  * @modules java.desktop/sun.awt
43  *          java.desktop/sun.awt.image
44  */
45 public class MultiResolutionImageCommonTest {
46 
47     private static final int IMAGE_WIDTH = 300;
48     private static final int IMAGE_HEIGHT = 200;
49     private static final Color COLOR_1X = Color.GREEN;
50     private static final Color COLOR_2X = Color.BLUE;
51 
main(String[] args)52     public static void main(String[] args) throws Exception {
53         testCustomMultiResolutionImage();
54         System.out.println("Test passed.");
55     }
56 
testCustomMultiResolutionImage()57     public static void testCustomMultiResolutionImage() {
58         testCustomMultiResolutionImage(false);
59         testCustomMultiResolutionImage(true);
60     }
61 
testCustomMultiResolutionImage( boolean enableImageScaling)62     public static void testCustomMultiResolutionImage(
63             boolean enableImageScaling) {
64 
65         Image image = new MultiResolutionBufferedImage();
66 
67         // Same image size
68         BufferedImage bufferedImage = new BufferedImage(
69                 IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
70         Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
71         setImageScalingHint(g2d, enableImageScaling);
72         g2d.drawImage(image, 0, 0, null);
73         checkColor(bufferedImage.getRGB(
74                 3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
75 
76         // Twice image size
77         bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT,
78                 BufferedImage.TYPE_INT_RGB);
79         g2d = (Graphics2D) bufferedImage.getGraphics();
80         setImageScalingHint(g2d, enableImageScaling);
81         g2d.drawImage(image, 0, 0, 2 * IMAGE_WIDTH,
82                 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
83         checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2,
84                 3 * IMAGE_HEIGHT / 2), enableImageScaling);
85 
86         // Scale 2x
87         bufferedImage = new BufferedImage(
88                 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
89         g2d = (Graphics2D) bufferedImage.getGraphics();
90         setImageScalingHint(g2d, enableImageScaling);
91         g2d.scale(2, 2);
92         g2d.drawImage(image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
93         checkColor(bufferedImage.getRGB(
94                 3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
95 
96         // Rotate
97         bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
98                 BufferedImage.TYPE_INT_RGB);
99         g2d = (Graphics2D) bufferedImage.getGraphics();
100         setImageScalingHint(g2d, enableImageScaling);
101         g2d.drawImage(image, 0, 0, null);
102         g2d.rotate(Math.PI / 4);
103         checkColor(bufferedImage.getRGB(
104                 3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
105 
106         // Scale 2x and Rotate
107         bufferedImage = new BufferedImage(
108                 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
109         g2d = (Graphics2D) bufferedImage.getGraphics();
110         setImageScalingHint(g2d, enableImageScaling);
111         g2d.scale(-2, 2);
112         g2d.rotate(-Math.PI / 10);
113         g2d.drawImage(image, -IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
114         checkColor(bufferedImage.getRGB(
115                 3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
116 
117         // General Transform
118         bufferedImage = new BufferedImage(
119                 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
120         g2d = (Graphics2D) bufferedImage.getGraphics();
121         setImageScalingHint(g2d, enableImageScaling);
122         float delta = 0.05f;
123         float cos = 1 - delta * delta / 2;
124         float sin = 1 + delta;
125         AffineTransform transform
126                 = new AffineTransform(2 * cos, 0.1, 0.3, -2 * sin, 10, -5);
127         g2d.setTransform(transform);
128         g2d.drawImage(image, 0, -IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, null);
129         checkColor(bufferedImage.getRGB(
130                 3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
131 
132         int D = 10;
133         // From Source to small Destination region
134         bufferedImage = new BufferedImage(
135                 IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
136         g2d = (Graphics2D) bufferedImage.getGraphics();
137         setImageScalingHint(g2d, enableImageScaling);
138         g2d.drawImage(image, IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2,
139                 IMAGE_WIDTH - D, IMAGE_HEIGHT - D,
140                 D, D, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null);
141         checkColor(bufferedImage.getRGB(
142                 3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
143 
144         // From Source to large Destination region
145         bufferedImage = new BufferedImage(
146                 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
147         g2d = (Graphics2D) bufferedImage.getGraphics();
148         setImageScalingHint(g2d, enableImageScaling);
149         g2d.drawImage(image, D, D, 2 * IMAGE_WIDTH - D, 2 * IMAGE_HEIGHT - D,
150                 IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2,
151                 IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null);
152         checkColor(bufferedImage.getRGB(
153                 3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
154     }
155 
156     static class MultiResolutionBufferedImage extends BufferedImage
157             implements MultiResolutionImage {
158 
159         Image highResolutionImage;
160 
MultiResolutionBufferedImage()161         public MultiResolutionBufferedImage() {
162             super(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
163             highResolutionImage = new BufferedImage(
164                     2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT,
165                     BufferedImage.TYPE_INT_RGB);
166             draw(getGraphics(), 1);
167             draw(highResolutionImage.getGraphics(), 2);
168         }
169 
draw(Graphics graphics, float resolution)170         final void draw(Graphics graphics, float resolution) {
171             Graphics2D g2 = (Graphics2D) graphics;
172             g2.scale(resolution, resolution);
173             g2.setColor((resolution == 1) ? COLOR_1X : COLOR_2X);
174             g2.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
175         }
176 
177         @Override
getResolutionVariant( double destImageWidth, double destImageHeight)178         public Image getResolutionVariant(
179                 double destImageWidth, double destImageHeight) {
180             return ((destImageWidth <= getWidth() && destImageHeight <= getHeight()))
181                     ? this : highResolutionImage;
182         }
183 
184         @Override
getResolutionVariants()185         public List<Image> getResolutionVariants() {
186             return Arrays.asList(this, highResolutionImage);
187         }
188     }
189 
setImageScalingHint( Graphics2D g2d, boolean enableImageScaling)190     static void setImageScalingHint(
191             Graphics2D g2d, boolean enableImageScaling) {
192         g2d.setRenderingHint(SunHints.KEY_RESOLUTION_VARIANT, enableImageScaling
193                 ? RenderingHints.VALUE_RESOLUTION_VARIANT_DEFAULT
194                 : RenderingHints.VALUE_RESOLUTION_VARIANT_BASE);
195     }
196 
checkColor(int rgb, boolean isImageScaled)197     static void checkColor(int rgb, boolean isImageScaled) {
198 
199         if (!isImageScaled && COLOR_1X.getRGB() != rgb) {
200             throw new RuntimeException("Wrong 1x color: " + new Color(rgb));
201         }
202 
203         if (isImageScaled && COLOR_2X.getRGB() != rgb) {
204             throw new RuntimeException("Wrong 2x color" + new Color(rgb));
205         }
206     }
207 
208 }
209