Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.util.*;
import java.lang.*;
import java.lang.reflect.*;
Expand Down Expand Up @@ -478,6 +479,9 @@ private AccessibleContext getAccessibleContextAt(int x, int y,
if (parent == null) {
return null;
}
Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y);
x = userSpaceXY.x;
y = userSpaceXY.y;
if (windowHandleToContextMap != null &&
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
// Path for applications that register their top-level
Expand Down Expand Up @@ -1593,6 +1597,8 @@ public Rectangle call() throws Exception {
if (p != null) {
r.x = p.x;
r.y = p.y;

r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r);
return r;
}
} catch (Exception e) {
Expand Down Expand Up @@ -2257,6 +2263,7 @@ public Rectangle call() throws Exception {
if (s != null && s.equals("\n")) {
rect.width = 0;
}
rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect);
return rect;
}
}
Expand Down Expand Up @@ -7338,4 +7345,182 @@ T getResult() throws Exception {
}
}
}

/**
* A helper class to handle coordinate conversion between screen and user spaces.
* See {@link sun.java2d.SunGraphicsEnvironment}
*/
private static abstract class AccessibilityGraphicsEnvironment extends GraphicsEnvironment {
/**
* Returns the graphics configuration which bounds contain the given point in the user's space.
*
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
*
* @param x the x coordinate of the given point in the user's space
* @param y the y coordinate of the given point in the user's space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(double x, double y) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
return getGraphicsConfigurationAtPoint(gc, x, y);
}

/**
* Returns the graphics configuration which bounds contain the given point in the user's space.
*
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
*
* @param current the default configuration which is checked in the first
* place
* @param x the x coordinate of the given point in the user's space
* @param y the y coordinate of the given point in the user's space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(
GraphicsConfiguration current, double x, double y) {
if (containsUserSpacePoint(current, x, y)) {
return current;
}
GraphicsEnvironment env = getLocalGraphicsEnvironment();
for (GraphicsDevice device : env.getScreenDevices()) {
GraphicsConfiguration config = device.getDefaultConfiguration();
if (containsUserSpacePoint(config, x, y)) {
return config;
}
}
return current;
}

/**
* Returns the graphics configuration which bounds contain the given point in the device space.
*
* @param x the x coordinate of the given point in the device space
* @param y the y coordinate of the given point in the device space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(double x, double y) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
return getGraphicsConfigurationAtDevicePoint(gc, x, y);
}

/**
* Returns the graphics configuration which bounds contain the given point in the device space.
*
* @param current the default configuration which is checked in the first
* place
* @param x the x coordinate of the given point in the device space
* @param y the y coordinate of the given point in the device space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(
GraphicsConfiguration current, double x, double y) {
if (containsDeviceSpacePoint(current, x, y)) {
return current;
}
GraphicsEnvironment env = getLocalGraphicsEnvironment();
for (GraphicsDevice device : env.getScreenDevices()) {
GraphicsConfiguration config = device.getDefaultConfiguration();
if (containsDeviceSpacePoint(config, x, y)) {
return config;
}
}
return current;
}

private static boolean containsDeviceSpacePoint(GraphicsConfiguration config, double x, double y) {
Rectangle bounds = config.getBounds();
bounds = toDeviceSpaceAbs(config, bounds.x, bounds.y, bounds.width, bounds.height);
return bounds.contains(x, y);
}

private static boolean containsUserSpacePoint(GraphicsConfiguration config, double x, double y) {
Rectangle bounds = config.getBounds();
return bounds.contains(x, y);
}

/**
* Converts absolute coordinates from the device
* space to the user's space space using appropriate device transformation.
*
* @param x absolute x coordinate in the device's space
* @param y absolute y coordinate in the device's space
* @return the corresponding coordinates in user's space
*/
public static Point toUserSpace(int x, int y) {
GraphicsConfiguration gc = getGraphicsConfigurationAtDevicePoint(x, y);
return toUserSpace(gc, x, y);
}

/**
* Converts absolute coordinates from the device
* space to the user's space using passed graphics configuration.
*
* @param gc the graphics configuration to be used for transformation
* @param x absolute x coordinate in the device's space
* @param y absolute y coordinate in the device's space
* @return the corresponding coordinates in user's space
*/
public static Point toUserSpace(GraphicsConfiguration gc, int x, int y) {
AffineTransform tx = gc.getDefaultTransform();
Rectangle screen = gc.getBounds();
int userX = screen.x + clipRound((x - screen.x) / tx.getScaleX());
int userY = screen.y + clipRound((y - screen.y) / tx.getScaleY());
return new Point(userX, userY);
}

/**
* Converts the rectangle from the user's space to the device space using
* appropriate device transformation.
*
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(Rectangle)}
*
* @param rect the rectangle in the user's space
* @return the rectangle which uses device space (pixels)
*/
public static Rectangle toDeviceSpaceAbs(Rectangle rect) {
GraphicsConfiguration gc = getGraphicsConfigurationAtPoint(rect.x, rect.y);
return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height);
}

/**
* Converts absolute coordinates (x, y) and the size (w, h) from the user's
* space to the device space using passed graphics configuration.
*
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(GraphicsConfiguration, int, int, int, int)}
*
* @param gc the graphics configuration to be used for transformation
* @param x absolute coordinate in the user's space
* @param y absolute coordinate in the user's space
* @param w the width in the user's space
* @param h the height in the user's space
* @return the rectangle which uses device space (pixels)
*/
public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc,
int x, int y, int w, int h) {
AffineTransform tx = gc.getDefaultTransform();
Rectangle screen = gc.getBounds();
return new Rectangle(
screen.x + clipRound((x - screen.x) * tx.getScaleX()),
screen.y + clipRound((y - screen.y) * tx.getScaleY()),
clipRound(w * tx.getScaleX()),
clipRound(h * tx.getScaleY())
);
}

/**
* See {@link sun.java2d.pipe.Region#clipRound}
*/
private static int clipRound(final double coordinate) {
final double newv = coordinate - 0.5;
if (newv < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
if (newv > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) Math.ceil(newv);
}
}
}