@@ -1061,7 +1061,8 @@ void apply() {
10611061
10621062 private void drawImageInPixels (Image image , Point location ) {
10631063 if (image .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1064- drawImage (image , 0 , 0 , -1 , -1 , location .x , location .y , -1 , -1 , true , getZoom ());
1064+ long handle = Image .win32_getHandle (image , getZoom ());
1065+ drawImage (image , 0 , 0 , -1 , -1 , location .x , location .y , -1 , -1 , true , handle );
10651066 }
10661067}
10671068
@@ -1099,7 +1100,10 @@ private void drawImageInPixels(Image image, Point location) {
10991100 */
11001101public void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight ) {
11011102 checkNonDisposed ();
1102- if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0 ) return ;
1103+ if (image == null && (srcWidth == 0 || srcHeight == 0 )) return ;
1104+ // Skip drawing only if exactly one source dimension is zero
1105+ if ((srcWidth == 0 ) ^ (srcHeight == 0 )) return ;
1106+ if (destWidth == 0 || destHeight == 0 ) return ;
11031107 if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0 ) {
11041108 SWT .error (SWT .ERROR_INVALID_ARGUMENT );
11051109 }
@@ -1164,8 +1168,8 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d
11641168private void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY ,
11651169 int destWidth , int destHeight , int imageZoom , int scaledImageZoom ) {
11661170 Rectangle src = Win32DPIUtils .pointToPixel (drawable , new Rectangle (srcX , srcY , srcWidth , srcHeight ), scaledImageZoom );
1167- Rectangle dest = Win32DPIUtils .pointToPixel (drawable , new Rectangle (destX , destY , destWidth , destHeight ), imageZoom );
1168- if (scaledImageZoom != 100 ) {
1171+ Rectangle destPixels = Win32DPIUtils .pointToPixel (drawable , new Rectangle (destX , destY , destWidth , destHeight ), imageZoom );
1172+ if (scaledImageZoom % 100 != 0 ) {
11691173 /*
11701174 * This is a HACK! Due to rounding errors at fractional scale factors,
11711175 * the coordinates may be slightly off. The workaround is to restrict
@@ -1182,7 +1186,46 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei
11821186 }
11831187 }
11841188 }
1185- drawImage (image , src .x , src .y , src .width , src .height , dest .x , dest .y , dest .width , dest .height , false , scaledImageZoom );
1189+ int targetWidth ;
1190+ int targetHeight ;
1191+ Rectangle scaledSrc ;
1192+ if (srcWidth == 0 && srcHeight == 0 ) {
1193+ scaledSrc = new Rectangle (srcX , srcY , srcWidth , srcHeight );
1194+ targetWidth = destWidth ;
1195+ targetHeight = destHeight ;
1196+ } else {
1197+ float widthScalingFactor = (float ) destWidth / srcWidth ;
1198+ float heightScalingFactor = (float ) destHeight / srcHeight ;
1199+ Rectangle fullImageBounds = image .getBounds ();
1200+ targetWidth = Math .round (fullImageBounds .width * widthScalingFactor );
1201+ targetHeight = Math .round (fullImageBounds .height * heightScalingFactor );
1202+
1203+ scaledSrc = new Rectangle (Math .round (src .x * widthScalingFactor ),
1204+ Math .round (src .y * heightScalingFactor ), Math .round (src .width * widthScalingFactor ),
1205+ Math .round (src .height * heightScalingFactor ));
1206+ }
1207+ Point targetSize = Win32DPIUtils .pointToPixel (drawable , new Point (targetWidth , targetHeight ), scaledImageZoom );
1208+ image .executeOnImageHandleAtSizeOrZoom ((tempHandle , handleSize ) -> {
1209+ Rectangle srcRect = computeSourceRectangle (handleSize , targetSize , scaledSrc , src );
1210+ drawImage (image , srcRect .x , srcRect .y , srcRect .width , srcRect .height , destPixels .x , destPixels .y , destPixels .width ,
1211+ destPixels .height , false , tempHandle );
1212+ }, targetSize .x , targetSize .y , scaledImageZoom );
1213+ }
1214+
1215+ /**
1216+ * Selects the source rectangle for drawing. If the requested width matches the image size,
1217+ * uses the scaled rectangle, otherwise the unscaled one.
1218+ */
1219+ private Rectangle computeSourceRectangle (Point imageSize , Point requestedSize , Rectangle scaledSrc ,
1220+ Rectangle unScaledSrc ) {
1221+
1222+ Rectangle src = (imageSize .equals (requestedSize )) ? scaledSrc : unScaledSrc ;
1223+ // If both width and height are zero, use the full image
1224+ // (avoids forcing a getBounds() call inside drawImage)
1225+ if (src .width == 0 && src .height == 0 ) {
1226+ return new Rectangle (0 , 0 , imageSize .x , imageSize .y );
1227+ }
1228+ return src ;
11861229}
11871230
11881231private class DrawImageToImageOperation extends ImageOperation {
@@ -1199,18 +1242,20 @@ private class DrawImageToImageOperation extends ImageOperation {
11991242
12001243 @ Override
12011244 void apply () {
1202- drawImage (getImage (), source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , getZoom ());
1245+ long handle = Image .win32_getHandle (getImage (), getZoom ());
1246+ drawImage (getImage (), source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , handle );
12031247 }
12041248}
12051249
1206- 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 ) {
1250+ 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 ) {
12071251 if (data .gdipGraphics != 0 ) {
12081252 //TODO - cache bitmap
1209- long [] gdipImage = srcImage .createGdipImage (imageZoom );
1253+ long [] gdipImage = srcImage .createGdipImageFromHandle (tempImageHandle );
1254+ BITMAP bm = new BITMAP ();
1255+ OS .GetObject (tempImageHandle , BITMAP .sizeof , bm );
12101256 long img = gdipImage [0 ];
12111257 int imgWidth = Gdip .Image_GetWidth (img );
12121258 int imgHeight = Gdip .Image_GetHeight (img );
1213-
12141259 if (simple ) {
12151260 srcWidth = destWidth = imgWidth ;
12161261 srcHeight = destHeight = imgHeight ;
@@ -1261,13 +1306,13 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
12611306 }
12621307 return ;
12631308 }
1264- long imageHandle = srcImage .getHandle (imageZoom , data .nativeZoom );
12651309 switch (srcImage .type ) {
12661310 case SWT .BITMAP :
1267- drawBitmap (srcImage , imageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
1311+ drawBitmap (srcImage , tempImageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight ,
1312+ simple );
12681313 break ;
12691314 case SWT .ICON :
1270- drawIcon (imageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
1315+ drawIcon (tempImageHandle , srcX , srcY , srcWidth , srcHeight , destX , destY , destWidth , destHeight , simple );
12711316 break ;
12721317 }
12731318}
0 commit comments