Skip to content

Commit

Permalink
Redesigned the Display coordinate system for win32
Browse files Browse the repository at this point in the history
This commit enforces displays to store x,y coordinates in point as the
absolute pixels in the display coordinate system. while scaling the
width and height to the points, following this the map methods are
reimplemented to do the right conversion between the new display coordinate
system and the coordinates within a control.

contributes to #62 and #127
  • Loading branch information
akoch-yatta authored and amartya4256 committed Jul 25, 2024
1 parent fc0098c commit 697b845
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3969,8 +3969,9 @@ void subclass () {
*/
public Point toControl (int x, int y) {
checkWidget ();
int zoom = getZoom();
return DPIUtil.scaleDown(toControlInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom);
Point displayPointInPixels = getDisplay().getLocationInPixelsInDisplayCoordinateSystem(x, y);
final Point controlPointInPixels = toControlInPixels(displayPointInPixels.x, displayPointInPixels.y);
return DPIUtil.scaleDown(controlPointInPixels, getZoom());
}

Point toControlInPixels (int x, int y) {
Expand Down Expand Up @@ -4003,9 +4004,7 @@ Point toControlInPixels (int x, int y) {
public Point toControl (Point point) {
checkWidget ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
int zoom = getZoom();
point = DPIUtil.scaleUp(point, zoom);
return DPIUtil.scaleDown(toControlInPixels(point.x, point.y), zoom);
return toControl(point.x, point.y);
}

/**
Expand All @@ -4031,7 +4030,8 @@ public Point toControl (Point point) {
public Point toDisplay (int x, int y) {
checkWidget ();
int zoom = getZoom();
return DPIUtil.scaleDown(toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom);
Point displayPointInPixels = toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom));
return getDisplay().getLocationInPointInDisplayCoordinateSystem(displayPointInPixels);
}

Point toDisplayInPixels (int x, int y) {
Expand Down Expand Up @@ -4064,9 +4064,7 @@ Point toDisplayInPixels (int x, int y) {
public Point toDisplay (Point point) {
checkWidget ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
int zoom = getZoom();
point = DPIUtil.scaleUp(point, zoom);
return DPIUtil.scaleDown(toDisplayInPixels(point.x, point.y), zoom);
return toDisplay(point.x, point.y);
}

long topHandle () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,8 @@ public Control getCursorControl () {
*/
public Point getCursorLocation () {
checkDevice ();
return DPIUtil.autoScaleDown(getCursorLocationInPixels());
Point cursorLocationInPixels = getCursorLocationInPixels();
return getLocationInPointInDisplayCoordinateSystem(cursorLocationInPixels.x, cursorLocationInPixels.y);
}

Point getCursorLocationInPixels () {
Expand All @@ -1700,6 +1701,30 @@ Point getCursorLocationInPixels () {
return new Point (pt.x, pt.y);
}

Point getLocationInPixelsInDisplayCoordinateSystem(Point point) {
return getLocationInPixelsInDisplayCoordinateSystem(point.x, point.y);
}

Point getLocationInPixelsInDisplayCoordinateSystem(int x, int y) {
Monitor monitor = getContainingMonitor(x, y);
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
x = DPIUtil.scaleUp(x - monitor.clientX, zoom) + monitor.clientX;
y = DPIUtil.scaleUp(y - monitor.clientY, zoom) + monitor.clientY;
return new Point(x, y);
}

Point getLocationInPointInDisplayCoordinateSystem(Point point) {
return getLocationInPointInDisplayCoordinateSystem(point.x, point.y);
}

Point getLocationInPointInDisplayCoordinateSystem(int x, int y) {
Monitor monitor = getContainingMonitorInPixelsCoordiate(x, y);
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
x = DPIUtil.scaleDown(x - monitor.clientX, zoom) + monitor.clientX;
y = DPIUtil.scaleDown(y - monitor.clientY, zoom) + monitor.clientY;
return new Point(x, y);
}

/**
* Returns an array containing the recommended cursor sizes.
*
Expand Down Expand Up @@ -2170,18 +2195,25 @@ Monitor getMonitor (long hmonitor) {
OS.GetMonitorInfo (hmonitor, lpmi);
Monitor monitor = new Monitor ();
monitor.handle = hmonitor;
Rectangle boundsInPixels = new Rectangle (lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top);
monitor.setBounds (DPIUtil.autoScaleDown (boundsInPixels));
Rectangle clientAreaInPixels = new Rectangle (lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top);
monitor.setClientArea (DPIUtil.autoScaleDown (clientAreaInPixels));
Rectangle boundsInPixels = new Rectangle(lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top);
Rectangle clientAreaInPixels = new Rectangle(lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top);
int [] dpiX = new int[1];
int [] dpiY = new int[1];
int result = OS.GetDpiForMonitor (monitor.handle, OS.MDT_EFFECTIVE_DPI, dpiX, dpiY);
result = (result == OS.S_OK) ? DPIUtil.mapDPIToZoom (dpiX[0]) : 100;

int autoscaleZoom;
if (DPIUtil.isAutoScaleOnRuntimeActive()) {
autoscaleZoom = DPIUtil.getZoomForAutoscaleProperty(result);
} else {
autoscaleZoom = DPIUtil.getDeviceZoom();
}
if (result == 0) {
System.err.println("***WARNING: GetDpiForMonitor: SWT could not get valid monitor scaling factor.");
result = 100;
}
monitor.setBounds(getMonitorBoundsInPointsInDisplayCoordinateSystem(boundsInPixels, autoscaleZoom));
monitor.setClientArea(getMonitorBoundsInPointsInDisplayCoordinateSystem(clientAreaInPixels, autoscaleZoom));
/*
* Always return true monitor zoom value as fetched from native, else will lead
* to scaling issue on OS Win8.1 and above, for more details refer bug 537614.
Expand All @@ -2190,6 +2222,13 @@ Monitor getMonitor (long hmonitor) {
return monitor;
}

private Rectangle getMonitorBoundsInPointsInDisplayCoordinateSystem(Rectangle boundsInPixels, int zoom) {
Rectangle bounds = DPIUtil.scaleDown(boundsInPixels, zoom);
bounds.x = boundsInPixels.x;
bounds.y = boundsInPixels.y;
return bounds;
}

/**
* Returns an array of monitors attached to the device.
*
Expand Down Expand Up @@ -2969,9 +3008,7 @@ boolean isValidThread () {
public Point map (Control from, Control to, Point point) {
checkDevice ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
int zoom = getZoomLevelForMapping(from, to);
point = DPIUtil.scaleUp(point, zoom);
return DPIUtil.scaleDown(mapInPixels(from, to, point), zoom);
return map(from, to, point.x, point.y);
}

Point mapInPixels (Control from, Control to, Point point) {
Expand Down Expand Up @@ -3016,10 +3053,18 @@ Point mapInPixels (Control from, Control to, Point point) {
*/
public Point map (Control from, Control to, int x, int y) {
checkDevice ();
int zoom = getZoomLevelForMapping(from, to);
x = DPIUtil.scaleUp(x, zoom);
y = DPIUtil.scaleUp(y, zoom);
return DPIUtil.scaleDown(mapInPixels(from, to, x, y), zoom);
Point mappedPointInPoints;
if (from == null) {
Point mappedPointInpixels = mapInPixels(from, to, getLocationInPixelsInDisplayCoordinateSystem(x, y));
mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom());
} else if (to == null) {
Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom()));
mappedPointInPoints = getLocationInPointInDisplayCoordinateSystem(mappedPointInpixels);
} else {
Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom()));
mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom());
}
return mappedPointInPoints;
}

