@@ -1061,7 +1061,8 @@ void apply() {
1061
1061
1062
1062
private void drawImageInPixels (Image image , Point location ) {
1063
1063
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 );
1065
1066
}
1066
1067
}
1067
1068
@@ -1099,7 +1100,10 @@ private void drawImageInPixels(Image image, Point location) {
1099
1100
*/
1100
1101
public void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY , int destWidth , int destHeight ) {
1101
1102
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 ;
1103
1107
if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0 ) {
1104
1108
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1105
1109
}
@@ -1164,8 +1168,8 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d
1164
1168
private void drawImage (Image image , int srcX , int srcY , int srcWidth , int srcHeight , int destX , int destY ,
1165
1169
int destWidth , int destHeight , int imageZoom , int scaledImageZoom ) {
1166
1170
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 ) {
1169
1173
/*
1170
1174
* This is a HACK! Due to rounding errors at fractional scale factors,
1171
1175
* 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
1182
1186
}
1183
1187
}
1184
1188
}
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 ;
1186
1229
}
1187
1230
1188
1231
private class DrawImageToImageOperation extends ImageOperation {
@@ -1199,18 +1242,20 @@ private class DrawImageToImageOperation extends ImageOperation {
1199
1242
1200
1243
@ Override
1201
1244
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 );
1203
1247
}
1204
1248
}
1205
1249
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 ) {
1207
1251
if (data .gdipGraphics != 0 ) {
1208
1252
//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 );
1210
1256
long img = gdipImage [0 ];
1211
1257
int imgWidth = Gdip .Image_GetWidth (img );
1212
1258
int imgHeight = Gdip .Image_GetHeight (img );
1213
-
1214
1259
if (simple ) {
1215
1260
srcWidth = destWidth = imgWidth ;
1216
1261
srcHeight = destHeight = imgHeight ;
@@ -1261,13 +1306,13 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
1261
1306
}
1262
1307
return ;
1263
1308
}
1264
- long imageHandle = srcImage .getHandle (imageZoom , data .nativeZoom );
1265
1309
switch (srcImage .type ) {
1266
1310
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 );
1268
1313
break ;
1269
1314
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 );
1271
1316
break ;
1272
1317
}
1273
1318
}
0 commit comments