From 10ed8b5afd1f8f16b4a3e5d58e5361179b971cd7 Mon Sep 17 00:00:00 2001 From: Andreas Koch Date: Fri, 24 Jan 2025 15:40:27 +0100 Subject: [PATCH] [win32] Scale up bounds as rectangle in GC This commit adresses render artifacts visible when drawing on a GC with monitor-specific scaling enabled e.g. on 175%. Reason is that scaling up all attributes of bounds separately can lead to rounding errors e.g. between y and height (one being scaled up, the other one not). Scaling them together as a rectangle solves this limitation. --- .../win32/org/eclipse/swt/graphics/GC.java | 107 +++++------------- 1 file changed, 29 insertions(+), 78 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index 58cfd77a7c2..eed4756214d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -533,14 +533,10 @@ public void copyArea (int srcX, int srcY, int width, int height, int destX, int * @since 3.1 */ public void copyArea (int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) { - int deviceZoom = getZoom(); - srcX = DPIUtil.scaleUp(drawable, srcX, deviceZoom); - srcY = DPIUtil.scaleUp(drawable, srcY, deviceZoom); - width = DPIUtil.scaleUp(drawable, width, deviceZoom); - height = DPIUtil.scaleUp(drawable, height, deviceZoom); - destX = DPIUtil.scaleUp(drawable, destX, deviceZoom); - destY = DPIUtil.scaleUp(drawable, destY, deviceZoom); - copyAreaInPixels(srcX, srcY, width, height, destX, destY, paint); + int zoom = getZoom(); + Rectangle sourceRect = DPIUtil.scaleUp(drawable, new Rectangle(srcX, srcY, width, height), zoom); + Rectangle destRect = DPIUtil.scaleUp(drawable, new Rectangle(destX, destY, width, height), zoom); + copyAreaInPixels(sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height, destRect.x, destRect.y, paint); } void copyAreaInPixels(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) { @@ -780,12 +776,8 @@ void disposeGdip() { * */ public void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); - width = DPIUtil.scaleUp(drawable, width, deviceZoom); - height = DPIUtil.scaleUp(drawable, height, deviceZoom); - drawArcInPixels(x, y, width, height, startAngle, arcAngle); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + drawArcInPixels(rect.x, rect.y, rect.width, rect.height, startAngle, arcAngle); } void drawArcInPixels (int x, int y, int width, int height, int startAngle, int arcAngle) { @@ -864,12 +856,8 @@ void drawArcInPixels (int x, int y, int width, int height, int startAngle, int a * @see #drawRectangle(int, int, int, int) */ public void drawFocus (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - drawFocusInPixels(x, y, width, height); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + drawFocusInPixels(rect.x, rect.y, rect.width, rect.height); } void drawFocusInPixels (int x, int y, int width, int height) { @@ -1717,12 +1705,8 @@ void drawLineInPixels (int x1, int y1, int x2, int y2) { * */ public void drawOval (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - drawOvalInPixels(x, y, width, height); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + drawOvalInPixels(rect.x, rect.y, rect.width, rect.height); } void drawOvalInPixels (int x, int y, int width, int height) { @@ -1931,12 +1915,7 @@ void drawPolylineInPixels(int[] pointArray) { * */ public void drawRectangle (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - drawRectangleInPixels(x, y, width, height); + drawRectangle(new Rectangle(x, y, width, height)); } void drawRectangleInPixels (int x, int y, int width, int height) { @@ -2017,14 +1996,11 @@ public void drawRectangle (Rectangle rect) { * */ public void drawRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - arcWidth = DPIUtil.scaleUp (drawable, arcWidth, deviceZoom); - arcHeight = DPIUtil.scaleUp (drawable, arcHeight, deviceZoom); - drawRoundRectangleInPixels(x, y, width, height, arcWidth, arcHeight); + int zoom = getZoom(); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), zoom); + arcWidth = DPIUtil.scaleUp (drawable, arcWidth, zoom); + arcHeight = DPIUtil.scaleUp (drawable, arcHeight, zoom); + drawRoundRectangleInPixels(rect.x, rect.y, rect.width, rect.height, arcWidth, arcHeight); } void drawRoundRectangleInPixels (int x, int y, int width, int height, int arcWidth, int arcHeight) { @@ -2708,12 +2684,8 @@ public boolean equals (Object object) { * @see #drawArc */ public void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - fillArcInPixels(x, y, width, height, startAngle, arcAngle); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + fillArcInPixels(rect.x, rect.y, rect.width, rect.height, startAngle, arcAngle); } void fillArcInPixels (int x, int y, int width, int height, int startAngle, int arcAngle) { @@ -2788,12 +2760,8 @@ void fillArcInPixels (int x, int y, int width, int height, int startAngle, int a * @see #drawRectangle(int, int, int, int) */ public void fillGradientRectangle (int x, int y, int width, int height, boolean vertical) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - fillGradientRectangleInPixels(x, y, width, height, vertical); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + fillGradientRectangleInPixels(rect.x, rect.y, rect.width, rect.height, vertical); } void fillGradientRectangleInPixels(int x, int y, int width, int height, boolean vertical) { @@ -2907,12 +2875,8 @@ void fillGradientRectangleInPixels(int x, int y, int width, int height, boolean * @see #drawOval */ public void fillOval (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - fillOvalInPixels(x, y, width, height); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), getZoom()); + fillOvalInPixels(rect.x, rect.y, rect.width, rect.height); } void fillOvalInPixels (int x, int y, int width, int height) { @@ -3031,12 +2995,7 @@ void fillPolygonInPixels (int[] pointArray) { * @see #drawRectangle(int, int, int, int) */ public void fillRectangle (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - fillRectangleInPixels(x, y, width, height); + fillRectangle(new Rectangle(x, y, width, height)); } void fillRectangleInPixels (int x, int y, int width, int height) { @@ -3097,14 +3056,11 @@ public void fillRectangle (Rectangle rect) { * @see #drawRoundRectangle */ public void fillRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp (drawable, x, deviceZoom); - y = DPIUtil.scaleUp (drawable, y, deviceZoom); - width = DPIUtil.scaleUp (drawable, width, deviceZoom); - height = DPIUtil.scaleUp (drawable, height, deviceZoom); - arcWidth = DPIUtil.scaleUp (drawable, arcWidth, deviceZoom); - arcHeight = DPIUtil.scaleUp (drawable, arcHeight, deviceZoom); - fillRoundRectangleInPixels(x, y, width, height, arcWidth, arcHeight); + int zoom = getZoom(); + Rectangle rect = DPIUtil.scaleUp(drawable, new Rectangle(x, y, width, height), zoom); + arcWidth = DPIUtil.scaleUp (drawable, arcWidth, zoom); + arcHeight = DPIUtil.scaleUp (drawable, arcHeight, zoom); + fillRoundRectangleInPixels(rect.x, rect.y, rect.width, rect.height, arcWidth, arcHeight); } void fillRoundRectangleInPixels (int x, int y, int width, int height, int arcWidth, int arcHeight) { @@ -4302,12 +4258,7 @@ void setClipping(long clipRgn) { * */ public void setClipping (int x, int y, int width, int height) { - int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); - width = DPIUtil.scaleUp(drawable, width, deviceZoom); - height = DPIUtil.scaleUp(drawable, height, deviceZoom); - setClippingInPixels(x, y, width, height); + setClipping(new Rectangle(x, y, width, height)); } void setClippingInPixels (int x, int y, int width, int height) {