1 /*
   2  * Copyright (c) 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 import java.awt.Color;
  24 import java.awt.Graphics;
  25 import java.awt.Graphics2D;
  26 import java.awt.Image;
  27 import java.awt.Toolkit;
  28 import java.awt.image.BufferedImage;
  29 import java.awt.image.ImageObserver;
  30 import static java.awt.image.ImageObserver.*;
  31 import java.io.File;
  32 import javax.imageio.ImageIO;
  33 /*
  34  * @test
  35  * @bug 8065627
  36  * @summary Animated GIFs fail to display on a HiDPI display
  37  * @author Alexander Scherbatiy
  38  * @run main MultiResolutionImageObserverTest
  39  */
  40 
  41 public class MultiResolutionImageObserverTest {
  42 
  43     private static final int TIMEOUT = 500;
  44 
  45     public static void main(String[] args) throws Exception {
  46 
  47         generateImages();
  48         Toolkit toolkit = Toolkit.getDefaultToolkit();
  49         Image image = Toolkit.getDefaultToolkit().getImage(IMAGE_NAME_1X);
  50 
  51         LoadImageObserver sizeObserver
  52                 = new LoadImageObserver(WIDTH | HEIGHT);
  53         toolkit.prepareImage(image, -1, -1, sizeObserver);
  54         waitForImageLoading(sizeObserver, "The first observer is not called");
  55 
  56         LoadImageObserver bitsObserver
  57                 = new LoadImageObserver(SOMEBITS | FRAMEBITS | ALLBITS);
  58 
  59         BufferedImage buffImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
  60         Graphics2D g2d = (Graphics2D) buffImage.createGraphics();
  61         g2d.scale(2, 2);
  62         g2d.drawImage(image, 0, 0, bitsObserver);
  63         waitForImageLoading(bitsObserver, "The second observer is not called!");
  64         g2d.dispose();
  65     }
  66 
  67     private static void waitForImageLoading(LoadImageObserver observer,
  68             String errorMessage) throws Exception {
  69 
  70         long endTime = System.currentTimeMillis() + TIMEOUT;
  71 
  72         while (!observer.loaded && System.currentTimeMillis() < endTime) {
  73             Thread.sleep(TIMEOUT / 10);
  74         }
  75 
  76         if (!observer.loaded) {
  77             throw new RuntimeException(errorMessage);
  78         }
  79     }
  80 
  81     private static final String IMAGE_NAME_1X = "image.png";
  82     private static final String IMAGE_NAME_2X = "image@2x.png";
  83 
  84     private static void generateImages() throws Exception {
  85         generateImage(1);
  86         generateImage(2);
  87     }
  88 
  89     private static void generateImage(int scale) throws Exception {
  90         BufferedImage image = new BufferedImage(
  91                 scale * 200, scale * 300,
  92                 BufferedImage.TYPE_INT_RGB);
  93         Graphics g = image.createGraphics();
  94         g.setColor(scale == 1 ? Color.GREEN : Color.BLUE);
  95         g.fillRect(0, 0, scale * 200, scale * 300);
  96         File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X);
  97         ImageIO.write(image, "png", file);
  98         g.dispose();
  99     }
 100 
 101     private static class LoadImageObserver implements ImageObserver {
 102 
 103         private final int infoflags;
 104         private boolean loaded;
 105 
 106         public LoadImageObserver(int flags) {
 107             this.infoflags = flags;
 108         }
 109 
 110         @Override
 111         public boolean imageUpdate(Image img, int flags, int x, int y, int width, int height) {
 112 
 113             if ((flags & infoflags) != 0) {
 114                 loaded = true;
 115             }
 116 
 117             return !loaded;
 118         }
 119     }
 120 }