diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java index b1a026ca92c..4afb5256959 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java @@ -16,6 +16,7 @@ import java.io.*; +import org.eclipse.swt.internal.*; import org.eclipse.swt.widgets.*; /** @@ -135,8 +136,8 @@ public OfFloat(int x, int y) { super(x, y); } - public OfFloat(float x, float y) { - super(Math.round(x), Math.round(y)); + public OfFloat(float x, float y, RoundingMode mode) { + super(mode.round(x), mode.round(y)); this.residualX = x - this.x; this.residualY = y - this.y; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/RoundingMode.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/RoundingMode.java new file mode 100644 index 00000000000..1f2774d2272 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/RoundingMode.java @@ -0,0 +1,17 @@ +package org.eclipse.swt.internal; +/** +* @noreference This class is not intended to be referenced by clients +*/ +public enum RoundingMode { + ROUND, UP; + +int round(float x) { + if (this == ROUND) { + return Math.round(x); + } + if (this == UP) { + return (int) Math.ceil(x); + } + return (int) x; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java index fb27d92d90d..bfbfc9b0a1e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java @@ -114,12 +114,17 @@ public static float pixelToPoint(Drawable drawable, float size, int zoom) { } public static Point pixelToPoint(Point point, int zoom) { + //TODO actually all callers should explicitly state what mode the want! + return pixelToPoint(point, zoom, RoundingMode.ROUND); + } + + public static Point pixelToPoint(Point point, int zoom, RoundingMode mode) { if (zoom == 100 || point == null) return point; Point.OfFloat fPoint = FloatAwareGeometryFactory.createFrom(point); float scaleFactor = DPIUtil.getScalingFactor(zoom); float scaledX = fPoint.getX() / scaleFactor; float scaledY = fPoint.getY() / scaleFactor; - return new Point.OfFloat(scaledX, scaledY); + return new Point.OfFloat(scaledX, scaledY, mode); } public static Point pixelToPoint(Drawable drawable, Point point, int zoom) { @@ -225,7 +230,7 @@ public static Point pointToPixel(Point point, int zoom) { float scaleFactor = DPIUtil.getScalingFactor(zoom); float scaledX = fPoint.getX() * scaleFactor; float scaledY = fPoint.getY() * scaleFactor; - return new Point.OfFloat(scaledX, scaledY); + return new Point.OfFloat(scaledX, scaledY, RoundingMode.ROUND); } public static Point pointToPixel(Drawable drawable, Point point, int zoom) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index 709f8aada02..a666b49ec71 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -620,7 +620,9 @@ public Point computeSize (int wHint, int hHint, boolean changed){ int zoom = getZoom(); wHint = (wHint != SWT.DEFAULT ? Win32DPIUtils.pointToPixel(wHint, zoom) : wHint); hHint = (hHint != SWT.DEFAULT ? Win32DPIUtils.pointToPixel(hHint, zoom) : hHint); - return Win32DPIUtils.pixelToPoint(computeSizeInPixels(wHint, hHint, changed), zoom); + //We should never return a size that is to small, RoundingMode.UP ensures we at worst case report + //a size that is a bit too large by half a point + return Win32DPIUtils.pixelToPoint(computeSizeInPixels(wHint, hHint, changed), zoom, RoundingMode.UP); } Point computeSizeInPixels (int wHint, int hHint, boolean changed) { @@ -1372,7 +1374,8 @@ public Object getLayoutData () { */ public Point getLocation () { checkWidget (); - return Win32DPIUtils.pixelToPoint(getLocationInPixels(), getZoom()); + //For a location the closest point values is okay + return Win32DPIUtils.pixelToPoint(getLocationInPixels(), getZoom(), RoundingMode.ROUND); } Point getLocationInPixels () { @@ -1528,7 +1531,7 @@ public Shell getShell () { */ public Point getSize (){ checkWidget (); - return Win32DPIUtils.pixelToPoint(getSizeInPixels (), getZoom()); + return Win32DPIUtils.pixelToPoint(getSizeInPixels (), getZoom(), RoundingMode.UP); } Point getSizeInPixels () { @@ -4030,7 +4033,7 @@ public Point toControl (int x, int y) { checkWidget (); Point displayPointInPixels = getDisplay().translateToDisplayCoordinates(new Point(x, y)); final Point controlPointInPixels = toControlInPixels(displayPointInPixels.x, displayPointInPixels.y); - return Win32DPIUtils.pixelToPoint(controlPointInPixels, getZoom()); + return Win32DPIUtils.pixelToPoint(controlPointInPixels, getZoom(), RoundingMode.ROUND); } Point toControlInPixels (int x, int y) {