Path: blob/master/test/jdk/java/awt/BasicStroke/DashOffset.java
41149 views
/*1* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.awt.BasicStroke;24import java.awt.Color;25import java.awt.Graphics;26import java.awt.Graphics2D;27import java.awt.GraphicsConfiguration;28import java.awt.GraphicsEnvironment;29import java.awt.Image;30import java.awt.image.BufferedImage;31import java.awt.image.IndexColorModel;32import java.awt.image.VolatileImage;33import java.io.File;34import java.io.IOException;35import java.util.Arrays;36import java.util.stream.Collectors;37import javax.imageio.ImageIO;3839import static java.awt.image.BufferedImage.TYPE_INT_RGB;4041/*42* @test43* @bug 4469881 8217263 821868244* @key headful45* @summary Verifies that dashed rectangles drawn to the screen line46* up with their undashed counterparts47* @author flar48* @run main/othervm -Dsun.java2d.uiScale=1 DashOffset49*/50public class DashOffset {5152private static final BasicStroke dash =53new BasicStroke(1.0f, BasicStroke.CAP_BUTT,54BasicStroke.JOIN_MITER, 10.0f,55new float[] {2.0f, 2.0f}, 0.0f);5657private static final Color COLOR1 = Color.BLUE;58private static final Color COLOR2 = Color.GREEN;5960private static final Color BACKGROUND = Color.WHITE;6162private static final int WIDTH = 20;63private static final int HEIGHT = 20;6465private static final int OFFSET = 2;6667private static final int MAX_DASH_LENGTH = 3;6869public static void main(String[] argv) throws Exception {70final boolean saveImage = argv.length > 0 && "-save".equals(argv[0]);7172final BufferedImage img = new BufferedImage(WIDTH, HEIGHT,73TYPE_INT_RGB);74try {75draw(img);76validate(img);77} finally {78if (saveImage) {79save(img, "bufferedImage.png");80}81}8283BufferedImage snapshot = null;84try {85final GraphicsConfiguration gc =86GraphicsEnvironment.getLocalGraphicsEnvironment()87.getDefaultScreenDevice()88.getDefaultConfiguration();89if (gc.getColorModel() instanceof IndexColorModel) {90System.err.println("Skipping VolatileImage because of IndexColorModel");91return;92}9394VolatileImage vi = gc.createCompatibleVolatileImage(WIDTH, HEIGHT);95int attempt = 0;96do {97vi.validate(gc);98draw(vi);99snapshot = vi.getSnapshot();100} while (vi.contentsLost() && ++attempt <= 10);101if (attempt > 10) {102throw new RuntimeException("Too many attempts: " + attempt);103}104validate(snapshot);105} finally {106if (saveImage && snapshot != null) {107save(snapshot, "volatileImage.png");108}109}110}111112private static void draw(final Image img) {113Graphics g = img.getGraphics();114g.setColor(BACKGROUND);115g.fillRect(0, 0, WIDTH, HEIGHT);116g.setColor(COLOR1);117g.drawRect(OFFSET, OFFSET, WIDTH - OFFSET * 2, HEIGHT - OFFSET * 2);118g.setColor(COLOR2);119g.clipRect(OFFSET, OFFSET, WIDTH - OFFSET * 2 + 1, HEIGHT - OFFSET * 2 + 1);120((Graphics2D) g).setStroke(dash);121g.drawRect(OFFSET, OFFSET, WIDTH - OFFSET * 2, HEIGHT - OFFSET * 2);122g.dispose();123}124125private static void validate(final BufferedImage img) {126checkHorizontalLine(img, OFFSET);127checkHorizontalLine(img, HEIGHT - OFFSET);128checkVerticalLine(img, OFFSET);129checkVerticalLine(img, WIDTH - OFFSET);130checkCorners(img);131}132133private static void checkHorizontalLine(final BufferedImage img,134final int y) {135int prev = img.getRGB(OFFSET, y);136int curr;137int count = 1;138checkColor(OFFSET, y, prev, COLOR1, COLOR2);139for (int x = OFFSET + 1; x <= WIDTH - OFFSET; x++) {140curr = img.getRGB(x, y);141if (curr != prev) {142checkColor(x, y, curr, COLOR1, COLOR2);143checkCount(x, y, count);144prev = curr;145count = 1;146} else {147count++;148}149if (x < WIDTH - OFFSET) {150checkColor(x, y - 1, img.getRGB(x, y - 1), BACKGROUND);151checkColor(x, y + 1, img.getRGB(x, y + 1), BACKGROUND);152}153}154checkCount(WIDTH - OFFSET, y, count);155}156157private static void checkVerticalLine(final BufferedImage img,158final int x) {159int prev = img.getRGB(x, OFFSET);160checkColor(x, OFFSET, prev, COLOR1, COLOR2);161int count = 1;162for (int y = OFFSET + 1; y <= HEIGHT - OFFSET; y++) {163int curr = img.getRGB(x, y);164if (curr != prev) {165checkColor(x, y, curr, COLOR1, COLOR2);166checkCount(x, y, count);167prev = curr;168count = 1;169} else {170count++;171}172if (y < HEIGHT - OFFSET) {173checkColor(x - 1, y, img.getRGB(x - 1, y), BACKGROUND);174checkColor(x + 1, y, img.getRGB(x + 1, y), BACKGROUND);175}176}177checkCount(x, HEIGHT - OFFSET, count);178}179180private static void checkCorners(final BufferedImage img) {181int[][] corners = {182{OFFSET - 1, OFFSET - 1},183{OFFSET, OFFSET - 1},184{OFFSET - 1, OFFSET + 1},185186{OFFSET - 1, HEIGHT - OFFSET},187{OFFSET - 1, HEIGHT - OFFSET + 1},188{OFFSET, HEIGHT - OFFSET + 1},189190{WIDTH - OFFSET, OFFSET - 1},191{WIDTH - OFFSET + 1, OFFSET - 1},192{WIDTH - OFFSET + 1, OFFSET},193194{WIDTH - OFFSET + 1, HEIGHT - OFFSET},195{WIDTH - OFFSET + 1, HEIGHT - OFFSET + 1},196{WIDTH - OFFSET, HEIGHT - OFFSET + 1},197};198199for (int[] corner : corners) {200int color = img.getRGB(corner[0], corner[1]);201checkColor(corner[0], corner[1], color, BACKGROUND);202}203}204205private static void checkColor(final int x, final int y,206final int color,207final Color... validColors) {208checkColor(x, y, color, Arrays.stream(validColors)209.mapToInt(Color::getRGB)210.toArray());211}212213private static void checkColor(final int x, final int y,214final int color,215final int... validColors) {216for (int valid : validColors) {217if (color == valid) {218return;219}220}221throw new RuntimeException("Unexpected color at " + x + ", " + y222+ ": " + Integer.toHexString(color) + "; expected: "223+ Arrays.stream(validColors)224.mapToObj(Integer::toHexString)225.collect(Collectors.joining(", ")));226}227228private static void checkCount(final int x, final int y, final int count) {229if (count > MAX_DASH_LENGTH) {230throw new RuntimeException("Dash is longer than " + MAX_DASH_LENGTH231+ " at " + x + ", " + y);232}233}234235private static void save(final BufferedImage img,236final String fileName) throws IOException {237ImageIO.write(img, "png", new File(fileName));238}239240}241242243