Skip to content

Commit 43f1a89

Browse files
committed
Streamline rounding for rectangles and add rounding mode to them
For the float-aware Point class, a rounding mode has been introduced to store in which way the Point needs to be rounded when necessary. For rectangles, this has not been implemented yet and is added by this change. It also correct the way in which rectangle values are rounded by considering the top-left and bottom-right corner instead of top-left corner and width/height, also done in the Win32DPIUtils. So it streamlines the rounding behavior in Win32DPIUtils and the Rectangle class to uniformly scale the upper left and bottom right corner of a rectangle. The changes also makes proper use of the floating-precision coordinates in the point/pixel conversions for rectangles in the Win32DPIUtils.
1 parent 27f1d6c commit 43f1a89

File tree

3 files changed

+67
-45
lines changed

3 files changed

+67
-45
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public void setY(float y) {
177177

178178
@Override
179179
public Point.OfFloat clone() {
180-
return new Point.OfFloat(getX(), getY());
180+
return new Point.OfFloat(getX(), getY(), roundingMode);
181181
}
182182

183183
/**

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

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public Rectangle (int x, int y, int width, int height) {
8686
this.height = height;
8787
}
8888

89+
private Rectangle() {
90+
}
91+
8992
/**
9093
* Destructively replaces the x, y, width and height values
9194
* in the receiver with ones which represent the union of the
@@ -411,16 +414,25 @@ public static sealed class OfFloat extends Rectangle permits Rectangle.WithMonit
411414

412415
private float residualX, residualY, residualWidth, residualHeight;
413416

417+
private RoundingMode locationRounding = RoundingMode.ROUND;
418+
419+
private RoundingMode sizeRounding = RoundingMode.ROUND;
420+
414421
public OfFloat(int x, int y, int width, int height) {
415422
super(x, y, width, height);
416423
}
417424

418425
public OfFloat(float x, float y, float width, float height) {
419-
super(Math.round(x), Math.round(y), Math.round(width), Math.round(height));
420-
this.residualX = x - this.x;
421-
this.residualY = y - this.y;
422-
this.residualWidth = width - this.width;
423-
this.residualHeight = height - this.height;
426+
this(x, y, width, height, RoundingMode.ROUND, RoundingMode.ROUND);
427+
}
428+
429+
public OfFloat(float x, float y, float width, float height, RoundingMode locationRounding, RoundingMode sizeRounding) {
430+
this.locationRounding = locationRounding;
431+
this.sizeRounding = sizeRounding;
432+
setX(x);
433+
setY(y);
434+
setWidth(width);
435+
setHeight(height);
424436
}
425437

426438
public float getX() {
@@ -440,28 +452,38 @@ public float getHeight() {
440452
}
441453

442454
public void setX(float x) {
443-
this.x = Math.round(x);
455+
this.x = locationRounding.round(x);
444456
this.residualX = x - this.x;
457+
setWidth(getWidth());
445458
}
446459

447460
public void setY(float y) {
448-
this.y = Math.round(y);
461+
this.y = locationRounding.round(y);
449462
this.residualY = y - this.y;
463+
setHeight(getHeight());
450464
}
451465

452466
public void setWidth(float width) {
453-
this.width = Math.round(width);
467+
this.width = sizeRounding.round(width + getX()) - x;
454468
this.residualWidth = width - this.width;
455469
}
456470

457471
public void setHeight(float height) {
458-
this.height = Math.round(height);
472+
this.height = sizeRounding.round(height + getY()) - y;
459473
this.residualHeight = height - this.height;
460474
}
461475

476+
public Point.OfFloat getTopLeft() {
477+
return new Point.OfFloat(getX(), getY(), locationRounding);
478+
}
479+
480+
public Point.OfFloat getBottomRight() {
481+
return new Point.OfFloat(getX() + getWidth(), getY() + getHeight(), sizeRounding);
482+
}
483+
462484
@Override
463485
public Rectangle.OfFloat clone() {
464-
return new Rectangle.OfFloat(getX(), getY(), getWidth(), getHeight());
486+
return new Rectangle.OfFloat(getX(), getY(), getWidth(), getHeight(), locationRounding, sizeRounding);
465487
}
466488

467489
/**

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

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,31 @@ public static Point pixelToPointAsConservativeSize(Point point, int zoom) {
137137

138138
private static Point pixelToPoint(Point point, int zoom, RoundingMode mode) {
139139
if (zoom == 100 || point == null) return point;
140-
Point.OfFloat fPoint = Point.OfFloat.from(point);
140+
Point.OfFloat floatPoint = Point.OfFloat.from(point);
141+
return pixelToPoint(new Point.OfFloat(floatPoint.getX(), floatPoint.getY(), mode), zoom);
142+
}
143+
144+
private static Point.OfFloat pixelToPoint(Point.OfFloat point, int zoom) {
145+
Point.OfFloat scaledPoint = point.clone();
141146
float scaleFactor = DPIUtil.getScalingFactor(zoom);
142-
float scaledX = fPoint.getX() / scaleFactor;
143-
float scaledY = fPoint.getY() / scaleFactor;
144-
return new Point.OfFloat(scaledX, scaledY, mode);
147+
scaledPoint.setX(point.getX() / scaleFactor);
148+
scaledPoint.setY(point.getY() / scaleFactor);
149+
return scaledPoint;
145150
}
146151

147152
public static Rectangle pixelToPoint(Rectangle rect, int zoom) {
148153
if (zoom == 100 || rect == null) return rect;
149-
if (rect instanceof Rectangle.OfFloat rectOfFloat) return pixelToPoint(rectOfFloat, zoom);
150-
Rectangle scaledRect = new Rectangle.OfFloat (0,0,0,0);
151-
Point scaledTopLeft = pixelToPointAsLocation(new Point (rect.x, rect.y), zoom);
152-
Point scaledBottomRight = pixelToPointAsSize(new Point (rect.x + rect.width, rect.y + rect.height), zoom);
153-
154-
scaledRect.x = scaledTopLeft.x;
155-
scaledRect.y = scaledTopLeft.y;
156-
scaledRect.width = scaledBottomRight.x - scaledTopLeft.x;
157-
scaledRect.height = scaledBottomRight.y - scaledTopLeft.y;
154+
Rectangle.OfFloat floatRect = Rectangle.OfFloat.from(rect);
155+
Point.OfFloat scaledTopLeft = pixelToPoint(floatRect.getTopLeft(), zoom);
156+
Point.OfFloat scaledBottomRight = pixelToPoint(floatRect.getBottomRight(), zoom);
157+
Rectangle.OfFloat scaledRect = floatRect.clone();
158+
scaledRect.setX(scaledTopLeft.getX());
159+
scaledRect.setY(scaledTopLeft.getY());
160+
scaledRect.setWidth(scaledBottomRight.getX() - scaledTopLeft.getX());
161+
scaledRect.setHeight(scaledBottomRight.getY() - scaledTopLeft.getY());
158162
return scaledRect;
159163
}
160164

161-
private static Rectangle pixelToPoint(Rectangle.OfFloat rect, int zoom) {
162-
return scaleBounds(rect, 100, zoom);
163-
}
164-
165165
public static Rectangle pixelToPoint(Drawable drawable, Rectangle rect, int zoom) {
166166
if (drawable != null && !drawable.isAutoScalable()) return rect;
167167
return pixelToPoint (rect, zoom);
@@ -229,11 +229,16 @@ public static float pointToPixel(Drawable drawable, float size, int zoom) {
229229

230230
private static Point pointToPixel(Point point, int zoom, RoundingMode mode) {
231231
if (zoom == 100 || point == null) return point;
232-
Point.OfFloat fPoint = Point.OfFloat.from(point);
232+
Point.OfFloat floatPoint = Point.OfFloat.from(point);
233+
return pointToPixel(new Point.OfFloat(floatPoint.getX(), floatPoint.getY(), mode), zoom);
234+
}
235+
236+
private static Point.OfFloat pointToPixel(Point.OfFloat point, int zoom) {
237+
Point.OfFloat scaledPoint = point.clone();
233238
float scaleFactor = DPIUtil.getScalingFactor(zoom);
234-
float scaledX = fPoint.getX() * scaleFactor;
235-
float scaledY = fPoint.getY() * scaleFactor;
236-
return new Point.OfFloat(scaledX, scaledY, mode);
239+
scaledPoint.setX(point.getX() * scaleFactor);
240+
scaledPoint.setY(point.getY() * scaleFactor);
241+
return scaledPoint;
237242
}
238243

239244
public static Point pointToPixelAsSize(Drawable drawable, Point point, int zoom) {
@@ -256,22 +261,17 @@ public static Point pointToPixelAsLocation(Point point, int zoom) {
256261

257262
public static Rectangle pointToPixel(Rectangle rect, int zoom) {
258263
if (zoom == 100 || rect == null) return rect;
259-
if (rect instanceof Rectangle.OfFloat rectOfFloat) return pointToPixel(rectOfFloat, zoom);
260-
Rectangle scaledRect = new Rectangle.OfFloat(0,0,0,0);
261-
Point scaledTopLeft = pointToPixelAsLocation (new Point(rect.x, rect.y), zoom);
262-
Point scaledBottomRight = pointToPixelAsLocation (new Point(rect.x + rect.width, rect.y + rect.height), zoom);
263-
264-
scaledRect.x = scaledTopLeft.x;
265-
scaledRect.y = scaledTopLeft.y;
266-
scaledRect.width = scaledBottomRight.x - scaledTopLeft.x;
267-
scaledRect.height = scaledBottomRight.y - scaledTopLeft.y;
264+
Rectangle.OfFloat floatRect = Rectangle.OfFloat.from(rect);
265+
Point.OfFloat scaledTopLeft = pointToPixel(floatRect.getTopLeft(), zoom);
266+
Point.OfFloat scaledBottomRight = pointToPixel(floatRect.getBottomRight(), zoom);
267+
Rectangle.OfFloat scaledRect = floatRect.clone();
268+
scaledRect.setX(scaledTopLeft.getX());
269+
scaledRect.setY(scaledTopLeft.getY());
270+
scaledRect.setWidth(scaledBottomRight.getX() - scaledTopLeft.getX());
271+
scaledRect.setHeight(scaledBottomRight.getY() - scaledTopLeft.getY());
268272
return scaledRect;
269273
}
270274

271-
private static Rectangle pointToPixel(Rectangle.OfFloat rect, int zoom) {
272-
return scaleBounds(rect, zoom, 100);
273-
}
274-
275275
public static Rectangle pointToPixel(Drawable drawable, Rectangle rect, int zoom) {
276276
if (drawable != null && !drawable.isAutoScalable()) return rect;
277277
return pointToPixel (rect, zoom);

0 commit comments

Comments
 (0)