Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Comment on lines +200 to +201
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.

return Math.max(scaleWidth, scaleHeight);
}

/**
* Ensure that the style specified is either LEFT_TO_RIGHT <b>or</b> RIGHT_TO_LEFT.
*
Expand Down Expand Up @@ -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);
}
}

/**
Expand Down Expand Up @@ -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) {
Expand Down
Loading