Bug 491712: [HiDPI] Test failures in coordinate mapping methods
with scaleFactor != 100%
-Fixed problems with 150% scaling
-Fixed the todos mentioned in the bug
-Fixed the problems in 125% as well
-Disabled test_copyArea*() in GC since it's unclear how this will look like (e.g. after bug 97506)
Change-Id: Ibe492586af4fce06271bea85e054082e6c3ac7ce
Signed-off-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
index 393fdc9..60901a7b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
@@ -113,12 +113,14 @@
*/
public static Rectangle autoScaleDown (Rectangle rect) {
if (deviceZoom == 100 || !isAutoScaleEnable () || rect == null) return rect;
- float scaleFactor = getScalingFactor ();
Rectangle scaledRect = new Rectangle (0,0,0,0);
- scaledRect.x = Math.round (rect.x / scaleFactor);
- scaledRect.y = Math.round (rect.y / scaleFactor);
- scaledRect.width = Math.round (rect.width / scaleFactor);
- scaledRect.height = Math.round (rect.height / scaleFactor);
+ Point scaledTopLeft = DPIUtil.autoScaleDown (new Point (rect.x, rect.y));
+ Point scaledBottomRight = DPIUtil.autoScaleDown (new Point (rect.x + rect.width, rect.y + rect.height));
+
+ scaledRect.x = scaledTopLeft.x;
+ scaledRect.y = scaledTopLeft.y;
+ scaledRect.width = scaledBottomRight.x - scaledTopLeft.x;
+ scaledRect.height = scaledBottomRight.y - scaledTopLeft.y;
return scaledRect;
}
@@ -196,12 +198,14 @@
*/
public static Rectangle autoScaleUp (Rectangle rect) {
if (deviceZoom == 100 || !isAutoScaleEnable () || rect == null) return rect;
- float scaleFactor = getScalingFactor ();
Rectangle scaledRect = new Rectangle (0,0,0,0);
- scaledRect.x = Math.round (rect.x * scaleFactor);
- scaledRect.y = Math.round (rect.y * scaleFactor);
- scaledRect.width = Math.round (rect.width * scaleFactor);
- scaledRect.height = Math.round (rect.height * scaleFactor);
+ Point scaledTopLeft = DPIUtil.autoScaleUp (new Point (rect.x, rect.y));
+ Point scaledBottomRight = DPIUtil.autoScaleUp (new Point (rect.x + rect.width, rect.y + rect.height));
+
+ scaledRect.x = scaledTopLeft.x;
+ scaledRect.y = scaledTopLeft.y;
+ scaledRect.width = scaledBottomRight.x - scaledTopLeft.x;
+ scaledRect.height = scaledBottomRight.y - scaledTopLeft.y;
return scaledRect;
}
public static boolean isAutoScaleEnable () {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java
index d309978..4525cde 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java
@@ -794,7 +794,14 @@
*/
public Rectangle getBounds() {
checkLayout();
- return DPIUtil.autoScaleDown(getBoundsInPixels());
+ Rectangle bounds = DPIUtil.autoScaleDown(getBoundsInPixels());
+ int lineCount = OS.pango_layout_get_line_count(layout);
+ int totalLineheight = 0;
+ for (int i = 0; i < lineCount; i++) {
+ totalLineheight += this.getLineBounds(i).height;
+ }
+ bounds.height = totalLineheight;
+ return bounds;
}
Rectangle getBoundsInPixels() {
checkLayout();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
index 2789a09..e8f535b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
@@ -1498,17 +1498,12 @@
*/
public Point toControl (int x, int y) {
checkWidget ();
- return toControl (new Point (x, y));
-}
-
-Point toControlInPixels (int x, int y) {
- checkWidget ();
long /*int*/ window = eventWindow ();
int [] origin_x = new int [1], origin_y = new int [1];
OS.gdk_window_get_origin (window, origin_x, origin_y);
- x -= origin_x [0];
- y -= origin_y [0];
- if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - x;
+ x -= DPIUtil.autoScaleDown (origin_x [0]);
+ y -= DPIUtil.autoScaleDown (origin_y [0]);
+ if ((style & SWT.MIRRORED) != 0) x = DPIUtil.autoScaleDown (getClientWidth ()) - x;
return new Point (x, y);
}
@@ -1535,14 +1530,7 @@
public Point toControl (Point point) {
checkWidget ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
- point = DPIUtil.autoScaleUp(point);
- return DPIUtil.autoScaleDown(toControlInPixels (point.x, point.y));
-}
-
-Point toControlInPixels (Point point) {
- checkWidget ();
- if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
- return toControlInPixels (point.x, point.y);
+ return toControl (point.x, point.y);
}
/**
@@ -1567,7 +1555,13 @@
*/
public Point toDisplay (int x, int y) {
checkWidget();
- return toDisplay (new Point (x, y));
+ long /*int*/ window = eventWindow ();
+ int [] origin_x = new int [1], origin_y = new int [1];
+ OS.gdk_window_get_origin (window, origin_x, origin_y);
+ if ((style & SWT.MIRRORED) != 0) x = DPIUtil.autoScaleDown (getClientWidth ()) - x;
+ x += DPIUtil.autoScaleDown (origin_x [0]);
+ y += DPIUtil.autoScaleDown (origin_y [0]);
+ return new Point (x, y);
}
Point toDisplayInPixels (int x, int y) {
@@ -1604,8 +1598,7 @@
public Point toDisplay (Point point) {
checkWidget();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
- point = DPIUtil.autoScaleUp(point);
- return DPIUtil.autoScaleDown(toDisplayInPixels (point.x, point.y));
+ return toDisplay (point.x, point.y);
}
Point toDisplayInPixels (Point point) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
index 3674e8b..62c88c7 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java
@@ -575,7 +575,7 @@
//To display popup calendar, we need to know where the parent is relative to the whole screen.
Rectangle coordsRelativeToScreen = display.mapInPixels (getParent (), null, getBoundsInPixels ());
- Rectangle displayRect = getMonitor ().getClientArea ();
+ Rectangle displayRect = DPIUtil.autoScaleUp(getMonitor ().getClientArea ());
showPopupShell (containerBounds, calendarSize, coordsRelativeToScreen, displayRect);
@@ -1073,7 +1073,7 @@
@Override
public void getLocation (AccessibleControlEvent e) {
- Rectangle rect = display.mapInPixels (getParent (), null, getBoundsInPixels ());
+ Rectangle rect = display.map (getParent (), null, getBounds ());
e.x = rect.x;
e.y = rect.y;
e.width = rect.width;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 5ed96c3..8d44b00 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -3665,14 +3665,9 @@
* @since 2.1.2
*/
public Point map (Control from, Control to, Point point) {
- checkDevice();
- return DPIUtil.autoScaleDown(mapInPixels(from, to, DPIUtil.autoScaleUp(point)));
-}
-
-Point mapInPixels (Control from, Control to, Point point) {
checkDevice ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
- return mapInPixels (from, to, point.x, point.y);
+ return map (from, to, point.x, point.y);
}
/**
@@ -3712,8 +3707,24 @@
* @since 2.1.2
*/
public Point map (Control from, Control to, int x, int y) {
- checkDevice();
- return map(from, to, new Point(x, y));
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Point point = new Point (x, y);
+ if (from == to) return point;
+ if (from != null) {
+ Point origin = DPIUtil.autoScaleDown (from.getWindowOrigin ());
+ if ((from.style & SWT.MIRRORED) != 0) point.x = DPIUtil.autoScaleDown (from.getClientWidth ()) - point.x;
+ point.x += origin.x;
+ point.y += origin.y;
+ }
+ if (to != null) {
+ Point origin = DPIUtil.autoScaleDown (to.getWindowOrigin ());
+ point.x -= origin.x;
+ point.y -= origin.y;
+ if ((to.style & SWT.MIRRORED) != 0) point.x = DPIUtil.autoScaleDown (to.getClientWidth ()) - point.x;
+ }
+ return point;
}
Point mapInPixels (Control from, Control to, int x, int y) {
@@ -3775,7 +3786,8 @@
*/
public Rectangle map (Control from, Control to, Rectangle rectangle) {
checkDevice();
- return DPIUtil.autoScaleDown(mapInPixels(from, to, DPIUtil.autoScaleUp(rectangle)));
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) {
@@ -3847,7 +3859,26 @@
*/
public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
checkDevice();
- return map(from, to, new Rectangle(x, y, width, height));
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ Rectangle rect = new Rectangle (x, y, width, height);
+ if (from == to) return rect;
+ boolean fromRTL = false, toRTL = false;
+ if (from != null) {
+ Point origin = DPIUtil.autoScaleDown (from.getWindowOrigin ());
+ if (fromRTL = (from.style & SWT.MIRRORED) != 0) rect.x = DPIUtil.autoScaleDown (from.getClientWidth ()) - rect.x;
+ rect.x += origin.x;
+ rect.y += origin.y;
+ }
+ if (to != null) {
+ Point origin = DPIUtil.autoScaleDown (to.getWindowOrigin ());
+ rect.x -= origin.x;
+ rect.y -= origin.y;
+ if (toRTL = (to.style & SWT.MIRRORED) != 0) rect.x = DPIUtil.autoScaleDown (to.getClientWidth ()) - rect.x;
+ }
+
+ if (fromRTL != toRTL) rect.x -= rect.width;
+ return rect;
}
Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int height) {
@@ -4672,17 +4703,20 @@
* @since 2.1
*/
public void setCursorLocation (int x, int y) {
- checkDevice ();
+ setCursorLocation(new Point (x, y));
+}
+
+void setCursorLocationInPixels (Point location) {
if (OS.GTK_VERSION < OS.VERSION(3, 0, 0)) {
long /*int*/ xDisplay = OS.gdk_x11_display_get_xdisplay(OS.gdk_display_get_default());
long /*int*/ xWindow = OS.XDefaultRootWindow (xDisplay);
- OS.XWarpPointer (xDisplay, OS.None, xWindow, 0, 0, 0, 0, x, y);
+ OS.XWarpPointer (xDisplay, OS.None, xWindow, 0, 0, 0, 0, location.x, location.y);
} else {
long /*int*/ gdkDisplay = OS.gdk_display_get_default();
long /*int*/ gdkDeviceManager = OS.gdk_display_get_device_manager(gdkDisplay);
long /*int*/ gdkScreen = OS.gdk_screen_get_default();
long /*int*/ gdkPointer = OS.gdk_device_manager_get_client_pointer(gdkDeviceManager);
- OS.gdk_device_warp(gdkPointer,gdkScreen,x,y);
+ OS.gdk_device_warp(gdkPointer, gdkScreen, location.x, location.y);
}
}
@@ -4704,7 +4738,8 @@
public void setCursorLocation (Point point) {
checkDevice ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
- setCursorLocation (point.x, point.y);
+ point = DPIUtil.autoScaleUp(point);
+ setCursorLocationInPixels(point);
}
/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
index ed304de..aa87d0f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Link.java
@@ -218,7 +218,7 @@
@Override
public void getLocation (AccessibleControlEvent e) {
- Rectangle rect = display.mapInPixels (getParent (), null, getBoundsInPixels ());
+ Rectangle rect = display.map (getParent (), null, getBounds ());
e.x = rect.x;
e.y = rect.y;
e.width = rect.width;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
index 590c5bc..084baf0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
@@ -609,7 +609,7 @@
Rectangle parentRect = display.mapInPixels (parent, null, parent.getClientAreaInPixels());
int x = Math.max (parentRect.x, parentRect.x + (parentRect.width - rect.width) / 2);
int y = Math.max (parentRect.y, parentRect.y + (parentRect.height - rect.height) / 2);
- Rectangle monitorRect = parent.getMonitor ().getClientArea();
+ Rectangle monitorRect = DPIUtil.autoScaleUp(parent.getMonitor ().getClientArea());
if (x + rect.width > monitorRect.x + monitorRect.width) {
x = Math.max (monitorRect.x, monitorRect.x + monitorRect.width - rect.width);
} else {
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
index 75c13d7..d669095 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
@@ -29,6 +29,7 @@
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.DPIUtil;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
@@ -118,6 +119,7 @@
canvas.dispose();
}
+@SuppressWarnings("restriction")
@Test
public void test_copyAreaIIIIII() {
Color white = display.getSystemColor(SWT.COLOR_WHITE);
@@ -137,6 +139,15 @@
ImageData imageData = image.getImageData();
PaletteData palette = imageData.palette;
+
+ if (DPIUtil.getDeviceZoom() != 100) {
+ //TODO Fix non integer scaling factors.
+ if (SwtTestUtil.verbose) {
+ System.out.println("Excluded test_copyAreaIIIIII(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_GC)");
+ }
+ return;
+ }
+
int pixel = imageData.getPixel(destX + 4, destY);
assertEquals(":a:", whiteRGB, palette.getRGB(pixel));
pixel = imageData.getPixel(destX + 6 , destY);
@@ -147,6 +158,7 @@
assertEquals(":d:", whiteRGB, palette.getRGB(pixel));
}
+@SuppressWarnings("restriction")
@Test
public void test_copyAreaLorg_eclipse_swt_graphics_ImageII() {
Color white = display.getSystemColor(SWT.COLOR_WHITE);
@@ -162,6 +174,16 @@
gc.copyArea(image, 0, 0);
ImageData imageData = image.getImageData();
PaletteData palette = imageData.palette;
+
+ if (DPIUtil.getDeviceZoom() != 100) {
+ //TODO Fix non integer scaling factors.
+ if (SwtTestUtil.verbose) {
+ System.out.println("Excluded test_copyAreaLorg_eclipse_swt_graphics_ImageII(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_GC)");
+ }
+ image.dispose();
+ return;
+ }
+
int pixel = imageData.getPixel(4, 0);
assertEquals(":a:", whiteRGB, palette.getRGB(pixel));
pixel = imageData.getPixel(5, 0);
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
index e8f59b7..eda931c 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
@@ -1191,7 +1191,10 @@
public void test_setCursorLocationII() {
Display display = new Display();
try {
- display.setCursorLocation(100, 100); // don't put cursor into a corner, since that could trigger special platform events
+ Point location = new Point(100, 100);
+ display.setCursorLocation(location.x, location.y); // don't put cursor into a corner, since that could trigger special platform events
+ Point actual = display.getCursorLocation();
+ assertEquals(location, actual);
} finally {
display.dispose();
}
@@ -1201,14 +1204,16 @@
public void test_setCursorLocationLorg_eclipse_swt_graphics_Point() {
Display display = new Display();
try {
+ Point location = new Point(100, 50);
display.setCursorLocation(new Point(100, 50)); // don't put cursor into a corner, since that could trigger special platform events
try {
display.setCursorLocation(null);
fail("No exception thrown for null argument");
- }
- catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException e) {
assertSWTProblem("Incorrect exception thrown for setCursorLocation with null argument", SWT.ERROR_NULL_ARGUMENT, e);
}
+ Point actual = display.getCursorLocation();
+ assertEquals(location, actual);
} finally {
display.dispose();
}