From 169fa75620d5ed601690d557a1179b2b9ced3d21 Mon Sep 17 00:00:00 2001 From: Thomas Singer Date: Tue, 19 Nov 2024 16:24:47 +0100 Subject: [PATCH] #1596: GC, Path: fix misalignment of scaled lines When drawing a vertical line at x == 1 with 200% zoom level (HiDPI), MacOS draws it on the physical pixel coordinates 2 and 3 while on Windows (with the existing code) it was drawn at 1 and 2. In other words: the existing code drew lines 1 pixel too far left/top. This commit should resolve this. --- .../org/eclipse/swt/internal/DPIUtil.java | 8 ++++ .../win32/org/eclipse/swt/graphics/GC.java | 43 ++++++++++--------- .../win32/org/eclipse/swt/graphics/Path.java | 39 +++++++++-------- 3 files changed, 52 insertions(+), 38 deletions(-) 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 5171bf5cf96..9676ea04cc6 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 @@ -400,6 +400,10 @@ public static int autoScaleUp(Drawable drawable, int size) { return scaleUp(drawable, size, deviceZoom); } +public static int scaleUpXY(Drawable drawable, int size, int zoom) { + return scaleUp(drawable, size + 1, zoom) - 1; +} + public static int scaleUp(Drawable drawable, int size, int zoom) { if (drawable != null && !drawable.isAutoScalable()) return size; return scaleUp (size, zoom); @@ -419,6 +423,10 @@ public static float autoScaleUp(Drawable drawable, float size) { return scaleUp(drawable, size, deviceZoom); } +public static float scaleUpXY(Drawable drawable, float size, int zoom) { + return scaleUp(drawable, size + 1, zoom) - 1; +} + public static float scaleUp(Drawable drawable, float size, int zoom) { if (drawable != null && !drawable.isAutoScalable()) return size; return scaleUp (size, zoom); 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 43eabea38f2..d15b6b93dca 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 @@ -1644,10 +1644,10 @@ void drawBitmapColor(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe */ public void drawLine (int x1, int y1, int x2, int y2) { int deviceZoom = getZoom(); - x1 = DPIUtil.scaleUp (drawable, x1, deviceZoom); - x2 = DPIUtil.scaleUp (drawable, x2, deviceZoom); - y1 = DPIUtil.scaleUp (drawable, y1, deviceZoom); - y2 = DPIUtil.scaleUp (drawable, y2, deviceZoom); + x1 = scaleUpXY (x1, deviceZoom); + x2 = scaleUpXY (x2, deviceZoom); + y1 = scaleUpXY (y1, deviceZoom); + y2 = scaleUpXY (y2, deviceZoom); drawLineInPixels(x1, y1, x2, y2); } @@ -1911,8 +1911,8 @@ 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); + x = scaleUpXY (x, deviceZoom); + y = scaleUpXY (y, deviceZoom); width = DPIUtil.scaleUp (drawable, width, deviceZoom); height = DPIUtil.scaleUp (drawable, height, deviceZoom); drawRectangleInPixels(x, y, width, height); @@ -1997,8 +1997,8 @@ 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); + x = scaleUpXY (x, deviceZoom); + y = scaleUpXY (y, deviceZoom); width = DPIUtil.scaleUp (drawable, width, deviceZoom); height = DPIUtil.scaleUp (drawable, height, deviceZoom); arcWidth = DPIUtil.scaleUp (drawable, arcWidth, deviceZoom); @@ -2095,8 +2095,8 @@ void drawRoundRectangleGdip (long gdipGraphics, long pen, int x, int y, int widt */ public void drawString (String string, int x, int y) { int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); + x = scaleUpXY(x, deviceZoom); + y = scaleUpXY(y, deviceZoom); drawStringInPixels(string, x, y, false); } @@ -2129,8 +2129,8 @@ public void drawString (String string, int x, int y) { */ public void drawString (String string, int x, int y, boolean isTransparent) { int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); + x = scaleUpXY(x, deviceZoom); + y = scaleUpXY(y, deviceZoom); drawStringInPixels(string, x, y, isTransparent); } @@ -2221,8 +2221,8 @@ void drawStringInPixels (String string, int x, int y, boolean isTransparent) { */ public void drawText (String string, int x, int y) { int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); + x = scaleUpXY(x, deviceZoom); + y = scaleUpXY(y, deviceZoom); drawTextInPixels(string, x, y); } @@ -2256,8 +2256,8 @@ void drawTextInPixels (String string, int x, int y) { */ public void drawText (String string, int x, int y, boolean isTransparent) { int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); + x = scaleUpXY(x, deviceZoom); + y = scaleUpXY(y, deviceZoom); drawTextInPixels(string, x, y, isTransparent); } @@ -2308,8 +2308,8 @@ void drawTextInPixels (String string, int x, int y, boolean isTransparent) { */ public void drawText (String string, int x, int y, int flags) { int deviceZoom = getZoom(); - x = DPIUtil.scaleUp(drawable, x, deviceZoom); - y = DPIUtil.scaleUp(drawable, y, deviceZoom); + x = scaleUpXY(x, deviceZoom); + y = scaleUpXY(y, deviceZoom); drawTextInPixels(string, x, y, flags); } @@ -2688,8 +2688,8 @@ public boolean equals (Object object) { */ 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); + x = scaleUpXY (x, deviceZoom); + y = scaleUpXY (y, deviceZoom); width = DPIUtil.scaleUp (drawable, width, deviceZoom); height = DPIUtil.scaleUp (drawable, height, deviceZoom); fillArcInPixels(x, y, width, height, startAngle, arcAngle); @@ -5163,4 +5163,7 @@ private int getZoom() { return DPIUtil.getZoomForAutoscaleProperty(data.nativeZoom); } +private int scaleUpXY(int xy, int deviceZoom) { + return DPIUtil.scaleUpXY (drawable, xy, deviceZoom); +} } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java index bcd482b549c..fa153d054df 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java @@ -209,8 +209,8 @@ private Path(Device device, PathData data, int zoom) { public void addArc (float x, float y, float width, float height, float startAngle, float arcAngle) { if (width == 0 || height == 0 || arcAngle == 0) return; Drawable drawable = getDevice(); - x = DPIUtil.scaleUp(drawable, x, initialZoom); - y = DPIUtil.scaleUp(drawable, y, initialZoom); + x = scaleUpXY(drawable, x); + y = scaleUpXY(drawable, y); width = DPIUtil.scaleUp(drawable, width, initialZoom); height = DPIUtil.scaleUp(drawable, height, initialZoom); addArcInPixels(x, y, width, height, startAngle, arcAngle); @@ -312,8 +312,8 @@ void addRectangleInPixels(float x, float y, float width, float height) { */ public void addString (String string, float x, float y, Font font) { Drawable drawable = getDevice(); - x = DPIUtil.scaleUp(drawable, x, initialZoom); - y = DPIUtil.scaleUp(drawable, y, initialZoom); + x = scaleUpXY(drawable, x); + y = scaleUpXY(drawable, y); addStringInPixels(string, x, y, font); } void addStringInPixels(String string, float x, float y, Font font) { @@ -384,8 +384,8 @@ public void close() { */ public boolean contains (float x, float y, GC gc, boolean outline) { Drawable drawable = getDevice(); - x = DPIUtil.scaleUp(drawable, x, initialZoom); - y = DPIUtil.scaleUp(drawable, y, initialZoom); + x = scaleUpXY(drawable, x); + y = scaleUpXY(drawable, y); return containsInPixels(x, y, gc, outline); } boolean containsInPixels(float x, float y, GC gc, boolean outline) { @@ -420,12 +420,12 @@ boolean containsInPixels(float x, float y, GC gc, boolean outline) { */ public void cubicTo (float cx1, float cy1, float cx2, float cy2, float x, float y) { Drawable drawable = getDevice(); - cx1 = DPIUtil.scaleUp(drawable, cx1, initialZoom); - cy1 = DPIUtil.scaleUp(drawable, cy1, initialZoom); - cx2 = DPIUtil.scaleUp(drawable, cx2, initialZoom); - cy2 = DPIUtil.scaleUp(drawable, cy2, initialZoom); - x = DPIUtil.scaleUp(drawable, x, initialZoom); - y = DPIUtil.scaleUp(drawable, y, initialZoom); + cx1 = scaleUpXY(drawable, cx1); + cy1 = scaleUpXY(drawable, cy1); + cx2 = scaleUpXY(drawable, cx2); + cy2 = scaleUpXY(drawable, cy2); + x = scaleUpXY(drawable, x); + y = scaleUpXY(drawable, y); cubicToInPixels(cx1, cy1, cx2, cy2, x, y); } @@ -591,7 +591,7 @@ PathData getPathDataInPixels() { */ public void lineTo (float x, float y) { Drawable drawable = getDevice(); - lineToInPixels(DPIUtil.scaleUp(drawable, x, initialZoom), DPIUtil.scaleUp(drawable, y, initialZoom)); + lineToInPixels(scaleUpXY(drawable, x), scaleUpXY(drawable, y)); } void lineToInPixels(float x, float y) { @@ -656,7 +656,7 @@ public boolean isDisposed() { */ public void moveTo (float x, float y) { Drawable drawable = getDevice(); - moveToInPixels(DPIUtil.scaleUp(drawable, x, initialZoom), DPIUtil.scaleUp(drawable, y, initialZoom)); + moveToInPixels(scaleUpXY(drawable, x), scaleUpXY(drawable, y)); } void moveToInPixels(float x, float y) { @@ -680,10 +680,10 @@ void moveToInPixels(float x, float y) { */ public void quadTo (float cx, float cy, float x, float y) { Drawable drawable = getDevice(); - cx = DPIUtil.scaleUp(drawable, cx, initialZoom); - cy = DPIUtil.scaleUp(drawable, cy, initialZoom); - x = DPIUtil.scaleUp(drawable, x, initialZoom); - y = DPIUtil.scaleUp(drawable, y, initialZoom); + cx = scaleUpXY(drawable, cx); + cy = scaleUpXY(drawable, cy); + x = scaleUpXY(drawable, x); + y = scaleUpXY(drawable, y); quadToInPixels(cx, cy, x, y); } @@ -718,4 +718,7 @@ long getHandle(int zoom) { return zoomLevelToHandle.get(zoom); } +private float scaleUpXY(Drawable drawable, float xy) { + return DPIUtil.scaleUpXY(drawable, xy, initialZoom); +} }