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 
  52     public static void main(String[] args) throws Exception {
  53         testCustomMultiResolutionImage();
  54         System.out.println("Test passed.");
  55     }
  56 
  57     public static void testCustomMultiResolutionImage() {
  58         testCustomMultiResolutionImage(false);
  59         testCustomMultiResolutionImage(true);
  60     }
  61 
  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 
 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 
 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
 178         public Image getResolutionVariant(
 179                 double destImageWidth, double destImageHeight) {
 180             return ((destImageWidth <= getWidth() && destImageHeight <= getHeight()))
 181                     ? this : highResolutionImage;
 182         }
 183 
 184         @Override
 185         public List<Image> getResolutionVariants() {
 186             return Arrays.asList(this, highResolutionImage);
 187         }
 188     }
 189 
 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 
 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 }