undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2015, 2018, 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.
*/
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import static sun.awt.OSInfo.*;
/**
* @test
* @key headful
* @bug 8069348 8198613
* @summary SunGraphics2D.copyArea() does not properly work for scaled graphics
* @modules java.desktop/sun.awt
* @run main/othervm -Dsun.java2d.uiScale=2 CopyScaledAreaTest
* @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 CopyScaledAreaTest
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.opengl=false
* -Dsun.java2d.uiScale=2 CopyScaledAreaTest
*/
public class CopyScaledAreaTest {
private static final int IMAGE_WIDTH = 800;
private static final int IMAGE_HEIGHT = 800;
private static final int X = 50;
private static final int Y = 50;
private static final int W = 100;
private static final int H = 75;
private static final int DX = 15;
private static final int DY = 10;
private static final int N = 3;
private static final Color BACKGROUND_COLOR = Color.YELLOW;
private static final Color FILL_COLOR = Color.ORANGE;
private static final double[][] SCALES = {{1.3, 1.4}, {0.3, 2.3}, {2.7, 0.1}};
private static boolean isSupported() {
String d3d = System.getProperty("sun.java2d.d3d");
return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS;
}
private static int scale(int x, double scale) {
return (int) Math.floor(x * scale);
}
private static VolatileImage createVolatileImage(GraphicsConfiguration conf) {
return conf.createCompatibleVolatileImage(IMAGE_WIDTH, IMAGE_HEIGHT);
}
// rendering to the image
private static void renderOffscreen(VolatileImage vImg,
GraphicsConfiguration conf,
double scaleX,
double scaleY)
{
int attempts = 0;
do {
if (attempts > 10) {
throw new RuntimeException("Too many attempts!");
}
if (vImg.validate(conf) == VolatileImage.IMAGE_INCOMPATIBLE) {
// old vImg doesn't work with new GraphicsConfig; re-create it
vImg = createVolatileImage(conf);
}
Graphics2D g = vImg.createGraphics();
//
// miscellaneous rendering commands...
//
g.setColor(BACKGROUND_COLOR);
g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
g.scale(scaleX, scaleY);
g.setColor(FILL_COLOR);
g.fillRect(X, Y, W, H);
for (int i = 0; i < N; i++) {
g.copyArea(X + i * DX, Y + i * DY, W, H, DX, DY);
}
g.dispose();
attempts++;
} while (vImg.contentsLost());
}
public static void main(String[] args) throws Exception {
if (!isSupported()) {
return;
}
GraphicsConfiguration graphicsConfiguration =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
for(double[] scales: SCALES){
testScale(scales[0], scales[1], graphicsConfiguration);
}
}
private static void testScale(double scaleX, double scaleY,
GraphicsConfiguration gc) throws Exception
{
BufferedImage buffImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics g = buffImage.createGraphics();
VolatileImage vImg = createVolatileImage(gc);
int attempts = 0;
do {
if (attempts > 10) {
throw new RuntimeException("Too many attempts!");
}
int returnCode = vImg.validate(gc);
if (returnCode == VolatileImage.IMAGE_RESTORED) {
// Contents need to be restored
renderOffscreen(vImg, gc, scaleX, scaleY); // restore contents
} else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
// old vImg doesn't work with new GraphicsConfig; re-create it
vImg = createVolatileImage(gc);
renderOffscreen(vImg, gc, scaleX, scaleY);
}
g.drawImage(vImg, 0, 0, null);
attempts++;
} while (vImg.contentsLost());
g.dispose();
int x = scale(X + N * DX, scaleX) + 1;
int y = scale(Y + N * DY, scaleY) + 1;
int w = scale(W, scaleX) - 2;
int h = scale(H, scaleY) - 2;
for (int i = x; i < x + w; i++) {
for (int j = y; j < y + h; j++) {
if (buffImage.getRGB(i, j) != FILL_COLOR.getRGB()) {
throw new RuntimeException("Wrong rectangle color!");
}
}
}
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2007, 2020, 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
* @bug 4614845
* @summary Test drawImage(bgcolor) gets correct RGB from SystemColor objects.
* @run main SystemBgColorTest
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.SystemColor;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.IndexColorModel;
public class SystemBgColorTest {
public static final int TESTW = 10;
public static final int TESTH = 10;
static SystemColor systemColorObjects [] = {
SystemColor.desktop,
SystemColor.activeCaption,
SystemColor.activeCaptionText,
SystemColor.activeCaptionBorder,
SystemColor.inactiveCaption,
SystemColor.inactiveCaptionText,
SystemColor.inactiveCaptionBorder,
SystemColor.window,
SystemColor.windowBorder,
SystemColor.windowText,
SystemColor.menu,
SystemColor.menuText,
SystemColor.text,
SystemColor.textText,
SystemColor.textHighlight,
SystemColor.textHighlightText,
SystemColor.textInactiveText,
SystemColor.control,
SystemColor.controlText,
SystemColor.controlHighlight,
SystemColor.controlLtHighlight,
SystemColor.controlShadow,
SystemColor.controlDkShadow,
SystemColor.scrollbar,
SystemColor.info,
SystemColor.infoText
};
static boolean counterrors;
static int errcount;
public static void error(String problem) {
if (counterrors) {
errcount++;
} else {
throw new RuntimeException(problem);
}
}
public static void main(String argv[]) {
counterrors = (argv.length > 0);
test(BufferedImage.TYPE_INT_ARGB);
test(BufferedImage.TYPE_INT_RGB);
if (errcount > 0) {
throw new RuntimeException(errcount+" errors");
}
}
static int cmap[] = {
0x00000000,
0xffffffff,
};
public static void test(int dsttype) {
BufferedImage src =
new BufferedImage(TESTW, TESTH, BufferedImage.TYPE_INT_ARGB);
test(src, dsttype);
IndexColorModel icm = new IndexColorModel(8, 2, cmap, 0, true, 0,
DataBuffer.TYPE_BYTE);
src = new BufferedImage(TESTW, TESTH,
BufferedImage.TYPE_BYTE_INDEXED, icm);
test(src, dsttype);
}
public static void test(Image src, int dsttype) {
BufferedImage dst =
new BufferedImage(TESTW, TESTH, dsttype);
for (int i = 0; i < systemColorObjects.length; i++) {
test(src, dst, systemColorObjects[i]);
}
}
public static void test(Image src, BufferedImage dst, Color bg) {
Graphics2D g = (Graphics2D) dst.getGraphics();
g.setComposite(AlphaComposite.Src);
g.setColor(Color.white);
g.fillRect(0, 0, TESTW, TESTH);
g.drawImage(src, 0, 0, bg, null);
int dstRGB = dst.getRGB(0, 0);
int bgRGB = bg.getRGB();
if (!dst.getColorModel().hasAlpha()) {
bgRGB |= 0xFF000000;
}
if (dstRGB != bgRGB) {
System.err.println("Actual: " + Integer.toHexString(dstRGB));
System.err.println("Expected: " + Integer.toHexString(bgRGB));
error("bad bg pixel for: " + bg);
}
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020, 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 8235904
@run main/othervm/timeout=60 DrawLineTest
*/
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
public class DrawLineTest extends Frame {
volatile static boolean done = false;
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(() -> {
DrawLineTest frame = new DrawLineTest();
frame.setVisible(true);
Image img = frame.createVolatileImage(1000, 1000);
img.getGraphics().drawLine(0, 0, 34005, 34005);
done = true;
frame.setVisible(false);
frame.dispose();
return;
});
int cnt=0;
while (!done && (cnt++ < 60)) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
if (!done) {
// jtreg will shutdown the test properly
if ((System.getProperty("test.src") != null)) {
throw new RuntimeException("Test Failed");
} else {
// Not to be used in jtreg
System.out.println("Test failed.");
Runtime.getRuntime().halt(-1);
}
}
return;
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1999, 2023, 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
* @bug 4166809
* @summary Make sure NPE is thrown when calling
* Graphics.drawString(null, int, int)
* @run main DrawNullStringTest
*/
import java.awt.image.BufferedImage;
import java.awt.EventQueue;
import java.awt.Graphics;
public class DrawNullStringTest {
static String s = null;
static boolean passed = false;
public static void main(String[] args) throws Exception {
EventQueue.invokeAndWait(() -> {
BufferedImage img = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
Graphics g = (Graphics)(img.getGraphics());
try {
g.drawString(s, 30, 30);
} catch (NullPointerException npe) {
System.out.println("NPE thrown - test passes");
passed = true;
}
if (passed == false) {
throw new Error("No Exception was thrown - should be an NPE");
}
});
}
}// class DrawNullStringTest

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2021, 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 8266159
* @summary Test to detect regression in pixel drawing.
* A small circle is drawn and boundary pixels are compared to expected pixels.
* Note : this test is specifically written for uiScale=1.0
* @run main/othervm -Dsun.java2d.uiScale=1.0 DrawOvalTest
*/
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
public class DrawOvalTest {
public static void main(String[] args) throws IOException {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(10, 10, Transparency.TRANSLUCENT);
// Draw test rendering sequence
BufferedImage snapshot = null;
Graphics2D g2 = vi.createGraphics();
do {
vi.validate(gc);
render(g2);
snapshot = vi.getSnapshot();
} while (vi.contentsLost());
// Pixel color sequence expected after test rendering is complete
// Blue color = -16776961
// Red color = -65536
int sequence[] = {
-16776961,
-16776961,
-16776961,
-65536,
-65536,
-65536,
-65536,
-16776961,
-16776961,
-16776961
};
// Test the color of pixels at the image boundary
for (int i = 0; i < snapshot.getWidth(); i++) {
// Test first row, last row, first column and last column
if ( snapshot.getRGB(i, 0) != sequence[i] ||
snapshot.getRGB(i, 9) != sequence[i] ||
snapshot.getRGB(0, i) != sequence[i] ||
snapshot.getRGB(9, i) != sequence[i] ) {
ImageIO.write(snapshot, "png", new File("DrawOvalTest_snapshot.png"));
throw new RuntimeException("Test failed.");
}
}
}
private static void render(Graphics2D g2) {
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 10, 10);
g2.setColor(Color.RED);
g2.drawOval(0, 0, 9, 9);
}
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 1999, 2025, 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.
*/
import javax.imageio.ImageIO;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @bug 4191297
* @summary Tests that unreferenced GDI resources are correctly
* destroyed when no longer needed.
* @key headful
* @run main GDIResourceExhaustionTest
*/
public class GDIResourceExhaustionTest extends Frame {
public void initUI() {
setSize(200, 200);
setUndecorated(true);
setLocationRelativeTo(null);
Panel labelPanel = new Panel();
Label label = new Label("Red label");
label.setBackground(Color.red);
labelPanel.add(label);
labelPanel.setLocation(20, 50);
add(labelPanel);
setVisible(true);
}
public void paint(Graphics graphics) {
super.paint(graphics);
for (int rgb = 0; rgb <= 0xfff; rgb++) {
graphics.setColor(new Color(rgb));
graphics.fillRect(0, 0, 5, 5);
}
}
public void requestCoordinates(Rectangle r) {
Insets insets = getInsets();
Point location = getLocationOnScreen();
Dimension size = getSize();
r.x = location.x + insets.left;
r.y = location.y + insets.top;
r.width = size.width - (insets.left + insets.right);
r.height = size.height - (insets.top + insets.bottom);
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException, IOException {
GDIResourceExhaustionTest test = new GDIResourceExhaustionTest();
try {
EventQueue.invokeAndWait(test::initUI);
Robot robot = new Robot();
robot.delay(2000);
Rectangle coords = new Rectangle();
EventQueue.invokeAndWait(() -> {
test.requestCoordinates(coords);
});
robot.mouseMove(coords.x - 50, coords.y - 50);
robot.waitForIdle();
robot.delay(5000);
BufferedImage capture = robot.createScreenCapture(coords);
robot.delay(500);
boolean redFound = false;
int redRGB = Color.red.getRGB();
for (int y = 0; y < capture.getHeight(); y++) {
for (int x = 0; x < capture.getWidth(); x++) {
if (capture.getRGB(x, y) == redRGB) {
redFound = true;
break;
}
if (redFound) {
break;
}
}
}
if (!redFound) {
File errorImage = new File("screenshot.png");
ImageIO.write(capture, "png", errorImage);
throw new RuntimeException("Red label is not detected, possibly GDI resources exhausted");
}
} finally {
EventQueue.invokeAndWait(test::dispose);
}
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2002, 2023, 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
* @bug 4746122
* @key headful
* @summary Checks getGraphics doesn't throw NullPointerExcepton for invalid colors and font.
* @run main GetGraphicsTest
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
public class GetGraphicsTest extends Frame {
public Color getBackground() {
return null;
}
public Color getForeground() {
return null;
}
public Font getFont() {
return null;
}
public static void main(String[] args) throws Exception {
GetGraphicsTest test = new GetGraphicsTest();
Graphics g = test.getGraphics();
}
}// class GetGraphicsTest

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2016, 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.
*/
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import static java.awt.RenderingHints.KEY_STROKE_CONTROL;
import static java.awt.RenderingHints.VALUE_STROKE_PURE;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
/**
* @test
* @key headful
* @bug 8167310
* @summary The clip should be correct if the scale is fractional
*/
public final class IncorrectFractionalClip {
private static final int SIZE = 128;
public static final Color RED = new Color(255, 0, 0, 100);
public static final Color GREEN = new Color(0, 255, 0, 100);
public static final Color WHITE = new Color(0, 0, 0, 0);
public static final BasicStroke STROKE = new BasicStroke(2.01f);
private static final double[] SCALES = {
0.1, 0.25, 0.4, 0.5, 0.6, 1, 1.4, 1.5, 1.6, 2.0, 2.4, 2.5, 2.6, 4
};
static BufferedImage bi;
static BufferedImage gold;
static BufferedImage redI;
static BufferedImage greenI;
public static void main(final String[] args) throws Exception {
bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
gold = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
redI = createImage(RED);
greenI = createImage(GREEN);
System.out.println("Will test fillRect");
test(0, true);
test(0, false);
System.out.println("Will test DrawImage");
test(1, true);
test(1, false);
System.out.println("Will test drawLine");
test(2, true);
test(2, false);
}
/**
* This method draws/fills a number of rectangle, images and lines. Each
* time the clip is set as one vertical/horizontal line. The resulted image
* should not have any overlapping of different colors. The clip is set via
* rectangle(test) and via shape(gold). Both images should be identical.
*/
private static void test(final int testId, final boolean horiz)
throws Exception {
for (final double scale : SCALES) {
// Initialize the test and gold images
drawToImage(testId, horiz, scale, bi, /* Rectangle */ false);
drawToImage(testId, horiz, scale, gold, /* Shape */ true);
validate(bi, gold, testId);
}
}
private static void drawToImage(int testId, boolean horiz, double scale,
BufferedImage image, boolean shape) {
Graphics2D g = image.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setColor(WHITE);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.setComposite(AlphaComposite.SrcOver);
g.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE);
// set the scale in one direction
if (horiz) {
g.scale(scale, 1);
} else {
g.scale(1, scale);
}
// cover all units in the user space to touch all pixels in the
// image after transform
final int destSize = (int) Math.ceil(SIZE / scale);
final int destW;
final int destH;
if (horiz) {
destW = destSize;
destH = SIZE;
} else {
destW = SIZE;
destH = destSize;
}
for (int step = 0; step < destSize; ++step) {
if (horiz) {
if (!shape) {
g.setClip(step, 0, 1, SIZE);
} else{
g.setClip(new Area(new Rectangle(step, 0, 1, SIZE)));
}
} else {
if (!shape) {
g.setClip(0, step, SIZE, 1);
}else{
g.setClip(new Area(new Rectangle(0, step, SIZE, 1)));
}
}
switch (testId) {
case 0:
g.setColor(step % 2 == 0 ? RED : GREEN);
g.fillRect(0, 0, destW, destH);
break;
case 1:
g.drawImage(step % 2 == 0 ? redI : greenI, 0, 0,
destW, destH, null);
break;
case 2:
g.setColor(step % 2 == 0 ? RED : GREEN);
g.setStroke(STROKE);
if (horiz) {
g.drawLine(step, 0, step, SIZE);
} else {
g.drawLine(0, step, SIZE, step);
}
break;
default:
throw new RuntimeException();
}
}
g.dispose();
}
private static void validate(final BufferedImage bi, BufferedImage gold,
final int testID) throws Exception {
for (int x = 0; x < SIZE; ++x) {
for (int y = 0; y < SIZE; ++y) {
int rgb = bi.getRGB(x, y);
int goldRGB = gold.getRGB(x, y);
if ((rgb != GREEN.getRGB() && rgb != RED.getRGB())
|| rgb != goldRGB) {
ImageIO.write(bi, "png", new File("image.png"));
ImageIO.write(gold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
private static BufferedImage createImage(final Color color) {
BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setColor(color);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.dispose();
return bi;
}
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2007, 2021, 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
* @bug 6576507
* @summary Both lines of text should be readable
* @run main/manual LCDTextAndGraphicsState
*/
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.geom.RoundRectangle2D;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class LCDTextAndGraphicsState extends Component {
private static final Frame testFrame = new Frame("Composite and Text Test");
private static final String text = "This test passes only if this text appears SIX TIMES else fail";
private static volatile boolean testResult;
private static volatile CountDownLatch countDownLatch;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.white);
g2d.fillRect(0,0,getSize().width, getSize().height);
test1(g.create(0, 0, 500, 100));
test2(g.create(0, 100, 500, 100));
test3(g.create(0, 200, 500, 100));
}
public void test1(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.setColor(Color.black);
g2d.drawString(text, 10, 20);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.9f));
g2d.drawString(text, 10, 50);
}
public void test2(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.setColor(Color.black);
g2d.drawString(text, 10, 20);
g2d.setPaint(new GradientPaint(
0f, 0f, Color.BLACK, 100f, 100f, Color.GRAY));
g2d.drawString(text, 10, 50);
}
public void test3(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.setColor(Color.black);
g2d.drawString(text, 10, 20);
Shape s = new RoundRectangle2D.Double(0, 30, 400, 50, 5, 5);
g2d.clip(s);
g2d.drawString(text, 10, 50);
}
public Dimension getPreferredSize() {
return new Dimension(500,300);
}
public static void disposeUI() {
countDownLatch.countDown();
testFrame.dispose();
}
public static void createTestUI() {
testFrame.add(new LCDTextAndGraphicsState(), BorderLayout.NORTH);
Panel resultButtonPanel = new Panel(new GridLayout(1, 2));
Button passButton = new Button("Pass");
passButton.addActionListener((ActionEvent e) -> {
testResult = true;
disposeUI();
});
Button failButton = new Button("Fail");
failButton.addActionListener(e -> {
testResult = false;
disposeUI();
});
resultButtonPanel.add(passButton);
resultButtonPanel.add(failButton);
Panel controlUI = new Panel(new BorderLayout());
TextArea instructions = new TextArea(
"Instructions:\n" +
"If you see the text six times above, press Pass.\n" +
"If not, press Fail.",
3,
50,
TextArea.SCROLLBARS_NONE
);
instructions.setEditable(false);
controlUI.add(instructions, BorderLayout.CENTER);
controlUI.add(resultButtonPanel, BorderLayout.SOUTH);
testFrame.add(controlUI, BorderLayout.SOUTH);
testFrame.pack();
testFrame.setLocationRelativeTo(null);
testFrame.setVisible(true);
}
public static void main(String[] args) throws InterruptedException {
countDownLatch = new CountDownLatch(1);
createTestUI();
if (!countDownLatch.await(10, TimeUnit.MINUTES)) {
throw new RuntimeException("Timeout : No action was performed on the test UI.");
}
if (!testResult) {
throw new RuntimeException("Test failed!");
}
}
}

View file

@ -0,0 +1,505 @@
/*
* Copyright (c) 2002, 2016, 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 4780022 4862193 7179526
* @summary Tests that clipped lines are drawn over the same pixels
* as unclipped lines (within the clip bounds)
* @run main/timeout=600/othervm -Dsun.java2d.ddforcevram=true LineClipTest
* @run main/timeout=600/othervm LineClipTest
*/
/**
* This app tests whether we are drawing clipped lines the same
* as unclipped lines. The problem occurred when we started
* clipping d3d lines using simple integer clipping, which did not
* account for sub-pixel precision and ended up drawing very different
* pixels than the same line drawn unclipped. A supposed fix
* to that problem used floating-point clipping instead, but there
* was some problem with very limited precision inside of d3d
* (presumably in hardware) that caused some variation in pixels.
* We decided that whatever the fix was, we needed a serious
* line check test to make sure that all kinds of different
* lines would be drawn exactly the same inside the clip area,
* regardless of whether clipping was enabled. This test should
* check all kinds of different cases, such as lines that fall
* completely outside, completely inside, start outside and
* end inside, etc., and lines should end and originate in
* all quadrants of the space divided up by the clip box.
*
* The test works as follows:
* We create nine quadrants using the spaces bisected by the
* edges of the clip bounds (note that only one of these
* quadrants is actually visible when clipping is enabled).
* We create several points in each of these quadrants
* (three in each of the invisible quadrants, nine in the
* center/visible quadrant). Our resulting grid looks like
* this:
*
* x x|x x x|x x
* | |
* | |
* | |
* | |
* | |
* x | | x
* -----------------------------------
* x |x x x| x
* | |
* | |
* x |x x x| x
* | |
* | |
* x |x x x| x
* -----------------------------------
* x | | x
* | |
* | |
* | |
* | |
* | |
* x x|x x x|x x
*
* The test then draws lines from every point to every other
* point. First, we draw unclipped lines in blue and
* then we draw clipped lines in red.
* At certain times (after every point during the default
* test, after every quadrant of lines if you run with the -quick
* option), we check for errors and draw the current image
* to the screen. Error checking consists of copying the
* VolatileImage to a BufferedImage (because we need access
* to the pixels directly) and checking every pixel in the
* image. The check is simple: everything outside the
* clip bounds should be blue (or the background color) and
* everything inside the clip bounds should be red (or the
* background color). So any blue pixel inside or red
* pixel outside means that there was a drawing error and
* the test fails.
* There are 4 modes that the test can run in (dynamic mode is
* exclusive to the other modes, but the other modes are combinable):
*
* (default): the clip is set
* to a default size (100x100) and the test is run.
*
* -quick: The error
* check is run only after every quadrant of lines is
* drawn. This speeds up the test considerably with
* some less accuracy in error checking (because pixels
* from some lines may overdrawn pixels from other lines
* before we have verified the correctness of those
* pixels).
*
* -dynamic: There is no error checking, but this version
* of the test automatically resizes the clip bounds and
* reruns the test over and over. Nothing besides the
* visual check verifies that the test is running correctly.
*
* -rect: Instead of drawing lines, the test draws rectangles
* to/from all points in all quadrants. This tests similar
* clipping functionality for drawRect().
*
* n (where "n" is a number): sets the clip size to the
* given value. Just like the default test except that
* the clip size is as specified.
*
* Note: this test must be run with the -Dsun.java2d.ddforcevram=true
* option to force the test image to stay in VRAM. We currently
* punt VRAM images to system memory when we detect lots of
* reads. Since we read the whole buffer on every error check
* to copy it to the BufferedImage), this causes us to punt the
* buffer. A system memory surface will have no d3d capabilities,
* thus we are not testing the d3d line quality when this happens.
* By using the ddforcevram flag, we make sure the buffer
* stays put in VRAM and d3d is used to draw the lines.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class LineClipTest extends Component implements Runnable {
int clipBumpVal = 5;
static int clipSize = 100;
int clipX1;
int clipY1;
static final int NUM_QUADS = 9;
Point quadrants[][] = new Point[NUM_QUADS][];
static boolean dynamic = false;
BufferedImage imageChecker = null;
Color unclippedColor = Color.blue;
Color clippedColor = Color.red;
int testW = -1, testH = -1;
VolatileImage testImage = null;
static boolean keepRunning = false;
static boolean quickTest = false;
static boolean rectTest = false;
static boolean runTestDone = false;
static Frame f = null;
/**
* Check for errors in the grid. This error check consists of
* copying the buffer into a BufferedImage and reading all pixels
* in that image. No pixel outside the clip bounds should be
* of the color clippedColor and no pixel inside should be
* of the color unclippedColor. Any wrong color returns an error.
*/
boolean gridError(Graphics g) {
boolean error = false;
if (imageChecker == null || (imageChecker.getWidth() != testW) ||
(imageChecker.getHeight() != testH))
{
// Recreate BufferedImage as necessary
GraphicsConfiguration gc = getGraphicsConfiguration();
ColorModel cm = gc.getColorModel();
WritableRaster wr =
cm.createCompatibleWritableRaster(getWidth(), getHeight());
imageChecker =
new BufferedImage(cm, wr,
cm.isAlphaPremultiplied(), null);
}
// Copy buffer to BufferedImage
Graphics gChecker = imageChecker.getGraphics();
gChecker.drawImage(testImage, 0, 0, this);
// Set up pixel colors to check against
int clippedPixelColor = clippedColor.getRGB();
int unclippedPixelColor = unclippedColor.getRGB();
int wrongPixelColor = clippedPixelColor;
boolean insideClip = false;
for (int row = 0; row < getHeight(); ++row) {
for (int col = 0; col < getWidth(); ++col) {
if (row >= clipY1 && row < (clipY1 + clipSize) &&
col >= clipX1 && col < (clipX1 + clipSize))
{
// Inside clip bounds - should not see unclipped color
wrongPixelColor = unclippedPixelColor;
} else {
// Outside clip - should not see clipped color
wrongPixelColor = clippedPixelColor;
}
int pixel = imageChecker.getRGB(col, row);
if (pixel == wrongPixelColor) {
System.out.println("FAILED: pixel = " +
Integer.toHexString(pixel) +
" at (x, y) = " + col + ", " + row);
// Draw magenta rectangle around problem pixel in buffer
// for visual feedback to user
g.setColor(Color.magenta);
g.drawRect(col - 1, row - 1, 2, 2);
error = true;
}
}
}
return error;
}
/**
* Draw all test lines and check for errors (unless running
* with -dynamic option)
*/
void drawLineGrid(Graphics screenGraphics, Graphics g) {
// Fill buffer with background color
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
// Now, iterate through all quadrants
for (int srcQuad = 0; srcQuad < NUM_QUADS; ++srcQuad) {
// Draw lines to all other quadrants
for (int dstQuad = 0; dstQuad < NUM_QUADS; ++dstQuad) {
for (int srcPoint = 0;
srcPoint < quadrants[srcQuad].length;
++srcPoint)
{
// For every point in the source quadrant
int sx = quadrants[srcQuad][srcPoint].x;
int sy = quadrants[srcQuad][srcPoint].y;
for (int dstPoint = 0;
dstPoint < quadrants[dstQuad].length;
++dstPoint)
{
int dx = quadrants[dstQuad][dstPoint].x;
int dy = quadrants[dstQuad][dstPoint].y;
if (!rectTest) {
// Draw unclipped/clipped lines to every
// point in the dst quadrant
g.setColor(unclippedColor);
g.drawLine(sx, sy, dx, dy);
g.setClip(clipX1, clipY1, clipSize, clipSize);
g.setColor(clippedColor);
g.drawLine(sx,sy, dx, dy);
} else {
// Draw unclipped/clipped rectangles to every
// point in the dst quadrant
g.setColor(unclippedColor);
int w = dx - sx;
int h = dy - sy;
g.drawRect(sx, sy, w, h);
g.setClip(clipX1, clipY1, clipSize, clipSize);
g.setColor(clippedColor);
g.drawRect(sx, sy, w, h);
}
g.setClip(null);
}
if (!dynamic) {
// Draw screen update for visual feedback
screenGraphics.drawImage(testImage, 0, 0, this);
// On default test, check for errors after every
// src point
if (!quickTest && gridError(g)) {
throw new java.lang.RuntimeException("Failed");
}
}
}
}
if (!dynamic && quickTest && gridError(g)) {
// On quick test, check for errors only after every
// src quadrant
throw new java.lang.RuntimeException("Failed");
//return;
}
}
if (!dynamic) {
System.out.println("PASSED");
if (!keepRunning) {
f.dispose();
}
}
}
/**
* If we have not yet run the test, or if the window size has
* changed, or if we are running the test in -dynamic mode,
* run the test. Then draw the test buffer to the screen
*/
public void paint(Graphics g) {
if (dynamic || testImage == null ||
getWidth() != testW || getHeight() != testH)
{
runTest(g);
}
if (testImage != null) {
g.drawImage(testImage, 0, 0, this);
}
}
/*
* Create the quadrant of points and run the test to draw all the lines
*/
public void runTest(Graphics screenGraphics) {
if (getWidth() == 0 || getHeight() == 0) {
// May get here before window is really ready
return;
}
clipX1 = (getWidth() - clipSize) / 2;
clipY1 = (getHeight() - clipSize) / 2;
int clipX2 = clipX1 + clipSize;
int clipY2 = clipY1 + clipSize;
int centerX = getWidth()/2;
int centerY = getHeight()/2;
int leftX = 0;
int topY = 0;
int rightX = getWidth() - 1;
int bottomY = getHeight() - 1;
int quadIndex = 0;
// Offsets are used to force diagonal (versus hor/vert) lines
int xOffset = 0;
int yOffset = 0;
if (quadrants[0] == null) {
for (int i = 0; i < 9; ++i) {
int numPoints = (i == 4) ? 9 : 3;
quadrants[i] = new Point[numPoints];
}
}
// Upper-left
quadrants[quadIndex] = new Point[] {
new Point(leftX + xOffset, clipY1 - 1 - yOffset),
new Point(leftX + xOffset, topY + yOffset),
new Point(clipX1 - 1 - xOffset, topY + yOffset),
};
quadIndex++;
yOffset++;
// Upper-middle
quadrants[quadIndex] = new Point[] {
new Point(clipX1 + 1 + xOffset, topY + yOffset),
new Point(centerX + xOffset, topY + yOffset),
new Point(clipX2 - 1 - xOffset, topY + yOffset),
};
quadIndex++;
++yOffset;
// Upper-right
quadrants[quadIndex] = new Point[] {
new Point(clipX2 + 1 + xOffset, topY + yOffset),
new Point(rightX - xOffset, topY + yOffset),
new Point(rightX - xOffset, clipY1 - 1 - yOffset),
};
quadIndex++;
yOffset = 0;
++xOffset;
// Middle-left
quadrants[quadIndex] = new Point[] {
new Point(leftX + xOffset, clipY1 + 1 + yOffset),
new Point(leftX + xOffset, centerY + yOffset),
new Point(leftX + xOffset, clipY2 - 1 - yOffset),
};
quadIndex++;
++yOffset;
// Middle-middle
quadrants[quadIndex] = new Point[] {
new Point(clipX1 + 1 + xOffset, clipY1 + 1 + yOffset),
new Point(centerX + xOffset, clipY1 + 1 + yOffset),
new Point(clipX2 - 1 - xOffset, clipY1 + 1 + yOffset),
new Point(clipX1 + 1 + xOffset, centerY + yOffset),
new Point(centerX + xOffset, centerY + yOffset),
new Point(clipX2 - 1 - xOffset, centerY + yOffset),
new Point(clipX1 + 1 + xOffset, clipY2 - 1 - yOffset),
new Point(centerX + xOffset, clipY2 - 1 - yOffset),
new Point(clipX2 - 1 - xOffset, clipY2 - 1 - yOffset),
};
quadIndex++;
++yOffset;
// Middle-right
quadrants[quadIndex] = new Point[] {
new Point(rightX - xOffset, clipY1 + 1 + yOffset),
new Point(rightX - xOffset, centerY + yOffset),
new Point(rightX - xOffset, clipY2 - 1 - yOffset),
};
quadIndex++;
yOffset = 0;
++xOffset;
// Lower-left
quadrants[quadIndex] = new Point[] {
new Point(leftX + xOffset, clipY2 + 1 + yOffset),
new Point(leftX + xOffset, bottomY - yOffset),
new Point(clipX1 - 1 - xOffset, bottomY - yOffset),
};
quadIndex++;
++yOffset;
// Lower-middle
quadrants[quadIndex] = new Point[] {
new Point(clipX1 + 1 + xOffset, bottomY - yOffset),
new Point(centerX + xOffset, bottomY - yOffset),
new Point(clipX2 - 1 - xOffset, bottomY - yOffset),
};
quadIndex++;
++yOffset;
// Lower-right
quadrants[quadIndex] = new Point[] {
new Point(clipX2 + 1 + xOffset, bottomY - yOffset),
new Point(rightX - xOffset, bottomY - yOffset),
new Point(rightX - xOffset, clipY2 + 1 + yOffset),
};
if (testImage != null) {
testImage.flush();
}
testW = getWidth();
testH = getHeight();
testImage = createVolatileImage(testW, testH);
Graphics g = testImage.getGraphics();
do {
int valCode = testImage.validate(getGraphicsConfiguration());
if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) {
testImage.flush();
testImage = createVolatileImage(testW, testH);
g = testImage.getGraphics();
}
drawLineGrid(screenGraphics, g);
} while (testImage.contentsLost());
if (dynamic) {
// Draw clip box if dynamic
g.setClip(null);
g.setColor(Color.black);
g.drawRect(clipX1, clipY1, clipSize, clipSize);
screenGraphics.drawImage(testImage, 0, 0, this);
}
runTestDone = true;
}
/**
* When running -dynamic, resize the clip bounds and run the test
* over and over
*/
public void run() {
while (true) {
clipSize += clipBumpVal;
if (clipSize > getWidth() || clipSize < 0) {
clipBumpVal = -clipBumpVal;
clipSize += clipBumpVal;
}
update(getGraphics());
try {
Thread.sleep(50);
} catch (Exception e) {}
}
}
public static void main(String args[]) {
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-dynamic")) {
dynamic = true;
} else if (args[i].equals("-rect")) {
rectTest = true;
} else if (args[i].equals("-quick")) {
quickTest = true;
} else if (args[i].equals("-keep")) {
keepRunning = true;
} else {
// could be clipSize
try {
clipSize = Integer.parseInt(args[i]);
} catch (Exception e) {}
}
}
f = new Frame();
f.setSize(500, 500);
LineClipTest test = new LineClipTest();
f.add(test);
if (dynamic) {
Thread t = new Thread(test);
t.start();
}
f.setVisible(true);
while (!runTestDone) {
// need to make sure jtreg doesn't exit before the
// test is done...
try {
Thread.sleep(50);
} catch (Exception e) {}
}
}
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2006, 2025, 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
* @bug 4094059
* @summary drawing to a subclass of canvas didn't draw to the correct location.
* @key headful
* @run main LineLocationTest
*/
import java.awt.AWTException;
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.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
public class LineLocationTest extends Frame {
private DrawScreen screen;
public void initialize() {
setSize(400, 400);
setLocationRelativeTo(null);
setTitle("Line Location Test");
Panel p = new Panel();
screen = new DrawScreen();
p.add(screen);
p.setLocation(50, 50);
p.setSize(300, 300);
add(p);
setBackground(Color.white);
setForeground(Color.blue);
setVisible(true);
}
public void requestCoordinates(Rectangle r) {
Point location = screen.getLocationOnScreen();
Dimension size = screen.getSize();
r.setBounds(location.x, location.y, size.width, size.height);
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
LineLocationTest me = new LineLocationTest();
EventQueue.invokeAndWait(me::initialize);
try {
Robot robot = new Robot();
robot.delay(1000);
Rectangle coords = new Rectangle();
EventQueue.invokeAndWait(() -> {
me.requestCoordinates(coords);
});
BufferedImage capture = robot.createScreenCapture(coords);
robot.delay(2000);
for (int y = 0; y < capture.getHeight(); y++) {
for (int x = 0; x < capture.getWidth(); x++) {
int blue = Color.blue.getRGB();
if (capture.getRGB(x, y) == blue) {
throw new RuntimeException("Blue detected at " + x + ", " + y);
}
}
}
} finally {
EventQueue.invokeAndWait(me::dispose);
}
}
}
class DrawScreen extends Canvas {
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public void paint(Graphics g) {
g.setColor(Color.blue);
g.drawLine(5, -3145583, 50, -3145583);
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 1999, 2025, 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
* @bug 4216180
* @summary This test verifies that Graphics2D.setBackground and clearRect
* performs correctly regardless of antialiasing hint.
* @key headful
* @run main NativeWin32Clear
*/
import java.awt.AWTException;
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.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
public class NativeWin32Clear extends Frame {
public void initialize() {
setLocationRelativeTo(null);
setSize(300, 200);
setBackground(Color.red);
setVisible(true);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Dimension d = getSize();
g2.setBackground(Color.green);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.clearRect(0, 0, d.width / 2, d.height);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2.clearRect(d.width / 2, 0, d.width / 2, d.height);
g2.setColor(Color.black);
}
public void cleanup() {
setVisible(false);
dispose();
}
public void requestCoordinates(Rectangle r) {
Insets insets = getInsets();
Point location = getLocationOnScreen();
Dimension size = getSize();
r.x = location.x + insets.left + 5;
r.y = location.y + insets.top + 5;
r.width = size.width - (insets.left + insets.right + 10);
r.height = size.height - (insets.top + insets.bottom + 10);
}
/*
* Check color match within allowed deviation.
* Prints first non-matching pixel coordinates and actual and expected values.
* Returns true if image is filled with the provided color, false otherwise.
*/
private boolean checkColor(BufferedImage img, Color c, int delta) {
int cRed = c.getRed();
int cGreen = c.getGreen();
int cBlue = c.getBlue();
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
int rgb = img.getRGB(x, y);
int red = (rgb & 0x00ff0000) >> 16;
int green = (rgb & 0x0000ff00) >> 8;
int blue = rgb & 0x000000ff;
if (cRed > (red + delta) || cRed < (red - delta)
|| cGreen > (green + delta) || cGreen < (green - delta)
|| cBlue > (blue + delta) || cBlue < (blue - delta)) {
System.err.println("Color at coordinates (" + x + ", " + y + ") does not match");
System.err.println("Expected color: " + c.getRGB());
System.err.println("Actual color: " + rgb);
System.err.println("Allowed deviation: " + delta);
return false;
}
}
}
return true;
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
NativeWin32Clear test = new NativeWin32Clear();
try {
EventQueue.invokeAndWait(test::initialize);
Robot robot = new Robot();
Rectangle coords = new Rectangle();
EventQueue.invokeAndWait(() -> {
test.requestCoordinates(coords);
});
robot.delay(2000);
robot.mouseMove(coords.x - 50, coords.y - 50);
robot.waitForIdle();
BufferedImage capture = robot.createScreenCapture(coords);
robot.delay(2000);
if (!test.checkColor(capture, Color.green, 5)) {
throw new RuntimeException("Incorrect color encountered, check error log for details");
}
} finally {
EventQueue.invokeAndWait(test::cleanup);
}
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2001, 2025, 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
* @bug 4465509 4453725 4489667
* @summary verify that fillPolygon completely fills area defined by drawPolygon
* @key headful
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual PolygonFillTest
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Polygon;
import java.lang.reflect.InvocationTargetException;
public class PolygonFillTest extends Frame {
Polygon poly;
static String INSTRUCTIONS = """
There should be two hourglass shapes drawn inside the window
called "Polygon Fill Test". The outline should be blue
and the interior should be green and there should be no gaps
between the filled interior and the outline nor should the green
filler spill outside the blue outline. You may need
to use a screen magnifier to inspect the smaller shape
on the left to verify that there are no gaps.
If both polygons painted correctly press "Pass" otherwise press "Fail".
""";
public PolygonFillTest() {
poly = new Polygon();
poly.addPoint(0, 0);
poly.addPoint(10, 10);
poly.addPoint(0, 10);
poly.addPoint(10, 0);
setSize(300, 300);
setTitle("Polygon Fill Test");
}
public void paint(Graphics g) {
int w = getWidth();
int h = getHeight();
Image img = createImage(20, 20);
Graphics g2 = img.getGraphics();
drawPolys(g2, 20, 20, 5, 5);
g2.dispose();
drawPolys(g, w, h, (w / 4) - 5, (h / 2) - 5);
g.drawImage(img, (3 * w / 4) - 40, (h / 2) - 40, 80, 80, null);
}
public void drawPolys(Graphics g, int w, int h, int x, int y) {
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
g.translate(x, y);
g.setColor(Color.green);
g.fillPolygon(poly);
g.setColor(Color.blue);
g.drawPolygon(poly);
g.translate(-x, -y);
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
PassFailJFrame.builder()
.title("Polygon Fill Instructions")
.instructions(INSTRUCTIONS)
.testUI(PolygonFillTest::new)
.build()
.awaitAndCheck();
}
}

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 1998, 2025, 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.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @bug 4081126 4129709
* @summary Test for proper repainting on multiprocessor systems.
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual RepeatedRepaintTest
*/
public class RepeatedRepaintTest extends Frame {
private Font font = null;
private Image background;
static String INSTRUCTIONS = """
The frame next to this window called "AWT Draw Test" has
some elements drawn on it. Move this window partially outside of the
screen bounds and then drag it back. Repeat it couple of times.
Drag the instructions window over the frame partially obscuring it.
If after number of attempts the frame content stops repainting
press "Fail", otherwise press "Pass".
""";
public RepeatedRepaintTest() {
setTitle("AWT Draw Test");
setSize(300, 300);
background = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics g = background.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, 300, 300);
g.dispose();
}
public void paint(Graphics g) {
Dimension dim = this.getSize();
super.paint(g);
g.drawImage(background, 0, 0, dim.width, dim.height, null);
g.setColor(Color.white);
if (font == null) {
font = new Font("SansSerif", Font.PLAIN, 24);
}
g.setFont(font);
FontMetrics metrics = g.getFontMetrics();
String message = "Draw Test";
g.drawString(message, (dim.width / 2) - (metrics.stringWidth(message) / 2),
(dim.height / 2) + (metrics.getHeight() / 2));
int counter = 50;
for (int i = 0; i < 50; i++) {
counter += 4;
g.drawOval(counter, 50, i, i);
}
counter = 20;
for (int i = 0; i < 100; i++) {
counter += 4;
g.drawOval(counter, 150, i, i);
}
g.setColor(Color.black);
g.drawLine(0, dim.height - 25, dim.width, dim.height - 25);
g.setColor(Color.gray);
g.drawLine(0, dim.height - 24, dim.width, dim.height - 24);
g.setColor(Color.lightGray);
g.drawLine(0, dim.height - 23, dim.width, dim.height - 23);
g.fillRect(0, dim.height - 22, dim.width, dim.height);
g.setXORMode(Color.blue);
g.fillRect(0, 0, 25, dim.height - 26);
g.setColor(Color.red);
g.fillRect(0, 0, 25, dim.height - 26);
g.setColor(Color.green);
g.fillRect(0, 0, 25, dim.height - 26);
g.setPaintMode();
Image img = createImage(50, 50);
Graphics imgGraphics = img.getGraphics();
imgGraphics.setColor(Color.magenta);
imgGraphics.fillRect(0, 0, 50, 50);
imgGraphics.setColor(Color.yellow);
imgGraphics.drawString("offscreen", 0, 20);
imgGraphics.drawString("image", 0, 30);
g.drawImage(img, dim.width - 100, dim.height - 100, Color.blue, null);
g.setXORMode(Color.white);
drawAt(g, 100, 100, 50, 50);
drawAt(g, 105, 105, 50, 50);
drawAt(g, 110, 110, 50, 50);
}
public void drawAt(Graphics g, int x, int y, int width, int height) {
g.setColor(Color.magenta);
g.fillRect(x, y, width, height);
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
PassFailJFrame.builder()
.title("Repeated Repaint Test Instructions")
.instructions(INSTRUCTIONS)
.testUI(RepeatedRepaintTest::new)
.build()
.awaitAndCheck();
}
}

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2002, 2025, 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.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Polygon;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @bug 4411814 4298688 4205762 4524760 4067534
* @summary Check that Graphics rendering primitives function
* correctly when fed small and degenerate shapes
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual SmallPrimitives
*/
public class SmallPrimitives extends Panel {
static String INSTRUCTIONS = """
In the borderless frame next to this window there should be a
set of tiny narrow blue polygons painted next to the green rectangles.
If rectangle is vertical the corresponding polygon is painted to the right of it,
if rectangle is horizontal the polygon is painted below it.
The length of the polygon should be roughly the same as the length of the
green rectangle next to it. If size is significantly different or any of the
polygons is not painted press "Fail" otherwise press "Pass".
Note: one may consider using screen magnifier to compare sizes.
""";
public void paint(Graphics g) {
Dimension d = getSize();
Polygon p;
GeneralPath gp;
g.setColor(Color.white);
g.fillRect(0, 0, d.width, d.height);
// Reposition for horizontal tests (below)
g.translate(0, 20);
// Reference shapes
g.setColor(Color.green);
g.fillRect(10, 7, 11, 1);
g.fillRect(10, 17, 11, 2);
g.fillRect(10, 27, 11, 1);
g.fillRect(10, 37, 11, 1);
g.fillRect(10, 47, 11, 2);
g.fillRect(10, 57, 11, 2);
g.fillRect(10, 67, 11, 1);
g.fillRect(10, 77, 11, 2);
g.fillRect(10, 87, 11, 1);
g.fillRect(10, 97, 11, 1);
g.fillRect(10, 107, 11, 1);
g.fillRect(10, 117, 6, 1); g.fillRect(20, 117, 6, 1);
// Potentially problematic test shapes
g.setColor(Color.blue);
g.drawRect(10, 10, 10, 0);
g.drawRect(10, 20, 10, 1);
g.drawRoundRect(10, 30, 10, 0, 0, 0);
g.drawRoundRect(10, 40, 10, 0, 4, 4);
g.drawRoundRect(10, 50, 10, 1, 0, 0);
g.drawRoundRect(10, 60, 10, 1, 4, 4);
g.drawOval(10, 70, 10, 0);
g.drawOval(10, 80, 10, 1);
p = new Polygon();
p.addPoint(10, 90);
p.addPoint(20, 90);
g.drawPolyline(p.xpoints, p.ypoints, p.npoints);
p = new Polygon();
p.addPoint(10, 100);
p.addPoint(20, 100);
g.drawPolygon(p.xpoints, p.ypoints, p.npoints);
((Graphics2D) g).draw(new Line2D.Double(10, 110, 20, 110));
gp = new GeneralPath();
gp.moveTo(10, 120);
gp.lineTo(15, 120);
gp.moveTo(20, 120);
gp.lineTo(25, 120);
((Graphics2D) g).draw(gp);
// Polygon limit tests
p = new Polygon();
trypoly(g, p);
p.addPoint(10, 120);
trypoly(g, p);
// Reposition for vertical tests (below)
g.translate(20, -20);
// Reference shapes
g.setColor(Color.green);
g.fillRect(7, 10, 1, 11);
g.fillRect(17, 10, 2, 11);
g.fillRect(27, 10, 1, 11);
g.fillRect(37, 10, 1, 11);
g.fillRect(47, 10, 2, 11);
g.fillRect(57, 10, 2, 11);
g.fillRect(67, 10, 1, 11);
g.fillRect(77, 10, 2, 11);
g.fillRect(87, 10, 1, 11);
g.fillRect(97, 10, 1, 11);
g.fillRect(107, 10, 1, 11);
g.fillRect(117, 10, 1, 6); g.fillRect(117, 20, 1, 6);
// Potentially problematic test shapes
g.setColor(Color.blue);
g.drawRect(10, 10, 0, 10);
g.drawRect(20, 10, 1, 10);
g.drawRoundRect(30, 10, 0, 10, 0, 0);
g.drawRoundRect(40, 10, 0, 10, 4, 4);
g.drawRoundRect(50, 10, 1, 10, 0, 0);
g.drawRoundRect(60, 10, 1, 10, 4, 4);
g.drawOval(70, 10, 0, 10);
g.drawOval(80, 10, 1, 10);
p = new Polygon();
p.addPoint(90, 10);
p.addPoint(90, 20);
g.drawPolyline(p.xpoints, p.ypoints, p.npoints);
p = new Polygon();
p.addPoint(100, 10);
p.addPoint(100, 20);
g.drawPolygon(p.xpoints, p.ypoints, p.npoints);
((Graphics2D) g).draw(new Line2D.Double(110, 10, 110, 20));
gp = new GeneralPath();
gp.moveTo(120, 10);
gp.lineTo(120, 15);
gp.moveTo(120, 20);
gp.lineTo(120, 25);
((Graphics2D) g).draw(gp);
// Polygon limit tests
p = new Polygon();
trypoly(g, p);
p.addPoint(110, 10);
trypoly(g, p);
// Reposition for oval tests
g.translate(0, 20);
for (int i = 0, xy = 8; i < 11; i++) {
g.setColor(Color.green);
g.fillRect(xy, 5, i, 1);
g.fillRect(5, xy, 1, i);
g.setColor(Color.blue);
g.fillOval(xy, 8, i, 1);
g.fillOval(8, xy, 1, i);
xy += i + 2;
}
g.translate(10, 10);
for (int i = 0, xy = 9; i < 6; i++) {
g.setColor(Color.green);
g.fillRect(xy, 5, i, 2);
g.fillRect(5, xy, 2, i);
g.setColor(Color.blue);
g.fillOval(xy, 8, i, 2);
g.fillOval(8, xy, 2, i);
xy += i + 2;
}
}
public static void trypoly(Graphics g, Polygon p) {
g.drawPolygon(p);
g.drawPolygon(p.xpoints, p.ypoints, p.npoints);
g.drawPolyline(p.xpoints, p.ypoints, p.npoints);
g.fillPolygon(p);
g.fillPolygon(p.xpoints, p.ypoints, p.npoints);
}
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
public static Frame createFrame() {
Frame f = new Frame();
SmallPrimitives sp = new SmallPrimitives();
sp.setLocation(0, 0);
f.add(sp);
f.setUndecorated(true);
f.pack();
return f;
}
public static void main(String argv[]) throws InterruptedException,
InvocationTargetException {
PassFailJFrame.builder()
.title("Small Primitives Instructions")
.instructions(INSTRUCTIONS)
.columns(60)
.testUI(SmallPrimitives::createFrame)
.build()
.awaitAndCheck();
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2004, 2025, 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
* @bug 4844952
* @summary test large text draws properly to the screen
* @key headful
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual TallText
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.lang.reflect.InvocationTargetException;
public class TallText extends Frame {
static String INSTRUCTIONS = """
There should be a window called "Tall Text Test" that contains text "ABCDEFGHIJ".
Test should be properly displayed: no missing letters
and all letters fit within the frame without overlapping.
If all letters are properly displayed press "Pass", otherwise press "Fail".
""";
public TallText() {
setSize(800, 200);
setTitle("Tall Text Test");
}
public void paint(Graphics g) {
Font font = new Font("dialog", Font.PLAIN, 99);
g.setFont(font);
g.setColor(Color.black);
g.drawString("ABCDEFGHIJ", 10, 150);
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
PassFailJFrame.builder()
.title("Tall Text Instructions")
.instructions(INSTRUCTIONS)
.testUI(TallText::new)
.build()
.awaitAndCheck();
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021, 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.
*/
import java.awt.Graphics;
import java.awt.Color;
import java.awt.image.BufferedImage;
/**
* @test
* @bug 6436374
* @summary Verifies that passing null to setColor() will be ignored.
*/
public class TestNullSetColor {
public static void main(String[] argv) {
BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.setColor(Color.RED);
g.setColor(null);
if (g.getColor() != Color.RED) {
throw new RuntimeException("Setting setColor(null) is not ignored");
}
}
}

View file

@ -0,0 +1,237 @@
/*
* 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
* @bug 6263951
* @summary Text should be B&W, grayscale, and LCD.
* @requires (os.family != "mac")
* @run main/manual TextAAHintsTest
*/
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.ImageCapabilities;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.TextArea;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class TextAAHintsTest extends Component {
private static final String black = "This text should be solid black";
private static final String gray = "This text should be gray scale anti-aliased";
private static final String lcd = "This text should be LCD sub-pixel text (coloured).";
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static volatile String failureReason;
private static volatile boolean testPassed = false;
private static Frame frame;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.white);
g2d.fillRect(0,0,getSize().width, getSize().height);
drawText(g.create(0, 0, 500, 100));
bufferedImageText(g.create(0, 100, 500, 100));
volatileImageText(g.create(0, 200, 500, 100));
}
private void drawText(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.white);
g2d.fillRect(0,0,500,100);
g2d.setColor(Color.black);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
g2d.drawString(black, 10, 20);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
g2d.drawString(gray, 10, 35);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.drawString(gray, 10, 50);
/* For visual comparison, render grayscale with graphics AA off */
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.drawString(gray, 10, 65);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.drawString(lcd, 10, 80);
}
public void bufferedImageText(Graphics g) {
BufferedImage bi =
new BufferedImage(500, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
drawText(g2d);
g.drawImage(bi, 0, 0, null);
}
public VolatileImage getVolatileImage(int w, int h) {
VolatileImage image;
try {
image = createVolatileImage(w, h, new ImageCapabilities(true));
} catch (AWTException e) {
System.out.println(e);
System.out.println("Try creating non-accelerated VI instead.");
try {
image = createVolatileImage(w, h,
new ImageCapabilities(false));
} catch (AWTException e1) {
System.out.println("Skipping volatile image test.");
image = null;
}
}
return image;
}
public void volatileImageText(Graphics g) {
VolatileImage image = getVolatileImage(500, 100);
if (image == null) {
return;
}
boolean painted = false;
while (!painted) {
int status = image.validate(getGraphicsConfiguration());
if (status == VolatileImage.IMAGE_INCOMPATIBLE) {
image = getVolatileImage(500, 100);
if (image == null) {
return;
}
}
drawText(image.createGraphics());
g.drawImage(image, 0, 0, null);
painted = !image.contentsLost();
System.out.println("painted = " + painted);
}
}
public Dimension getPreferredSize() {
return new Dimension(500,300);
}
public static void createTestUI() {
frame = new Frame("Composite and Text Test");
TextAAHintsTest textAAHintsTestObject = new TextAAHintsTest();
frame.add(textAAHintsTestObject, BorderLayout.NORTH);
String instructions = """
Note: Texts are rendered with different TEXT_ANTIALIASING &
VALUE_TEXT_ANTIALIAS. Text should be B&W, grayscale, and LCD.
Note: The results may be visually the same.
1. Verify that first set of text are rendered correctly.
2. Second set of text are created using BufferedImage of the first text.
3. Third set of text are created using VolatileImage of the first text.
""";
TextArea instructionTextArea = new TextArea(instructions, 8, 50);
instructionTextArea.setEditable(false);
frame.add(instructionTextArea, BorderLayout.CENTER);
Panel controlPanel = new Panel();
Button passButton = new Button("Pass");
passButton.addActionListener(e -> {
testPassed = true;
countDownLatch.countDown();
frame.dispose();
});
Button failButton = new Button("Fail");
failButton.addActionListener(e -> {
getFailureReason();
testPassed = false;
countDownLatch.countDown();
frame.dispose();
});
controlPanel.add(passButton);
controlPanel.add(failButton);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void getFailureReason() {
// Show dialog to read why the testcase was failed and append the
// testcase failure reason to the output
final Dialog dialog = new Dialog(frame, "TestCase" +
" failure reason", true);
TextArea textArea = new TextArea("", 5, 60, TextArea.SCROLLBARS_BOTH);
dialog.add(textArea, BorderLayout.CENTER);
Button okButton = new Button("OK");
okButton.addActionListener(e1 -> {
failureReason = textArea.getText();
dialog.dispose();
});
Panel ctlPanel = new Panel();
ctlPanel.add(okButton);
dialog.add(ctlPanel, BorderLayout.SOUTH);
dialog.setLocationRelativeTo(null);
dialog.pack();
dialog.setVisible(true);
}
public static void main(String[] args) throws InterruptedException, InvocationTargetException {
EventQueue.invokeAndWait(TextAAHintsTest::createTestUI);
if (!countDownLatch.await(2, TimeUnit.MINUTES)) {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
throw new RuntimeException("Timeout : No action was taken on the test.");
}
if (!testPassed) {
throw new RuntimeException("Test failed : Reason : " + failureReason);
}
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2002, 2025, 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.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.image.VolatileImage;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @bug 4505650
* @summary Check that you can render solid text after doing XOR mode
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual TextAfterXor
*/
public class TextAfterXor extends Panel {
public static final int TESTW = 300;
public static final int TESTH = 100;
static String INSTRUCTIONS = """
In the window called "Text After XOR Test" there should be two
composite components, at the bottom of each component the green text
"Test passes if this is green!" should be visible.
On the top component this text should be green on all platforms.
On the bottom component it is possible that on non-Windows
platforms text can be of other color or not visible at all.
That does not constitute a problem.
So if platform is Windows and green text appears twice or on any
other platform green text appears at least once press "Pass",
otherwise press "Fail".
""";
VolatileImage vimg;
public void paint(Graphics g) {
render(g);
g.drawString("(Drawing to screen)", 10, 60);
if (vimg == null) {
vimg = createVolatileImage(TESTW, TESTH);
}
do {
vimg.validate(null);
Graphics g2 = vimg.getGraphics();
render(g2);
String not = vimg.getCapabilities().isAccelerated() ? "" : "not ";
g2.drawString("Image was " + not + "accelerated", 10, 55);
g2.drawString("(only matters on Windows)", 10, 65);
g2.dispose();
g.drawImage(vimg, 0, TESTH, null);
} while (vimg.contentsLost());
}
public void render(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, TESTW, TESTH);
g.setColor(Color.white);
g.fillRect(5, 5, TESTW-10, TESTH-10);
g.setColor(Color.black);
g.drawString("Test only passes if green string appears", 10, 20);
g.setColor(Color.white);
g.setXORMode(Color.blue);
g.drawRect(30, 30, 10, 10);
g.setPaintMode();
g.setColor(Color.green);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString("Test passes if this is green!", 10, 80);
g.setColor(Color.black);
}
public Dimension getPreferredSize() {
return new Dimension(TESTW, TESTH*2);
}
public static Frame createFrame() {
Frame f = new Frame("Text After XOR Test");
f.add(new TextAfterXor());
f.pack();
return f;
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
PassFailJFrame.builder()
.title("Text After XOR Instructions")
.instructions(INSTRUCTIONS)
.testUI(TextAfterXor::createFrame)
.build()
.awaitAndCheck();
}
}

View file

@ -0,0 +1,239 @@
/*
* Copyright (c) 2005, 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
* @bug 5106309
* @key headful
* @summary Verifies that XOR mode works properly for all pipelines
* (for both simple Colors and complex Paints).
*
* @requires (os.family == "windows")
* @run main/othervm XORPaint
* @run main/othervm -Dsun.java2d.d3d=True -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.d3d=True -Dsun.java2d.uiScale=1.25 XORPaint
* @run main/othervm -Dsun.java2d.d3d=True -Dsun.java2d.uiScale=1.5 XORPaint
* @run main/othervm -Dsun.java2d.d3d=True -Dsun.java2d.uiScale=1.75 XORPaint
* @run main/othervm -Dsun.java2d.d3d=True -Dsun.java2d.uiScale=2 XORPaint
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.uiScale=1.25 XORPaint
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.uiScale=1.5 XORPaint
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.uiScale=1.75 XORPaint
* @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.uiScale=2 XORPaint
*/
/*
* @test
* @bug 5106309
* @key headful
* @summary Verifies that XOR mode works properly for all pipelines
* (for both simple Colors and complex Paints).
*
* @requires (os.family == "mac")
* @run main/othervm XORPaint
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.uiScale=2 XORPaint
* @run main/othervm -Dsun.java2d.metal=True -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.metal=True -Dsun.java2d.uiScale=2 XORPaint
*/
/*
* @test
* @bug 5106309
* @key headful
* @summary Verifies that XOR mode works properly for all pipelines
* (for both simple Colors and complex Paints).
*
* @requires (os.family == "linux")
* @run main/othervm XORPaint
* @run main/othervm -Dsun.java2d.xrender=True -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.xrender=True -Dsun.java2d.uiScale=2 XORPaint
* @run main/othervm -Dsun.java2d.xrender=false -Dsun.java2d.uiScale=1 XORPaint
* @run main/othervm -Dsun.java2d.xrender=false -Dsun.java2d.uiScale=2 XORPaint
*/
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
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.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class XORPaint extends Panel {
private static final int WHITE = 0xffffffff;
private static final int BLUE = 0xff0000ff;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
// render the tests without antialiasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
renderTests(g2d, "This is non-AA text");
// now do the above tests again, this time with antialiasing
g2d.translate(0, 100);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
renderTests(g2d, "This is AA text");
}
private void renderTests(Graphics2D g2d, String text) {
g2d.setFont(new Font("Dialog", Font.PLAIN, 12));
g2d.setColor(Color.blue);
g2d.setXORMode(Color.white);
// fill a rectangle once and make sure it is blue
g2d.fillRect(5, 5, 20, 20);
// fill another rectangle twice and make sure it is reversible
// (should produce the background color)
g2d.fillRect(35, 5, 20, 20);
g2d.fillRect(35, 5, 20, 20);
// draw a string once and make sure it is blue
g2d.drawString(text, 5, 50);
// draw another string twice and make sure it is reversible
// (should produce the background color)
g2d.drawString(text, 5, 70);
g2d.drawString(text, 5, 70);
g2d.setPaint(new GradientPaint(0.0f, 0.0f, Color.blue,
100.0f, 100.f, Color.blue, true));
g2d.fillRect(70, 5, 20, 20);
}
/*
* Not great having to allow any tolerance but some of
* the scaling down for screen captures seems to introduce
* tiny rounding errors that aren't consistent.
* Allow a very small tolerance for this
*/
private static boolean pixelsMatch(int p1, int p2) {
// note : ignoring alpha
int tol = 1;
int r1 = p1 & 0x00ff0000 >> 16;
int g1 = p1 & 0x0000ff00 >> 8;
int b1 = p1 & 0x000000ff;
int r2 = p2 & 0x00ff0000 >> 16;
int g2 = p2 & 0x0000ff00 >> 8;
int b2 = p2 & 0x000000ff;
int rd = r2 - r1; if (rd < 0) rd = -rd;
int gd = g2 - g1; if (gd < 0) gd = -gd;
int bd = b2 - b1; if (bd < 0) bd = -bd;
return (rd <= tol && gd <= tol && bd <= tol);
}
private static void testPixel(BufferedImage capture,
int x, int y, int expectedPixel,
String testDesc, boolean expectedRes)
{
int pixel = capture.getRGB(x, y);
if (expectedRes) {
if (!pixelsMatch(pixel, expectedPixel)) {
try {
ImageIO.write(capture, "png", new File("capture.png"));
} catch (IOException e) {
System.err.println("can't write image " + e);
}
throw new RuntimeException(
"Failed: Incorrect color for " + testDesc
+ " at (" + x + ", " + y + ") "
+ "(expected: " + Integer
.toHexString(expectedPixel) + " actual: "
+ Integer.toHexString(pixel) + ")");
}
} else {
if (pixelsMatch(pixel, expectedPixel)) {
try {
ImageIO.write(capture, "png", new File("capture.png"));
} catch (IOException e) {
System.err.println("can't write image " + e);
}
throw new RuntimeException(
"Failed: Incorrect color for " + testDesc +
" at (" + x + ", " + y + ") " +
" : 0x" + Integer.toHexString(pixel));
}
}
}
private static void testPixels(BufferedImage capture,
int yoff, String type)
{
testPixel(capture, 10, yoff+10, BLUE, "solid rect"+type , true);
testPixel(capture, 40, yoff+10, WHITE, "erased solid rect"+type, true);
testPixel(capture, 80, yoff+10, BLUE, "GradientPaint rect"+type, true);
testPixel(capture, 5, yoff+61, WHITE, "erased text"+type, true);
}
public static void main(String[] args) throws Exception {
final Frame frame = new Frame("XORPaint Test");
final XORPaint xorPanel = new XORPaint();
EventQueue.invokeAndWait(() -> {
frame.add(xorPanel);
frame.setUndecorated(true);
frame.pack();
frame.setSize(250, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
Toolkit.getDefaultToolkit().sync();
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(2000);
Point pt1 = xorPanel.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 200, 200);
BufferedImage capture = robot.createScreenCapture(rect);
EventQueue.invokeAndWait(() -> frame.dispose());
// Make sure we have a white background, for starters
testPixel(capture, 180, 180, WHITE, "background", true);
// Test the non-AA primitives
testPixels(capture, 0, " (non-AA)");
// Test the AA primitives
testPixels(capture, 100, " (AA)");
}
}