/* * Copyright (c) 2007, 2022, 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 * @key headful * @bug 5009033 6603000 6666362 8159142 8198613 * @summary Verifies that images transformed with bilinear filtering do not * leave artifacts at the edges. * @run main/othervm -Dsun.java2d.uiScale=2.5 DrawImageBilinear * @run main/othervm -Dsun.java2d.uiScale=2.5 -Dsun.java2d.d3d=false DrawImageBilinear */ import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.awt.image.VolatileImage; public class DrawImageBilinear extends Canvas { private static final int SIZE = 5; private static boolean done; private BufferedImage bimg1, bimg2; private VolatileImage vimg; private static BufferedImage capture; private static DrawImageBilinear test; private static Frame frame; private void renderPattern(Graphics g) { g.setColor(Color.red); g.fillRect(0, 0, SIZE, SIZE); g.dispose(); } public void paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; if (bimg1 == null) { bimg1 = (BufferedImage)createImage(SIZE, SIZE); bimg1.setAccelerationPriority(0.0f); renderPattern(bimg1.createGraphics()); bimg2 = (BufferedImage)createImage(SIZE, SIZE); renderPattern(bimg2.createGraphics()); vimg = createVolatileImage(SIZE, SIZE); vimg.validate(getGraphicsConfiguration()); renderPattern(vimg.createGraphics()); } do { g2d.setColor(Color.white); g2d.fillRect(0, 0, getWidth(), getHeight()); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // first time will be a sw->surface blit g2d.drawImage(bimg1, 10, 10, 40, 40, null); // second time will be a texture->surface blit g2d.drawImage(bimg2, 80, 10, 40, 40, null); g2d.drawImage(bimg2, 80, 10, 40, 40, null); // third time will be a pbuffer->surface blit if (vimg.validate(getGraphicsConfiguration()) != VolatileImage.IMAGE_OK) { renderPattern(vimg.createGraphics()); } g2d.drawImage(vimg, 150, 10, 40, 40, null); Toolkit.getDefaultToolkit().sync(); } while (vimg.contentsLost()); } public Dimension getPreferredSize() { return new Dimension(200, 100); } private static void testRegion(BufferedImage bi, Rectangle affectedRegion) { int x1 = affectedRegion.x; int y1 = affectedRegion.y; int x2 = x1 + affectedRegion.width; int y2 = y1 + affectedRegion.height; for (int y = y1; y < y2; y++) { for (int x = x1; x < x2; x++) { int actual = bi.getRGB(x, y); if ((actual != 0xfffe0000) && (actual != 0xffff0000)) { throw new RuntimeException("Test failed at x="+x+" y="+y+ " (expected=0xffff0000"+ " actual=0x"+ Integer.toHexString(actual) + ")"); } } } } private static void createAndShowGUI() { test = new DrawImageBilinear(); frame = new Frame(); frame.add(test); frame.setUndecorated(true); frame.setAlwaysOnTop(true); frame.setLocationRelativeTo(null); frame.pack(); frame.setVisible(true); } public static void main(String[] args) throws Exception { try { EventQueue.invokeAndWait(() -> createAndShowGUI()); GraphicsConfiguration gc = frame.getGraphicsConfiguration(); if (gc.getColorModel() instanceof IndexColorModel) { System.out.println("IndexColorModel detected: " + "test considered PASSED"); return; } Robot robot = new Robot(); robot.setAutoDelay(100); robot.mouseMove(0,0); robot.waitForIdle(); Point pt1 = frame.getLocationOnScreen(); Rectangle rect = new Rectangle(pt1.x, pt1.y, frame.getWidth(), frame.getHeight()); capture = robot.createScreenCapture(rect); robot.waitForIdle(); if (capture == null) { throw new RuntimeException("Failed: capture is null"); } // Test background color int pixel = capture.getRGB(5, 5); if (pixel != 0xffffffff) { throw new RuntimeException("Failed: Incorrect color for " + "background"); } // Test pixels testRegion(capture, new Rectangle(10, 10, 40, 40)); testRegion(capture, new Rectangle(80, 10, 40, 40)); testRegion(capture, new Rectangle(150, 10, 40, 40)); } finally { if (frame != null) { frame.dispose(); } } } }