@@ -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+
12171228private 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
12271242private 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