Point mapInPixels (Control from, Control to, int x, int y) {
Expand All @@ -3035,15 +3080,6 @@ Point mapInPixels (Control from, Control to, int x, int y) {
return new Point (point.x, point.y);
}

private int getZoomLevelForMapping(Control from, Control to) {
if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
if (to != null) {
return to.getZoom();
}
return from.getZoom();
}

/**
* Maps a point from one coordinate system to another.
* When the control is null, coordinates are mapped to
Expand Down Expand Up @@ -3083,9 +3119,25 @@ private int getZoomLevelForMapping(Control from, Control to) {
public Rectangle map (Control from, Control to, Rectangle rectangle) {
checkDevice ();
if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
int zoom = getZoomLevelForMapping(from, to);
rectangle = DPIUtil.scaleUp(rectangle, zoom);
return DPIUtil.scaleDown(mapInPixels(from, to, rectangle), zoom);
return map(from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}

private Rectangle getRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height) {
Point topLeft = getLocationInPixelsInDisplayCoordinateSystem(x, y);
Monitor monitor = getContainingMonitor(x, y);
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
int widthInPixels = DPIUtil.scaleUp(width, zoom);
int heightInPixels = DPIUtil.scaleUp(height, zoom);
return new Rectangle(topLeft.x, topLeft.y, widthInPixels, heightInPixels);
}

private Rectangle getRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels) {
Point topLeft = getLocationInPointInDisplayCoordinateSystem(x, y);
Monitor monitor = getContainingMonitorInPixelsCoordiate(x, y);
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
int width = DPIUtil.scaleDown(widthInPixels, zoom);
int height = DPIUtil.scaleDown(heightInPixels, zoom);
return new Rectangle(topLeft.x, topLeft.y, width, height);
}

Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) {
Expand Down Expand Up @@ -3132,12 +3184,18 @@ Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) {
*/
public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
checkDevice ();
int zoom = getZoomLevelForMapping(from, to);
x = DPIUtil.scaleUp(x, zoom);
y = DPIUtil.scaleUp(y, zoom);
width = DPIUtil.scaleUp(width, zoom);
height = DPIUtil.scaleUp(height, zoom);
return DPIUtil.scaleDown(mapInPixels(from, to, x, y, width, height), zoom);
Rectangle mappedRectangleInPoints;
if (from == null) {
Rectangle mappedRectangleInPixels = mapInPixels(from, to, getRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height));
mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom());
} else if (to == null) {
Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom()));
mappedRectangleInPoints = getRectangleInPointsInDisplayCoordinateSystem(mappedRectangleInPixels.x, mappedRectangleInPixels.y, mappedRectangleInPixels.width, mappedRectangleInPixels.height);
} else {
Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom()));
mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom());
}
return mappedRectangleInPoints;
}

Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int height) {
Expand Down Expand Up @@ -4380,7 +4438,8 @@ public void sendPostExternalEventDispatchEvent () {
*/
public void setCursorLocation (int x, int y) {
checkDevice ();
setCursorLocationInPixels (DPIUtil.autoScaleUp (x), DPIUtil.autoScaleUp (y));
Point cursorLocationInPixels = getLocationInPixelsInDisplayCoordinateSystem(x, y);
setCursorLocationInPixels (cursorLocationInPixels.x, cursorLocationInPixels.y);
}

void setCursorLocationInPixels (int x, int y) {
Expand Down Expand Up @@ -5306,4 +5365,27 @@ private void setProperDPIAwareness() {
}
}

Monitor getContainingMonitor(int x, int y) {
Monitor[] monitors = getMonitors();
for (Monitor currentMonitor : monitors) {
Rectangle clientArea = currentMonitor.getClientArea();
if (clientArea.contains(x, y)) {
return currentMonitor;
}
}
return getPrimaryMonitor();
}

Monitor getContainingMonitorInPixelsCoordiate(int xInPixels, int yInPixels) {
Monitor[] monitors = getMonitors();
for (Monitor current : monitors) {
Rectangle clientArea = DPIUtil.scaleUp(current.getClientArea(), DPIUtil.getZoomForAutoscaleProperty(current.zoom));
clientArea.x = current.clientX;
clientArea.y = current.clientY;
if (clientArea.contains(xInPixels, yInPixels)) {
return current;
}
}
return getPrimaryMonitor();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,50 @@ public void setAlpha (int alpha) {
}
}

@Override
public Rectangle getBounds() {
Rectangle boundsInPixels = getBoundsInPixels ();
Rectangle bounds = DPIUtil.scaleDown(boundsInPixels, getZoom());
Point pointWithMonitorOffset = display.getLocationInPointInDisplayCoordinateSystem(boundsInPixels.x, boundsInPixels.y);
bounds.x = pointWithMonitorOffset.x;
bounds.y = pointWithMonitorOffset.y;
return bounds;
}

@Override
public Point getLocation() {
Point locationInPixels = getLocationInPixels();
Point location = display.getLocationInPointInDisplayCoordinateSystem(locationInPixels.x, locationInPixels.y);
return location;
}

@Override
public void setLocation(Point location) {
if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
location = display.getLocationInPixelsInDisplayCoordinateSystem(location.x, location.y);
setLocationInPixels(location.x, location.y);
}

@Override
public void setLocation(int x, int y) {
Point location = display.getLocationInPixelsInDisplayCoordinateSystem(x, y);
setLocationInPixels(location.x, location.y);
}

@Override
public void setBounds(Rectangle rect) {
if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
setBounds(rect.x, rect.y, rect.width, rect.height);
}

@Override
public void setBounds(int x, int y, int width2, int height2) {
Point topLeft = display.getLocationInPixelsInDisplayCoordinateSystem(x, y);
int width = DPIUtil.scaleUp(width2, getZoom());
int height = DPIUtil.scaleUp(height2, getZoom());
setBoundsInPixels(topLeft.x, topLeft.y, width, height);
}

@Override
void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) {
if (fullScreen) setFullScreen (false);
Expand Down

0 comments on commit 697b845

Please sign in to comment.