@@ -1053,7 +1053,8 @@ void apply() {
10531053
10541054 private void drawImageInPixels (Image image , Point location ) {
10551055 if (image .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1056- drawImage (image , 0 , 0 , -1 , -1 , location .x , location .y , -1 , -1 , true , getZoom ());
1056+ long handle = Image .win32_getHandle (image , getZoom ());
1057+ drawImage (image , 0 , 0 , -1 , -1 , location .x , location .y , -1 , -1 , true , handle );
10571058 }
10581059}
10591060
@@ -1091,7 +1092,10 @@ private void drawImageInPixels(Image image, Point location) {
10911092 */
10921093public void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight ) {
10931094 checkNonDisposed ();
1094- if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0 ) return ;
1095+ if (image == null && (srcWidth == 0 || srcHeight == 0 )) return ;
1096+ // Skip drawing only if exactly one source dimension is zero
1097+ if ((srcWidth == 0 ) ^ (srcHeight == 0 )) return ;
1098+ if (destWidth == 0 || destHeight == 0 ) return ;
10951099 if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0 ) {
10961100 SWT .error (SWT .ERROR_INVALID_ARGUMENT );
10971101 }
@@ -1156,8 +1160,8 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d
11561160private void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY ,
11571161 int destWidth , int destHeight , int imageZoom , int scaledImageZoom ) {
11581162 Rectangle src = Win32DPIUtils .pointToPixel (drawable , new Rectangle (srcX , srcY , srcWidth , srcHeight ), scaledImageZoom );
1159- Rectangle dest = Win32DPIUtils .pointToPixel (drawable , new Rectangle (destX , destY , destWidth , destHeight ), imageZoom );
1160- if (scaledImageZoom != 100 ) {
1163+ Rectangle destPixels = Win32DPIUtils .pointToPixel (drawable , new Rectangle (destX , destY , destWidth , destHeight ), imageZoom );
1164+ if (scaledImageZoom % 100 != 0 ) {
11611165 /*
11621166 * This is a HACK! Due to rounding errors at fractional scale factors,
11631167 * the coordinates may be slightly off. The workaround is to restrict
@@ -1174,7 +1178,46 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei
11741178 }
11751179 }
11761180 }
1177- drawImage (image , src .x , src .y , src .width , src .height , dest .x , dest .y , dest .width , dest .height , false , scaledImageZoom );
1181+ int targetWidth ;
1182+ int targetHeight ;
1183+ Rectangle scaledSrc ;
1184+ if (srcWidth == 0 && srcHeight == 0 ) {
1185+ scaledSrc = new Rectangle (srcX , srcY , srcWidth , srcHeight );
1186+ targetWidth = destWidth ;
1187+ targetHeight = destHeight ;
1188+ } else {
1189+ float widthScalingFactor = (float ) destWidth / srcWidth ;
1190+ float heightScalingFactor = (float ) destHeight / srcHeight ;
1191+ Rectangle fullImageBounds = image .getBounds ();
1192+ targetWidth = Math .round (fullImageBounds .width * widthScalingFactor );
1193+ targetHeight = Math .round (fullImageBounds .height * heightScalingFactor );
1194+
1195+ scaledSrc = new Rectangle (Math .round (src .x * widthScalingFactor ),
1196+ Math .round (src .y * heightScalingFactor ), Math .round (src .width * widthScalingFactor ),
1197+ Math .round (src .height * heightScalingFactor ));
1198+ }
1199+ Point targetSize = Win32DPIUtils .pointToPixel (drawable , new Point (targetWidth , targetHeight ), scaledImageZoom );
1200+ image .executeOnImageHandleAtSizeOrZoom ((tempHandle , handleSize ) -> {
1201+ Rectangle srcRect = computeSourceRectangle (handleSize , targetSize , scaledSrc , src );
1202+ drawImage (image , srcRect .x , srcRect .y , srcRect .width , srcRect .height , destPixels .x , destPixels .y , destPixels .width ,
1203+ destPixels .height , false , tempHandle );
1204+ }, targetSize .x , targetSize .y , scaledImageZoom );
1205+ }
1206+
1207+ /**
1208+ * Selects the source rectangle for drawing. If the requested width matches the image size,
1209+ * uses the scaled rectangle, otherwise the unscaled one.
1210+ */
1211+ private Rectangle computeSourceRectangle (Point imageSize , Point requestedSize , Rectangle scaledSrc ,
1212+ Rectangle unScaledSrc ) {
1213+
1214+ Rectangle src = ((imageSize .x == requestedSize .x ) && (imageSize .y == requestedSize .y )) ? scaledSrc : unScaledSrc ;
1215+ // If both width and height are zero, use the full image
1216+ // (avoids forcing a getBounds() call inside drawImage)
1217+ if (src .width == 0 && src .height == 0 ) {
1218+ return new Rectangle (0 , 0 , imageSize .x , imageSize .y );
1219+ }
1220+ return src ;
11781221}
11791222
11801223private class DrawImageToImageOperation extends ImageOperation {
@@ -1191,18 +1234,20 @@ private class DrawImageToImageOperation extends ImageOperation {
11911234
11921235 @ Override
11931236 void apply () {
1194- drawImage (getImage (), source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , getZoom ());
1237+ long handle = Image .win32_getHandle (getImage (), getZoom ());
1238+ drawImage (getImage (), source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , handle );
11951239 }
11961240}
11971241
1198- private void drawImage (Image srcImage , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight , boolean simple , int imageZoom ) {
1242+ private void drawImage (Image srcImage , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight , boolean simple , long tempImageHandle ) {
11991243 if (data .gdipGraphics != 0 ) {
12001244 //TODO - cache bitmap
1201- long [] gdipImage = srcImage .createGdipImage (imageZoom );
1245+ long [] gdipImage = srcImage .createGdipImageFromHandle (tempImageHandle );
1246+ BITMAP bm = new BITMAP ();
1247+ OS .GetObject (tempImageHandle , BITMAP .sizeof , bm );
12021248 long img = gdipImage [0 ];
12031249 int imgWidth = Gdip .Image_GetWidth (img );
12041250 int imgHeight = Gdip .Image_GetHeight (img );
1205-
12061251 if (simple ) {
12071252 srcWidth = destWidth = imgWidth ;
12081253 srcHeight = destHeight = imgHeight ;
@@ -1253,13 +1298,13 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
12531298 }
12541299 return ;
12551300 }
1256- long imageHandle = srcImage .getHandle (imageZoom , data .nativeZoom );
12571301 switch (srcImage .type ) {
12581302 case SWT .BITMAP :
1259- drawBitmap (srcImage , imageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
1303+ drawBitmap (srcImage , tempImageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight ,
1304+ simple );
12601305 break ;
12611306 case SWT .ICON :
1262- drawIcon (imageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
1307+ drawIcon (tempImageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
12631308 break ;
12641309 }
12651310}
0 commit comments