@@ -1053,7 +1053,8 @@ void apply() {
1053
1053
1054
1054
private void drawImageInPixels (Image image , Point location ) {
1055
1055
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 );
1057
1058
}
1058
1059
}
1059
1060
@@ -1091,7 +1092,10 @@ private void drawImageInPixels(Image image, Point location) {
1091
1092
*/
1092
1093
public void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight ) {
1093
1094
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 ;
1095
1099
if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0 ) {
1096
1100
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1097
1101
}
@@ -1156,8 +1160,8 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d
1156
1160
private void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY ,
1157
1161
int destWidth , int destHeight , int imageZoom , int scaledImageZoom ) {
1158
1162
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 ) {
1161
1165
/*
1162
1166
* This is a HACK! Due to rounding errors at fractional scale factors,
1163
1167
* 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
1174
1178
}
1175
1179
}
1176
1180
}
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 .equals (requestedSize )) ? 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 ;
1178
1221
}
1179
1222
1180
1223
private class DrawImageToImageOperation extends ImageOperation {
@@ -1191,18 +1234,20 @@ private class DrawImageToImageOperation extends ImageOperation {
1191
1234
1192
1235
@ Override
1193
1236
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 );
1195
1239
}
1196
1240
}
1197
1241
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 ) {
1199
1243
if (data .gdipGraphics != 0 ) {
1200
1244
//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 );
1202
1248
long img = gdipImage [0 ];
1203
1249
int imgWidth = Gdip .Image_GetWidth (img );
1204
1250
int imgHeight = Gdip .Image_GetHeight (img );
1205
-
1206
1251
if (simple ) {
1207
1252
srcWidth = destWidth = imgWidth ;
1208
1253
srcHeight = destHeight = imgHeight ;
@@ -1253,13 +1298,13 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
1253
1298
}
1254
1299
return ;
1255
1300
}
1256
- long imageHandle = srcImage .getHandle (imageZoom , data .nativeZoom );
1257
1301
switch (srcImage .type ) {
1258
1302
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 );
1260
1305
break ;
1261
1306
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 );
1263
1308
break ;
1264
1309
}
1265
1310
}
0 commit comments