Skip to content

Commit 55b5adf

Browse files
HeikoKlareakoch-yatta
authored andcommitted
[Win32] Fix cut off controls #2641
In HiDPI scenarios with fractional monitor scales (such as 125% and 175%), some controls appear slightly cut off. The reason for this is inconsistent rounding of control sizes. The rounding is necessary during pixel/point conversion and leads to added or lost single pixels. One controls which obviously shows the behavior is the border of CTabFolders. This change adapts the calculation in the following way: - It ensures that pixelToPoint and pointToPixel conversions for sizes round in opposite ways instead of rounding up in both directions as currently done. This ensures that sizes being set (via pointToPixel) are rounded up while sizes being retrieved (via pixelToPoint) are rounded down. - It extracts the pixelToPoint conversion for sizes that are calculated based on pixel values and are supposed to represent a conservative size (i.e., better be to high than to low). - It ensures that also the pixelToPoint conversion of rectangles takes the proper rounding method for sizes into account. Fixes #2641
1 parent cf6ee39 commit 55b5adf

File tree

5 files changed

+13
-6
lines changed

5 files changed

+13
-6
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/RoundingMode.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @noreference This class is not intended to be referenced by clients
44
*/
55
public enum RoundingMode {
6-
ROUND, UP;
6+
ROUND, UP, DOWN;
77

88
public int round(float x) {
99
if (this == ROUND) {
@@ -12,6 +12,9 @@ public int round(float x) {
1212
if (this == UP) {
1313
return (int) Math.ceil(x);
1414
}
15+
if (this == DOWN) {
16+
return (int) Math.floor(x);
17+
}
1518
return (int) x;
1619
}
1720
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,17 @@ public static Point pixelToPointAsLocation(Drawable drawable, Point point, int z
124124
}
125125

126126
public static Point pixelToPointAsSize(Point point, int zoom) {
127-
return pixelToPoint(point, zoom, RoundingMode.UP);
127+
return pixelToPoint(point, zoom, RoundingMode.DOWN);
128128
}
129129

130130
public static Point pixelToPointAsLocation(Point point, int zoom) {
131131
return pixelToPoint(point, zoom, RoundingMode.ROUND);
132132
}
133133

134+
public static Point pixelToPointAsConservativeSize(Point point, int zoom) {
135+
return pixelToPoint(point, zoom, RoundingMode.UP);
136+
}
137+
134138
private static Point pixelToPoint(Point point, int zoom, RoundingMode mode) {
135139
if (zoom == 100 || point == null) return point;
136140
Point.OfFloat fPoint = Point.OfFloat.from(point);
@@ -145,7 +149,7 @@ public static Rectangle pixelToPoint(Rectangle rect, int zoom) {
145149
if (rect instanceof Rectangle.OfFloat rectOfFloat) return pixelToPoint(rectOfFloat, zoom);
146150
Rectangle scaledRect = new Rectangle.OfFloat (0,0,0,0);
147151
Point scaledTopLeft = pixelToPointAsLocation(new Point (rect.x, rect.y), zoom);
148-
Point scaledBottomRight = pixelToPointAsLocation(new Point (rect.x + rect.width, rect.y + rect.height), zoom);
152+
Point scaledBottomRight = pixelToPointAsSize(new Point (rect.x + rect.width, rect.y + rect.height), zoom);
149153

150154
scaledRect.x = scaledTopLeft.x;
151155
scaledRect.y = scaledTopLeft.y;

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ public Point computeSize (int wHint, int hHint, boolean changed){
623623
hHint = (hHint != SWT.DEFAULT ? DPIUtil.pointToPixel(hHint, zoom) : hHint);
624624
//We should never return a size that is to small, RoundingMode.UP ensures we at worst case report
625625
//a size that is a bit too large by half a point
626-
return Win32DPIUtils.pixelToPointAsSize(computeSizeInPixels(wHint, hHint, changed), zoom);
626+
return Win32DPIUtils.pixelToPointAsConservativeSize(computeSizeInPixels(wHint, hHint, changed), zoom);
627627
}
628628

629629
Point computeSizeInPixels (int wHint, int hHint, boolean changed) {

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoolItem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public Point computeSize (int wHint, int hHint) {
188188
int zoom = getZoom();
189189
wHint = (wHint != SWT.DEFAULT ? DPIUtil.pointToPixel(wHint, zoom) : wHint);
190190
hHint = (hHint != SWT.DEFAULT ? DPIUtil.pointToPixel(hHint, zoom) : hHint);
191-
return Win32DPIUtils.pixelToPointAsSize(computeSizeInPixels(wHint, hHint), zoom);
191+
return Win32DPIUtils.pixelToPointAsConservativeSize(computeSizeInPixels(wHint, hHint), zoom);
192192
}
193193
Point computeSizeInPixels (int wHint, int hHint) {
194194
int index = parent.indexOf (this);

tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/Win32DPIUtilTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void scaleDownPoint() {
103103
@Test
104104
public void scaleDownRectangle() {
105105
Rectangle valueAt200 = new Rectangle(100, 150, 10, 14);
106-
Rectangle valueAt150 = new Rectangle(75, 113, 7, 10);
106+
Rectangle valueAt150 = new Rectangle(75, 113, 8, 10);
107107
Rectangle valueAt100 = new Rectangle(50, 75, 5, 7);
108108

109109
Rectangle scaledValue = Win32DPIUtils.pixelToPoint(valueAt200, 200);

0 commit comments

Comments
 (0)