Skip to content

[GTK] Consider transformation scale in GC.drawImage(image, x, y) #2919#3201

Open
ptziegler wants to merge 1 commit intoeclipse-platform:masterfrom
ptziegler:gc-transform
Open

[GTK] Consider transformation scale in GC.drawImage(image, x, y) #2919#3201
ptziegler wants to merge 1 commit intoeclipse-platform:masterfrom
ptziegler:gc-transform

Conversation

@ptziegler
Copy link
Copy Markdown
Contributor

With e97143c, 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
#2919

…pse-platform#2919

With e97143c, 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
eclipse-platform#2919
@ptziegler
Copy link
Copy Markdown
Contributor Author

A side-by-side comparison of how this change affects GEF:

image

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Test Results (linux)

   88 files  + 3     88 suites  +3   14m 10s ⏱️ -22s
4 557 tests + 1  4 337 ✅ + 2  220 💤 ±0  0 ❌  - 1 
3 275 runs  +37  3 206 ✅ +36   69 💤 +2  0 ❌  - 1 

Results for commit 00f0547. ± Comparison against base commit 9e86574.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates GTK GC#drawImage(...) so that when a Transform with scaling is applied, SWT requests an image rendered at the effective (scaled) destination size, improving best-fit selection for multi-resolution/SVG images (parity with the earlier Windows change).

Changes:

  • Add a helper to compute an effective transformation scale from the current GC transform.
  • Delegate drawImage(image, x, y) to the width/height overload when a non-identity transform is active.
  • Multiply destination dimensions by the transformation scale before calling Image#executeOnImageAtSize(...).

Comment on lines +200 to +201
float scaleWidth = (float) Math.hypot(currentTransform[0], currentTransform[2]);
float scaleHeight = (float) Math.hypot(currentTransform[1], currentTransform[3]);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calculateTransformationScale() appears to use the wrong matrix elements for computing the effective X/Y scale. SWT/Cairo transforms are stored as {m11, m12, m21, m22, dx, dy} (see Transform#getElements), where the unit X basis vector maps to (m11, m12) and the unit Y basis vector maps to (m21, m22). Using hypot(currentTransform[0], currentTransform[2]) / hypot(currentTransform[1], currentTransform[3]) computes row lengths, which does vary with rotation when scaling is non-uniform, so the requested image size can be underestimated. Compute scaleWidth as hypot(m11, m12) and scaleHeight as hypot(m21, m22) instead.

Suggested change
float scaleWidth = (float) Math.hypot(currentTransform[0], currentTransform[2]);
float scaleHeight = (float) Math.hypot(currentTransform[1], currentTransform[3]);
float scaleWidth = (float) Math.hypot(currentTransform[0], currentTransform[1]);
float scaleHeight = (float) Math.hypot(currentTransform[2], currentTransform[3]);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am quite sure we have evaluated how to properly do this calculation when doing the implementation for Windows. The Transform representation does not differ between Windows and Linux, so in case this concern is correct, the Windows implementation would probably have to be changed as well.

Comment on lines 802 to +811
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);
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduces transform-aware image-size selection on GTK for drawImage(image, x, y) and drawImage(image, destX, destY, destWidth, destHeight), but there doesn’t appear to be a corresponding automated regression test enabled for GTK/Linux. There is already a Windows-only JUnit test for this behavior in Test_org_eclipse_swt_graphics_GC#test_drawImage..._withTransform; consider adding/expanding a test so the GTK implementation is exercised as well (especially for SVG-backed images).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@HeikoKlare HeikoKlare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks sound to me. The comment regarding tests made by Copilot seems valid. There are two test cases in Test...GC, one is even missing an @Test annotation, so we could take the chance of properly enabling it. The other is @EnabledOnOS(OS.WINDOWS), which we now may change to @DisabledOnOS(OS.MAC) until we have applied the same change to macOS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants