Skip to content

Commit f9c3b63

Browse files
committed
GC#drawImage methods now consider applied Transformations
If a transform is applied via the GC, then both drawImage APIs consider now the best fitting handle by requesting it through the width/height of the full image scaled by the scaleFactor (relating destination width/height to source winowdth/height) times the width/height scaling induced by the transformation.
1 parent af8c805 commit f9c3b63

1 file changed

Lines changed: 39 additions & 22 deletions

File tree

  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d
11931193
return gcZoom;
11941194
}
11951195

1196-
float imageScaleFactor = 1f * destWidth / srcWidth;
1196+
float imageScaleFactor = Math.max(1f * destWidth / srcWidth, 1f * destHeight / srcHeight);
11971197
int imageZoom = Math.round(gcZoom * imageScaleFactor);
11981198
return imageZoom;
11991199
}
@@ -1214,59 +1214,76 @@ void apply() {
12141214
}
12151215
}
12161216

1217+
private float calculateTransformationScale() {
1218+
Transform current = new Transform(device);
1219+
getTransform(current);
1220+
float[] m = new float[6];
1221+
current.getElements(m);
1222+
float scaleWidth = (float) Math.hypot(m[0], m[2]);
1223+
float scaleHeight = (float) Math.hypot(m[1], m[3]);
1224+
current.dispose();
1225+
return Math.max(scaleWidth, scaleHeight);
1226+
}
1227+
12171228
private void drawImage(Image image, int destX, int destY, int destWidth, int destHeight, int imageZoom) {
1218-
Rectangle destPixels= Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX , destY, destWidth , destHeight),
1229+
float transformationScale = calculateTransformationScale();
1230+
int scaledImageZoomWithTransform = Math.round(transformationScale * imageZoom);
1231+
Rectangle destPixels = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX , destY, destWidth , destHeight),
12191232
imageZoom);
1233+
Rectangle destPixelsScaledWithTransform = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX , destY, destWidth , destHeight),
1234+
scaledImageZoomWithTransform);
12201235

12211236
image.executeOnImageHandleAtBestFittingSize(tempHandle -> {
12221237
drawImage(image, 0, 0, tempHandle.width(), tempHandle.height(), destPixels.x, destPixels.y,
12231238
destPixels.width, destPixels.height, false, tempHandle);
1224-
}, destPixels.width, destPixels.height);
1239+
}, destPixelsScaledWithTransform.width, destPixelsScaledWithTransform.height);
12251240
}
12261241

12271242
private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,
12281243
int destWidth, int destHeight, int imageZoom, int scaledImageZoom) {
1229-
Rectangle src = Win32DPIUtils.pointToPixel(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom);
1230-
Rectangle dest = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom);
1244+
Rectangle srcPixels = Win32DPIUtils.pointToPixel(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom);
1245+
Rectangle destPixels = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom);
12311246
Rectangle fullImageBounds = image.getBounds();
1232-
Rectangle fullImageBoundsScaled = Win32DPIUtils.pointToPixel(drawable, fullImageBounds, scaledImageZoom);
1233-
Rectangle unscaledSrc = new Rectangle(srcX, srcY, srcWidth, srcHeight);
1247+
Rectangle fullImageBoundsPixels = Win32DPIUtils.pointToPixel(drawable, fullImageBounds, scaledImageZoom);
1248+
Rectangle src = new Rectangle(srcX, srcY, srcWidth, srcHeight);
1249+
float transformationScale = calculateTransformationScale();
1250+
int scaledImageZoomWithTransform = Math.round(transformationScale * scaledImageZoom);
1251+
Rectangle fullImageBoundsScaledWithTransform = Win32DPIUtils.pointToPixel(drawable, fullImageBounds, scaledImageZoomWithTransform);
12341252
if (scaledImageZoom != 100) {
12351253
/*
12361254
* This is a HACK! Due to rounding errors at fractional scale factors,
12371255
* the coordinates may be slightly off. The workaround is to restrict
12381256
* coordinates to the allowed bounds.
12391257
*/
1240-
int errX = src.x + src.width - fullImageBoundsScaled.width;
1241-
int errY = src.y + src.height - fullImageBoundsScaled.height;
1258+
int errX = srcPixels.x + srcPixels.width - fullImageBoundsPixels.width;
1259+
int errY = srcPixels.y + srcPixels.height - fullImageBoundsPixels.height;
12421260
if (errX != 0 || errY != 0) {
12431261
if (errX <= scaledImageZoom / 100 && errY <= scaledImageZoom / 100) {
1244-
src.intersect(fullImageBoundsScaled);
1262+
srcPixels.intersect(fullImageBoundsPixels);
12451263
} else {
12461264
SWT.error (SWT.ERROR_INVALID_ARGUMENT);
12471265
}
12481266
}
12491267
}
12501268
image.executeOnImageHandleAtBestFittingSize((tempHandle) -> {
1251-
Rectangle newSrc = computeSourceRectangle(tempHandle, fullImageBounds, fullImageBoundsScaled, unscaledSrc, src);
1252-
drawImage(image, newSrc.x, newSrc.y, newSrc.width, newSrc.height, dest.x, dest.y, dest.width,
1253-
dest.height, false, tempHandle);
1254-
}, fullImageBoundsScaled.width, fullImageBoundsScaled.height);
1269+
Rectangle newSrcPixels = computeSourceRectangle(tempHandle, fullImageBounds, fullImageBoundsPixels, src, srcPixels);
1270+
drawImage(image, newSrcPixels.x, newSrcPixels.y, newSrcPixels.width, newSrcPixels.height, destPixels.x, destPixels.y, destPixels.width,
1271+
destPixels.height, false, tempHandle);
1272+
}, fullImageBoundsScaledWithTransform.width, fullImageBoundsScaledWithTransform.height);
12551273
}
12561274

1257-
private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle fullImageBounds, Rectangle fullImageBoundsScaled, Rectangle unscaledSrc, Rectangle src) {
1258-
if (new Rectangle(0, 0, imageHandle.getWidth(), imageHandle.getHeight()).equals(fullImageBoundsScaled)) {
1259-
return src;
1275+
private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle fullImageBounds, Rectangle fullImageBoundsPixels, Rectangle src, Rectangle srcPixels) {
1276+
if (new Rectangle(0, 0, imageHandle.width(), imageHandle.height()).equals(fullImageBoundsPixels)) {
1277+
return srcPixels;
12601278
} else {
12611279
/*
1262-
* the achieved handle with its drawings has not the required size, thus we calculate the zoom of the handle
1263-
*
1264-
* with respect to the full 100% image. The point values (x,y,width,height) of the source "part" of the full image will
1280+
* the achieved handle with its drawings has not the required size, thus we calculate the zoom of the handle
1281+
* with respect to the full 100% image. The values (x,y,width,height) of the source "part" of the full image will
12651282
* be computed to pixels by this zoom.
12661283
*/
1267-
float scaleFactor = 1f * imageHandle.getWidth() / fullImageBounds.width;
1284+
float scaleFactor = Math.max(1f * imageHandle.width() / fullImageBounds.width, 1f * imageHandle.height() / fullImageBounds.height);
12681285
int closestZoomOfHandle = Math.round(scaleFactor * 100);
1269-
return Win32DPIUtils.pointToPixel(drawable, unscaledSrc, closestZoomOfHandle);
1286+
return Win32DPIUtils.pointToPixel(drawable, src, closestZoomOfHandle);
12701287
}
12711288
}
12721289

0 commit comments

Comments
 (0)