8069348: SunGraphics2D.copyArea() does not properly work for scaled graphics in D3D
Reviewed-by: flar, serb
This commit is contained in:
parent
3e11eda222
commit
1d135a8780
@ -478,13 +478,9 @@ public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements Raster
|
||||
// <rdar://problem/4488745> For the Sun2D renderer we should rely on the implementation of the super class.
|
||||
// BufImageSurfaceData.java doesn't have an implementation of copyArea() and relies on the super class.
|
||||
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
if (sg2d.transformState == SunGraphics2D.TRANSFORM_ANY_TRANSLATE ||
|
||||
sg2d.transformState == SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
|
||||
offsetX = (int) sg2d.transform.getTranslateX();
|
||||
offsetY = (int) sg2d.transform.getTranslateY();
|
||||
} else if (sg2d.transformState != SunGraphics2D.TRANSFORM_ISIDENT) { return false; }
|
||||
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset the clip (this is how it works on windows)
|
||||
// we actually can handle a case with any clips but windows ignores the light clip
|
||||
@ -498,18 +494,23 @@ public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements Raster
|
||||
return true;
|
||||
}
|
||||
|
||||
// the rectangle returned from clipCopyArea() is in the coordinate space of the surface (image)
|
||||
// we need to substract the offsetX and offsetY to move it to the coordinate space of the graphics2d.
|
||||
// sg2d.drawImage expects the destination rect to be in the coord space of the graphics2d. <rdar://3746194>
|
||||
// (vm)
|
||||
x = clippedCopyAreaRect.x - offsetX;
|
||||
y = clippedCopyAreaRect.y - offsetY;
|
||||
// the rectangle returned from clipCopyArea() is in the coordinate space
|
||||
// of the surface (image)
|
||||
x = clippedCopyAreaRect.x;
|
||||
y = clippedCopyAreaRect.y;
|
||||
w = clippedCopyAreaRect.width;
|
||||
h = clippedCopyAreaRect.height;
|
||||
|
||||
// copy (dst coordinates are in the coord space of the graphics2d, and src coordinates are
|
||||
// in the coordinate space of the image)
|
||||
sg2d.drawImage(this.bim, x + dx, y + dy, x + dx + w, y + dy + h, x + offsetX, y + offsetY, x + w + offsetX, y + h + offsetY, null);
|
||||
// copy (dst coordinates are in the coord space of the graphics2d, and
|
||||
// src coordinates are in the coordinate space of the image)
|
||||
// sg2d.drawImage expects the destination rect to be in the coord space
|
||||
// of the graphics2d. <rdar://3746194> (vm)
|
||||
// we need to substract the transX and transY to move it
|
||||
// to the coordinate space of the graphics2d.
|
||||
int dstX = x + dx - sg2d.transX;
|
||||
int dstY = y + dy - sg2d.transY;
|
||||
sg2d.drawImage(this.bim, dstX, dstY, dstX + w, dstY + h,
|
||||
x, y, x + w, y + h, null);
|
||||
|
||||
// restore the clip
|
||||
sg2d.setClip(clip);
|
||||
|
@ -1094,19 +1094,13 @@ public abstract class OSXSurfaceData extends BufImgSurfaceData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips the copy area to the heavywieght bounds and returns the cliped rectangle. The tricky part here is the
|
||||
* passed arguments x, y are in the coordinate space of the sg2d/lightweight comp. In order to do the clipping we
|
||||
* translate them to the coordinate space of the surface, and the returned clipped rectangle is in the coordinate
|
||||
* space of the surface.
|
||||
* Clips the copy area to the heavyweight bounds and returns the clipped rectangle.
|
||||
* The returned clipped rectangle is in the coordinate space of the surface.
|
||||
*/
|
||||
protected Rectangle clipCopyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
|
||||
// we need to clip against the heavyweight bounds
|
||||
copyAreaBounds.setBounds(sg2d.devClip.getLoX(), sg2d.devClip.getLoY(), sg2d.devClip.getWidth(), sg2d.devClip.getHeight());
|
||||
|
||||
// put src rect into surface coordinate space
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
|
||||
// clip src rect
|
||||
srcCopyAreaRect.setBounds(x, y, w, h);
|
||||
intersection(srcCopyAreaRect, copyAreaBounds, srcCopyAreaRect);
|
||||
|
@ -175,31 +175,6 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
|
||||
int dx, int dy) {
|
||||
final int state = sg2d.transformState;
|
||||
if (state > SunGraphics2D.TRANSFORM_TRANSLATESCALE
|
||||
|| sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
|
||||
return false;
|
||||
}
|
||||
if (state <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
} else if (state == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
|
||||
final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
|
||||
sg2d.transform.transform(coords, 0, coords, 0, 3);
|
||||
x = (int) Math.ceil(coords[0] - 0.5);
|
||||
y = (int) Math.ceil(coords[1] - 0.5);
|
||||
w = ((int) Math.ceil(coords[2] - 0.5)) - x;
|
||||
h = ((int) Math.ceil(coords[3] - 0.5)) - y;
|
||||
dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
|
||||
dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
|
||||
}
|
||||
oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected native void clearWindow();
|
||||
|
||||
public static class CGLWindowSurfaceData extends CGLSurfaceData {
|
||||
|
@ -2101,13 +2101,39 @@ public final class SunGraphics2D
|
||||
if (w <= 0 || h <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (transformState == SunGraphics2D.TRANSFORM_ISIDENT) {
|
||||
// do nothing
|
||||
} else if (transformState <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
|
||||
x += transX;
|
||||
y += transY;
|
||||
} else if (transformState == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
|
||||
final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
|
||||
transform.transform(coords, 0, coords, 0, 3);
|
||||
x = (int) Math.ceil(coords[0] - 0.5);
|
||||
y = (int) Math.ceil(coords[1] - 0.5);
|
||||
w = ((int) Math.ceil(coords[2] - 0.5)) - x;
|
||||
h = ((int) Math.ceil(coords[3] - 0.5)) - y;
|
||||
dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
|
||||
dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
|
||||
// In case of negative scale transform, reflect the rect coords.
|
||||
if (w < 0) {
|
||||
w = -w;
|
||||
x -= w;
|
||||
}
|
||||
if (h < 0) {
|
||||
h = -h;
|
||||
y -= h;
|
||||
}
|
||||
} else {
|
||||
throw new InternalError("transformed copyArea not implemented yet");
|
||||
}
|
||||
|
||||
SurfaceData theData = surfaceData;
|
||||
if (theData.copyArea(this, x, y, w, h, dx, dy)) {
|
||||
return;
|
||||
}
|
||||
if (transformState > TRANSFORM_TRANSLATESCALE) {
|
||||
throw new InternalError("transformed copyArea not implemented yet");
|
||||
}
|
||||
|
||||
// REMIND: This method does not deal with missing data from the
|
||||
// source object (i.e. it does not send exposure events...)
|
||||
|
||||
@ -2126,26 +2152,6 @@ public final class SunGraphics2D
|
||||
lastCAcomp = comp;
|
||||
}
|
||||
|
||||
double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
|
||||
transform.transform(coords, 0, coords, 0, 3);
|
||||
|
||||
x = (int)Math.ceil(coords[0] - 0.5);
|
||||
y = (int)Math.ceil(coords[1] - 0.5);
|
||||
w = ((int)Math.ceil(coords[2] - 0.5)) - x;
|
||||
h = ((int)Math.ceil(coords[3] - 0.5)) - y;
|
||||
dx = ((int)Math.ceil(coords[4] - 0.5)) - x;
|
||||
dy = ((int)Math.ceil(coords[5] - 0.5)) - y;
|
||||
|
||||
// In case of negative scale transform, reflect the rect coords.
|
||||
if (w < 0) {
|
||||
w *= -1;
|
||||
x -= w;
|
||||
}
|
||||
if (h < 0) {
|
||||
h *= -1;
|
||||
y -= h;
|
||||
}
|
||||
|
||||
Blit ob = lastCAblit;
|
||||
if (dy == 0 && dx > 0 && dx < w) {
|
||||
while (w > 0) {
|
||||
@ -2167,7 +2173,7 @@ public final class SunGraphics2D
|
||||
}
|
||||
return;
|
||||
}
|
||||
ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
|
||||
ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1039,6 +1039,11 @@ public abstract class SurfaceData
|
||||
* Performs a copyarea within this surface. Returns
|
||||
* false if there is no algorithm to perform the copyarea
|
||||
* given the current settings of the SunGraphics2D.
|
||||
*
|
||||
* @param x the x coordinate of the area in device space
|
||||
* @param y the y coordinate of the area in device space
|
||||
* @param w the width of the area in device space
|
||||
* @param h the height of the area in device space
|
||||
*/
|
||||
public boolean copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
|
@ -542,20 +542,14 @@ public abstract class OGLSurfaceData extends SurfaceData
|
||||
return super.getMaskFill(sg2d);
|
||||
}
|
||||
|
||||
public boolean copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
sg2d.compositeState < SunGraphics2D.COMP_XOR)
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
|
||||
oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
|
||||
return true;
|
||||
@Override
|
||||
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
|
||||
int dx, int dy) {
|
||||
if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
|
@ -487,12 +487,9 @@ public abstract class X11SurfaceData extends XSurfaceData {
|
||||
makePipes();
|
||||
}
|
||||
CompositeType comptype = sg2d.imageComp;
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
(CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
if ((CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
CompositeType.SrcNoEa.equals(comptype)))
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
boolean needExposures = canSourceSendExposures(x, y, w, h);
|
||||
|
@ -365,12 +365,9 @@ public abstract class XRSurfaceData extends XSurfaceData {
|
||||
makePipes();
|
||||
}
|
||||
CompositeType comptype = sg2d.imageComp;
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
(CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
CompositeType.SrcNoEa.equals(comptype)))
|
||||
if (CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
CompositeType.SrcNoEa.equals(comptype))
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
try {
|
||||
SunToolkit.awtLock();
|
||||
boolean needExposures = canSourceSendExposures(x, y, w, h);
|
||||
|
@ -703,20 +703,13 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
sg2d.compositeState < SunGraphics2D.COMP_XOR)
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
|
||||
d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
|
||||
return true;
|
||||
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
|
||||
int dx, int dy) {
|
||||
if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -311,13 +311,10 @@ public class GDIWindowSurfaceData extends SurfaceData {
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
CompositeType comptype = sg2d.imageComp;
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
sg2d.clipState != SunGraphics2D.CLIP_SHAPE &&
|
||||
if (sg2d.clipState != SunGraphics2D.CLIP_SHAPE &&
|
||||
(CompositeType.SrcOverNoEa.equals(comptype) ||
|
||||
CompositeType.SrcNoEa.equals(comptype)))
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
int dstx1 = x + dx;
|
||||
int dsty1 = y + dy;
|
||||
int dstx2 = dstx1 + w;
|
||||
|
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* @bug 8069348
|
||||
* @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.opengl=true -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
144
jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java
Normal file
144
jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import javax.swing.JDesktopPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import static sun.awt.OSInfo.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8069348
|
||||
* @summary SunGraphics2D.copyArea() does not properly work for scaled graphics
|
||||
* @author Alexandr Scherbatiy
|
||||
* @modules java.desktop/sun.awt
|
||||
* @run main/othervm -Dsun.java2d.uiScale=2 bug8069348
|
||||
* @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.uiScale=2 bug8069348
|
||||
* @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 bug8069348
|
||||
*/
|
||||
public class bug8069348 {
|
||||
|
||||
private static final int WIN_WIDTH = 500;
|
||||
private static final int WIN_HEIGHT = 500;
|
||||
|
||||
private static final Color DESKTOPPANE_COLOR = Color.YELLOW;
|
||||
private static final Color FRAME_COLOR = Color.ORANGE;
|
||||
|
||||
private static JFrame frame;
|
||||
private static JInternalFrame internalFrame;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
if (!isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI);
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(50);
|
||||
robot.waitForIdle();
|
||||
|
||||
Rectangle screenBounds = getInternalFrameScreenBounds();
|
||||
|
||||
int x = screenBounds.x + screenBounds.width / 2;
|
||||
int y = screenBounds.y + 10;
|
||||
int dx = screenBounds.width / 2;
|
||||
int dy = screenBounds.height / 2;
|
||||
|
||||
robot.mouseMove(x, y);
|
||||
robot.waitForIdle();
|
||||
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseMove(x + dx, y + dy);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.waitForIdle();
|
||||
|
||||
int cx = screenBounds.x + screenBounds.width + dx / 2;
|
||||
int cy = screenBounds.y + screenBounds.height + dy / 2;
|
||||
|
||||
robot.mouseMove(cx, cy);
|
||||
if (!FRAME_COLOR.equals(robot.getPixelColor(cx, cy))) {
|
||||
throw new RuntimeException("Internal frame is not correctly dragged!");
|
||||
}
|
||||
} finally {
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSupported() {
|
||||
String d3d = System.getProperty("sun.java2d.d3d");
|
||||
return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS;
|
||||
}
|
||||
|
||||
private static Rectangle getInternalFrameScreenBounds() throws Exception {
|
||||
Rectangle[] points = new Rectangle[1];
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
points[0] = new Rectangle(internalFrame.getLocationOnScreen(),
|
||||
internalFrame.getSize());
|
||||
});
|
||||
return points[0];
|
||||
}
|
||||
|
||||
private static void createAndShowGUI() {
|
||||
|
||||
frame = new JFrame();
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
JDesktopPane desktopPane = new JDesktopPane();
|
||||
desktopPane.setBackground(DESKTOPPANE_COLOR);
|
||||
|
||||
internalFrame = new JInternalFrame("Test") {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
g.setColor(FRAME_COLOR);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
internalFrame.setSize(WIN_WIDTH / 3, WIN_HEIGHT / 3);
|
||||
internalFrame.setVisible(true);
|
||||
desktopPane.add(internalFrame);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
panel.add(desktopPane, BorderLayout.CENTER);
|
||||
frame.add(panel);
|
||||
frame.setSize(WIN_WIDTH, WIN_HEIGHT);
|
||||
frame.setVisible(true);
|
||||
frame.requestFocus();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user