From 00f05476377c431784b406730728117f640fa669 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Tue, 7 Apr 2026 18:53:18 +0200 Subject: [PATCH] [GTK] Consider transformation scale in GC.drawImage(image, x, y) #2919 With e97143c7b058d66315d22d67f778188530af32ab, support was added on Windows to take the `Transform` scaling into consideration when calling `drawImage(image,x,y)`. Especially when used in combination with an SVG-based image, this leads to better results as the best-fitting image is used for painting, rather than relying on interpolation. This change follows a similar logic to what has been done for Windows; The call to `drawImage(image,x,y)` is delegated to `drawImage(x,y,w,h)` when a `Transform` has been set. Within this method, the width and height of the image are used as size after being multiplied by the transformation scale. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/2919 --- .../gtk/org/eclipse/swt/graphics/GC.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 5d358be4b1..b103276517 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -190,6 +190,18 @@ public GC(Drawable drawable, int style) { init(); } +private float calculateTransformationScale() { + if (currentTransform == null) { + return 1.0f; + } + // this calculates the effective length in x and y + // direction without being affected by the rotation + // of the transformation + float scaleWidth = (float) Math.hypot(currentTransform[0], currentTransform[2]); + float scaleHeight = (float) Math.hypot(currentTransform[1], currentTransform[3]); + return Math.max(scaleWidth, scaleHeight); +} + /** * Ensure that the style specified is either LEFT_TO_RIGHT or RIGHT_TO_LEFT. * @@ -791,7 +803,12 @@ public void drawImage(Image image, int x, int y) { if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - drawImage(image, 0, 0, -1, -1, x, y, -1, -1, true); + if (currentTransform != null && !isIdentity(currentTransform)) { + Rectangle imageBounds = image.getBounds(); + drawImage(image, x, y, imageBounds.width, imageBounds.height); + } else { + drawImage(image, 0, 0, -1, -1, x, y, -1, -1, true); + } } /** @@ -886,7 +903,10 @@ public void drawImage(Image image, int destX, int destY, int destWidth, int dest if (image.isDisposed()) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } - image.executeOnImageAtSize(imageAtSize -> drawImage(imageAtSize, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false), destWidth, destHeight); + float transformationScale = calculateTransformationScale(); + int scaledWidth = Math.round(destWidth * transformationScale); + int scaledHeight = Math.round(destHeight * transformationScale); + image.executeOnImageAtSize(imageAtSize -> drawImage(imageAtSize, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false), scaledWidth, scaledHeight); } void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {