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 937a9015367..36ac78c00c5 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 @@ -18,6 +18,7 @@ import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.gdip.*; import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.widgets.*; /** * Class GC is where all of the drawing capabilities that are @@ -133,6 +134,14 @@ public final class GC extends Resource { */ public GC(Drawable drawable) { this(drawable, SWT.NONE); + if(drawable instanceof Widget) { + data.deviceZoom = ((Widget) drawable).zoom; + if (drawable instanceof Control) { + data.nativeDeviceZoom = ((Control) drawable).getShell().nativeZoom; + } + } else if(drawable instanceof Image) { + data.deviceZoom = ((Image) drawable).currentDeviceZoom; + } } /** @@ -455,8 +464,9 @@ void checkGC(int mask) { * */ public void copyArea (Image image, int x, int y) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); copyAreaInPixels(image, x, y); } @@ -511,12 +521,13 @@ 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) { - srcX = DPIUtil.autoScaleUp(drawable, srcX); - srcY = DPIUtil.autoScaleUp(drawable, srcY); - width = DPIUtil.autoScaleUp(drawable, width); - height = DPIUtil.autoScaleUp(drawable, height); - destX = DPIUtil.autoScaleUp(drawable, destX); - destY = DPIUtil.autoScaleUp(drawable, destY); + int deviceZoom = getDeviceZoom(); + srcX = DPIUtil.autoScaleUp(drawable, srcX, deviceZoom); + srcY = DPIUtil.autoScaleUp(drawable, srcY, deviceZoom); + width = DPIUtil.autoScaleUp(drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp(drawable, height, deviceZoom); + destX = DPIUtil.autoScaleUp(drawable, destX, deviceZoom); + destY = DPIUtil.autoScaleUp(drawable, destY, deviceZoom); copyAreaInPixels(srcX, srcY, width, height, destX, destY, paint); } @@ -757,10 +768,11 @@ void disposeGdip() { * */ public void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); - width = DPIUtil.autoScaleUp(drawable, width); - height = DPIUtil.autoScaleUp(drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp(drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp(drawable, height, deviceZoom); drawArcInPixels(x, y, width, height, startAngle, arcAngle); } @@ -840,10 +852,11 @@ 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) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); drawFocusInPixels(x, y, width, height); } @@ -918,8 +931,9 @@ void drawFocusInPixels (int x, int y, int width, int height) { * */ public void drawImage (Image image, int x, int y) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawImageInPixels(image, x, y); } @@ -971,9 +985,9 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei if (image == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Rectangle src = DPIUtil.autoScaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight)); - Rectangle dest = DPIUtil.autoScaleUp(drawable, new Rectangle(destX, destY, destWidth, destHeight)); - int deviceZoom = DPIUtil.getDeviceZoom(); + int deviceZoom = getDeviceZoom(); + Rectangle src = DPIUtil.autoScaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), deviceZoom); + Rectangle dest = DPIUtil.autoScaleUp(drawable, new Rectangle(destX, destY, destWidth, destHeight), deviceZoom); if (deviceZoom != 100) { /* * This is a HACK! Due to rounding errors at fractional scale factors, @@ -1640,10 +1654,11 @@ void drawBitmapColor(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe * */ public void drawLine (int x1, int y1, int x2, int y2) { - x1 = DPIUtil.autoScaleUp (drawable, x1); - x2 = DPIUtil.autoScaleUp (drawable, x2); - y1 = DPIUtil.autoScaleUp (drawable, y1); - y2 = DPIUtil.autoScaleUp (drawable, y2); + int deviceZoom = getDeviceZoom(); + x1 = DPIUtil.autoScaleUp (drawable, x1, deviceZoom); + x2 = DPIUtil.autoScaleUp (drawable, x2, deviceZoom); + y1 = DPIUtil.autoScaleUp (drawable, y1, deviceZoom); + y2 = DPIUtil.autoScaleUp (drawable, y2, deviceZoom); drawLineInPixels(x1, y1, x2, y2); } @@ -1692,10 +1707,11 @@ void drawLineInPixels (int x1, int y1, int x2, int y2) { * */ public void drawOval (int x, int y, int width, int height) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); drawOvalInPixels(x, y, width, height); } @@ -1768,8 +1784,9 @@ public void drawPath (Path path) { * @since 3.0 */ public void drawPoint (int x, int y) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); drawPointInPixels(x, y); } @@ -1802,7 +1819,7 @@ void drawPointInPixels (int x, int y) { */ public void drawPolygon (int[] pointArray) { if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - drawPolygonInPixels(DPIUtil.autoScaleUp(drawable, pointArray)); + drawPolygonInPixels(DPIUtil.autoScaleUp(drawable, pointArray, getDeviceZoom())); } void drawPolygonInPixels(int[] pointArray) { @@ -1850,7 +1867,7 @@ void drawPolygonInPixels(int[] pointArray) { * */ public void drawPolyline (int[] pointArray) { - drawPolylineInPixels(DPIUtil.autoScaleUp(drawable, pointArray)); + drawPolylineInPixels(DPIUtil.autoScaleUp(drawable, pointArray, getDeviceZoom())); } void drawPolylineInPixels(int[] pointArray) { @@ -1903,10 +1920,11 @@ void drawPolylineInPixels(int[] pointArray) { * */ public void drawRectangle (int x, int y, int width, int height) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); drawRectangleInPixels(x, y, width, height); } @@ -1962,7 +1980,7 @@ void drawRectangleInPixels (int x, int y, int width, int height) { */ public void drawRectangle (Rectangle rect) { if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - rect = DPIUtil.autoScaleUp(drawable, rect); + rect = DPIUtil.autoScaleUp(drawable, rect, getDeviceZoom()); drawRectangleInPixels(rect.x, rect.y, rect.width, rect.height); } @@ -1988,12 +2006,13 @@ public void drawRectangle (Rectangle rect) { * */ public void drawRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); - arcWidth = DPIUtil.autoScaleUp (drawable, arcWidth); - arcHeight = DPIUtil.autoScaleUp (drawable, arcHeight); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); + arcWidth = DPIUtil.autoScaleUp (drawable, arcWidth, deviceZoom); + arcHeight = DPIUtil.autoScaleUp (drawable, arcHeight, deviceZoom); drawRoundRectangleInPixels(x, y, width, height, arcWidth, arcHeight); } @@ -2085,8 +2104,9 @@ void drawRoundRectangleGdip (long gdipGraphics, long pen, int x, int y, int widt * */ public void drawString (String string, int x, int y) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawStringInPixels(string, x, y, false); } @@ -2118,8 +2138,9 @@ public void drawString (String string, int x, int y) { * */ public void drawString (String string, int x, int y, boolean isTransparent) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawStringInPixels(string, x, y, isTransparent); } @@ -2209,8 +2230,9 @@ void drawStringInPixels (String string, int x, int y, boolean isTransparent) { * */ public void drawText (String string, int x, int y) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawTextInPixels(string, x, y); } @@ -2243,8 +2265,9 @@ void drawTextInPixels (String string, int x, int y) { * */ public void drawText (String string, int x, int y, boolean isTransparent) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawTextInPixels(string, x, y, isTransparent); } @@ -2294,8 +2317,9 @@ void drawTextInPixels (String string, int x, int y, boolean isTransparent) { * */ public void drawText (String string, int x, int y, int flags) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); drawTextInPixels(string, x, y, flags); } @@ -2673,10 +2697,11 @@ public boolean equals (Object object) { * @see #drawArc */ public void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); fillArcInPixels(x, y, width, height, startAngle, arcAngle); } @@ -2752,10 +2777,11 @@ 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) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); fillGradientRectangleInPixels(x, y, width, height, vertical); } @@ -2870,10 +2896,11 @@ void fillGradientRectangleInPixels(int x, int y, int width, int height, boolean * @see #drawOval */ public void fillOval (int x, int y, int width, int height) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); fillOvalInPixels(x, y, width, height); } @@ -2943,7 +2970,7 @@ public void fillPath (Path path) { */ public void fillPolygon (int[] pointArray) { if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - fillPolygonInPixels(DPIUtil.autoScaleUp(drawable, pointArray)); + fillPolygonInPixels(DPIUtil.autoScaleUp(drawable, pointArray, getDeviceZoom())); } void fillPolygonInPixels (int[] pointArray) { @@ -2992,10 +3019,11 @@ void fillPolygonInPixels (int[] pointArray) { * @see #drawRectangle(int, int, int, int) */ public void fillRectangle (int x, int y, int width, int height) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); fillRectangleInPixels(x, y, width, height); } @@ -3035,7 +3063,7 @@ void fillRectangleInPixels (int x, int y, int width, int height) { */ public void fillRectangle (Rectangle rect) { if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - rect = DPIUtil.autoScaleUp(drawable, rect); + rect = DPIUtil.autoScaleUp(drawable, rect, getDeviceZoom()); fillRectangleInPixels(rect.x, rect.y, rect.width, rect.height); } @@ -3057,12 +3085,13 @@ public void fillRectangle (Rectangle rect) { * @see #drawRoundRectangle */ public void fillRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) { - x = DPIUtil.autoScaleUp (drawable, x); - y = DPIUtil.autoScaleUp (drawable, y); - width = DPIUtil.autoScaleUp (drawable, width); - height = DPIUtil.autoScaleUp (drawable, height); - arcWidth = DPIUtil.autoScaleUp (drawable, arcWidth); - arcHeight = DPIUtil.autoScaleUp (drawable, arcHeight); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp (drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp (drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp (drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp (drawable, height, deviceZoom); + arcWidth = DPIUtil.autoScaleUp (drawable, arcWidth, deviceZoom); + arcHeight = DPIUtil.autoScaleUp (drawable, arcHeight, deviceZoom); fillRoundRectangleInPixels(x, y, width, height, arcWidth, arcHeight); } @@ -3321,7 +3350,7 @@ public int getCharWidth(char ch) { * */ public Rectangle getClipping () { - return DPIUtil.autoScaleDown(drawable, getClippingInPixels()); + return DPIUtil.autoScaleDown(drawable, getClippingInPixels(), getDeviceZoom()); } Rectangle getClippingInPixels() { @@ -3579,9 +3608,10 @@ public int getInterpolation() { */ public LineAttributes getLineAttributes () { LineAttributes attributes = getLineAttributesInPixels(); - attributes.width = DPIUtil.autoScaleDown(drawable, attributes.width); + int deviceZoom = getDeviceZoom(); + attributes.width = DPIUtil.autoScaleDown(drawable, attributes.width, deviceZoom); if(attributes.dash != null) { - attributes.dash = DPIUtil.autoScaleDown(drawable, attributes.dash); + attributes.dash = DPIUtil.autoScaleDown(drawable, attributes.dash, deviceZoom); } return attributes; } @@ -3630,8 +3660,9 @@ public int[] getLineDash() { if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (data.lineDashes == null) return null; int[] lineDashes = new int[data.lineDashes.length]; + int deviceZoom = getDeviceZoom(); for (int i = 0; i < lineDashes.length; i++) { - lineDashes[i] = DPIUtil.autoScaleDown(drawable, (int)data.lineDashes[i]); + lineDashes[i] = DPIUtil.autoScaleDown(drawable, (int)data.lineDashes[i], deviceZoom); } return lineDashes; } @@ -3684,7 +3715,7 @@ public int getLineStyle() { * */ public int getLineWidth () { - return DPIUtil.autoScaleDown(drawable, getLineWidthInPixels()); + return DPIUtil.autoScaleDown(drawable, getLineWidthInPixels(), getDeviceZoom()); } int getLineWidthInPixels() { @@ -3887,6 +3918,7 @@ long identity() { void init(Drawable drawable, GCData data, long hDC) { int foreground = data.foreground; + this.data = data; if (foreground != -1) { data.state &= ~(FOREGROUND | FOREGROUND_TEXT | PEN); } else { @@ -3920,7 +3952,6 @@ void init(Drawable drawable, GCData data, long hDC) { if ((data.style & SWT.RIGHT_TO_LEFT) != 0) data.style |= SWT.MIRRORED; } this.drawable = drawable; - this.data = data; handle = hDC; } @@ -4242,10 +4273,11 @@ void setClipping(long clipRgn) { * */ public void setClipping (int x, int y, int width, int height) { - x = DPIUtil.autoScaleUp(drawable, x); - y = DPIUtil.autoScaleUp(drawable, y); - width = DPIUtil.autoScaleUp(drawable, width); - height = DPIUtil.autoScaleUp(drawable, height); + int deviceZoom = getDeviceZoom(); + x = DPIUtil.autoScaleUp(drawable, x, deviceZoom); + y = DPIUtil.autoScaleUp(drawable, y, deviceZoom); + width = DPIUtil.autoScaleUp(drawable, width, deviceZoom); + height = DPIUtil.autoScaleUp(drawable, height, deviceZoom); setClippingInPixels(x, y, width, height); } @@ -4313,7 +4345,7 @@ public void setClipping (Rectangle rect) { setClipping(0); } else { - rect = DPIUtil.autoScaleUp(drawable, rect); + rect = DPIUtil.autoScaleUp(drawable, rect, getDeviceZoom()); setClippingInPixels(rect.x, rect.y, rect.width, rect.height); } } @@ -4386,7 +4418,7 @@ public void setFillRule(int rule) { public void setFont (Font font) { if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (font != null && font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - data.font = font != null ? Font.win32_new(font, DPIUtil.getNativeDeviceZoom()) : data.device.systemFont; + data.font = font != null ? Font.win32_new(font, getNativeDeviceZoom()) : data.device.systemFont; data.state &= ~FONT; } @@ -4519,7 +4551,7 @@ public void setInterpolation(int interpolation) { */ public void setLineAttributes (LineAttributes attributes) { if (attributes == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - attributes.width = DPIUtil.autoScaleUp(drawable, attributes.width); + attributes.width = DPIUtil.autoScaleUp(drawable, attributes.width, getDeviceZoom()); setLineAttributesInPixels(attributes); } @@ -4582,8 +4614,9 @@ void setLineAttributesInPixels (LineAttributes attributes) { } if (changed) { float[] newDashes = new float[dashes.length]; + int deviceZoom = getDeviceZoom(); for (int i = 0; i < newDashes.length; i++) { - newDashes[i] = DPIUtil.autoScaleUp(drawable, dashes[i]); + newDashes[i] = DPIUtil.autoScaleUp(drawable, dashes[i], deviceZoom); } dashes = newDashes; mask |= LINE_STYLE; @@ -4671,9 +4704,10 @@ public void setLineDash(int[] dashes) { if (dashes != null && dashes.length > 0) { boolean changed = data.lineStyle != SWT.LINE_CUSTOM || lineDashes == null || lineDashes.length != dashes.length; float[] newDashes = new float[dashes.length]; + int deviceZoom = getDeviceZoom(); for (int i = 0; i < dashes.length; i++) { if (dashes[i] <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - newDashes[i] = DPIUtil.autoScaleUp(drawable, (float) dashes[i]); + newDashes[i] = DPIUtil.autoScaleUp(drawable, (float) dashes[i], deviceZoom); if (!changed && lineDashes[i] != newDashes[i]) changed = true; } if (!changed) return; @@ -4774,7 +4808,7 @@ public void setLineStyle(int lineStyle) { * */ public void setLineWidth(int lineWidth) { - lineWidth = DPIUtil.autoScaleUp (drawable, lineWidth); + lineWidth = DPIUtil.autoScaleUp (drawable, lineWidth, getDeviceZoom()); setLineWidthInPixels(lineWidth); } @@ -4920,7 +4954,7 @@ public void setTransform(Transform transform) { */ public Point stringExtent (String string) { if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return DPIUtil.autoScaleDown(drawable, stringExtentInPixels(string)); + return DPIUtil.autoScaleDown(drawable, stringExtentInPixels(string), getDeviceZoom()); } Point stringExtentInPixels (String string) { @@ -4965,7 +4999,7 @@ Point stringExtentInPixels (String string) { * */ public Point textExtent (String string) { - return DPIUtil.autoScaleDown(drawable, textExtentInPixels(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB)); + return DPIUtil.autoScaleDown(drawable, textExtentInPixels(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB), getDeviceZoom()); } /** @@ -5000,7 +5034,7 @@ public Point textExtent (String string) { * */ public Point textExtent (String string, int flags) { - return DPIUtil.autoScaleDown(drawable, textExtentInPixels(string, flags)); + return DPIUtil.autoScaleDown(drawable, textExtentInPixels(string, flags), getDeviceZoom()); } Point textExtentInPixels(String string, int flags) { @@ -5120,4 +5154,12 @@ private static int sin(int angle, int length) { return (int)(Math.sin(angle * (Math.PI/180)) * length); } +private int getNativeDeviceZoom() { + return data.nativeDeviceZoom != 0 ? data.nativeDeviceZoom : DPIUtil.getNativeDeviceZoom(); +} + +private int getDeviceZoom() { + return data.deviceZoom != 0 ? data.deviceZoom : DPIUtil.getDeviceZoom(); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java index fa177db2c83..5950045742d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java @@ -15,6 +15,7 @@ import org.eclipse.swt.*; +import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.win32.*; /** @@ -47,6 +48,8 @@ public final class GCData { public float[] lineDashes; public float lineMiterLimit = 10; public int alpha = 0xFF; + public int deviceZoom; + public int nativeDeviceZoom; public Image image; public PAINTSTRUCT ps; @@ -57,4 +60,9 @@ public final class GCData { public float gdipXOffset, gdipYOffset; public int uiState = 0; public boolean focusDrawn; + + public void setNativeDeviceZoom(int nativeDeviceZoom) { + this.nativeDeviceZoom = nativeDeviceZoom; + this.deviceZoom = DPIUtil.getZoomForAutoscaleProperty(nativeDeviceZoom); + } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 1d6b0be129c..6faaf0fbdc1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -139,7 +139,7 @@ public final class Image extends Resource implements Drawable { /** * Attribute to cache current device zoom level */ - private int currentDeviceZoom = 100; + int currentDeviceZoom = 100; /** * width of the image diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java index abd6169da7b..e338cd22d4c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java @@ -1519,6 +1519,7 @@ LRESULT WM_PAINT (long wParam, long lParam) { long hBufferedPaint = OS.BeginBufferedPaint (hDC, prcTarget, flags, null, phdc); GCData data = new GCData (); data.device = display; + data.setNativeDeviceZoom(getShell().getNativeZoom()); data.foreground = getForegroundPixel (); Control control = findBackgroundControl (); if (control == null) control = this; @@ -1547,6 +1548,7 @@ LRESULT WM_PAINT (long wParam, long lParam) { /* Create the paint GC */ GCData data = new GCData (); + data.setNativeDeviceZoom(getShell().getNativeZoom()); data.ps = ps; data.hwnd = handle; GC gc = GC.win32_new (this, data); @@ -1581,6 +1583,7 @@ LRESULT WM_PAINT (long wParam, long lParam) { paintGC = gc; gc = new GC (image, paintGC.getStyle() & SWT.RIGHT_TO_LEFT); GCData gcData = gc.getGCData (); + gcData.setNativeDeviceZoom(getShell().getNativeZoom()); gcData.uiState = data.uiState; gc.setForeground (getForeground ()); gc.setBackground (getBackground ()); 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 abfd251dd13..f09ad1c95a4 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 @@ -3657,6 +3657,14 @@ public void setRedraw (boolean redraw) { } } +@Override +void sendEvent(int eventType, Event event, boolean send) { + if(event != null && event.gc != null && event.gc.getGCData() != null) { + event.gc.getGCData().setNativeDeviceZoom(getShell().getNativeZoom()); + } + super.sendEvent(eventType, event, send); +} + /** * Sets the shape of the control to the region specified * by the argument. When the argument is null, the diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java index 366b2b32e95..a9176826b4e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java @@ -563,6 +563,7 @@ void wmDrawChildImage(DRAWITEMSTRUCT struct) { } GCData data = new GCData(); + data.setNativeDeviceZoom(getShell().getNativeZoom()); data.device = display; GC gc = GC.win32_new (struct.hDC, data); Image image = getEnabled () ? this.image : new Image (display, this.image, SWT.IMAGE_DISABLE); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java index c31e9e84486..555b74d827a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java @@ -125,7 +125,20 @@ public class Shell extends Decorations { ToolTip [] toolTips; long hwndMDIClient, lpstrTip, toolTipHandle, balloonTipHandle, menuItemToolTipHandle; int minWidth = SWT.DEFAULT, minHeight = SWT.DEFAULT, maxWidth = SWT.DEFAULT, maxHeight = SWT.DEFAULT; - private int nativeZoom; + /** + * the native zoom of the monitor the shell is drawn on + * (Warning: This field is platform dependent) + *

+ * IMPORTANT: This field is not part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It is not available on all + * platforms and should never be accessed from application code. + *

+ * + * @noreference This field is not intended to be referenced by clients. + * @since 3.126 + */ + public int nativeZoom; long [] brushes; boolean showWithParent, fullScreen, wasMaximized, modified, center; String toolTitle, balloonTitle; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java index 65f9903a143..58fda2e4995 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java @@ -831,6 +831,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) { int nSavedDC = OS.SaveDC (hDC); GCData data = new GCData (); data.device = display; + data.setNativeDeviceZoom(getShell().getNativeZoom()); data.font = item.getFont (index); data.foreground = OS.GetTextColor (hDC); data.background = OS.GetBkColor (hDC); @@ -1050,6 +1051,7 @@ LRESULT CDDS_ITEMPREPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) { } int nSavedDC = OS.SaveDC (hDC); GCData data = new GCData (); + data.setNativeDeviceZoom(getShell().getNativeZoom()); data.device = display; if (selected && explorerTheme) { data.foreground = OS.GetSysColor (OS.COLOR_WINDOWTEXT); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java index 1fcf440f448..42a16ec55fe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java @@ -52,7 +52,20 @@ */ public abstract class Widget { - private int zoom; + /** + * the zoom level of the widget + * (Warning: This field is platform dependent) + *

+ * IMPORTANT: This field is not part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It is not available on all + * platforms and should never be accessed from application code. + *

+ * + * @noreference This field is not intended to be referenced by clients. + * @since 3.126 + */ + public int zoom; int style, state; Display display; EventTable eventTable; diff --git a/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/graphics/GCWin32Tests.java b/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/graphics/GCWin32Tests.java new file mode 100644 index 00000000000..77bfa1c8ec4 --- /dev/null +++ b/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/graphics/GCWin32Tests.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2024 Yatta Solutions + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Yatta Solutions - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.win32.graphics; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.GCData; +import org.eclipse.swt.internal.DPIUtil; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GCWin32Tests { + private Display display; + private int initialZoom; + + @Before + public void setUp() { + initialZoom = DPIUtil.getDeviceZoom(); + display = Display.getDefault(); + DPIUtil.setDeviceZoom(100); + } + + @After + public void tearDown() { + DPIUtil.setDeviceZoom(initialZoom); + } + + @Test + public void gcZoomLevelMustChangeOnShellZoomChange() { + int zoom = DPIUtil.getDeviceZoom(); + Shell shell = new Shell(display); + shell.addListener(SWT.Paint, event -> { + assertEquals("GCData must have a zoom level equal to the actual zoom level of the widget/shell", shell.zoom, event.gc.getGCData().deviceZoom); + }); + shell.addListener(SWT.ZoomChanged, event -> { + assertEquals("GCData must have a zoom level equal to the actual zoom level of the widget/shell on zoomChanged event", shell.zoom, event.gc.getGCData().deviceZoom); + }); + shell.open(); + int newSWTZoom = zoom * 2; + Event swtEvent = new Event(); + swtEvent.type = SWT.ZoomChanged; + swtEvent.gc = GC.win32_new(shell, new GCData()); + swtEvent.widget = shell; + DPIUtil.setDeviceZoom(newSWTZoom); + shell.zoom = newSWTZoom; + shell.nativeZoom = DPIUtil.getZoomForAutoscaleProperty(newSWTZoom); + shell.notifyListeners(SWT.ZoomChanged, swtEvent); + } + + @Test + public void drawnElementsShouldScaleUpToTheRightZoomLevel() { + int zoom = DPIUtil.getDeviceZoom(); + int scalingFactor = 2; + Shell shell = new Shell(display); + GC gc = GC.win32_new(shell, new GCData()); + gc.getGCData().deviceZoom = zoom * scalingFactor; + gc.getGCData().lineWidth = 10; + assertEquals("DPIUtil calls with getDeviceZoom should scale to the right value", gc.getGCData().lineWidth, gc.getLineWidth() * scalingFactor, 0); + } + +}