Skip to content

Commit 9a317a3

Browse files
arunjose696akoch-yatta
authored andcommitted
Add drawImage API that takes only a destination rectangle
Introduces a new method that draws the full image into a specified destination rectangle without requiring source bounds. Consumers no longer need to call image.getBounds() to determine image dimensions, unlike the existing drawImage method (Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight), which required knowing the image size in advance.
1 parent f51bb3b commit 9a317a3

File tree

5 files changed

+228
-47
lines changed

5 files changed

+228
-47
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,7 @@ void drawBackground(GC gc, int[] shape, int x, int y, int width, int height, Col
698698
// draw the background image in shape
699699
gc.setBackground(defaultBackground);
700700
gc.fillRectangle(x, y, width, height);
701-
Rectangle imageRect = image.getBounds();
702-
gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height, x, y, width, height);
701+
gc.drawImage(image, x, y, width, height);
703702
} else if (colors != null) {
704703
// draw gradient
705704
if (colors.length == 1) {
@@ -1646,9 +1645,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) {
16461645
int imageY = y + (height - imageHeight) / 2;
16471646
imageY += parent.onBottom ? -1 : 1;
16481647
int imageWidth = imageBounds.width * imageHeight / imageBounds.height;
1649-
gc.drawImage(image,
1650-
imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height,
1651-
imageX, imageY, imageWidth, imageHeight);
1648+
gc.drawImage(image, imageX, imageY, imageWidth, imageHeight);
16521649
xDraw += imageWidth + INTERNAL_SPACING;
16531650
}
16541651
}

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,11 +1189,67 @@ public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeig
11891189
drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false);
11901190
}
11911191

1192+
/**
1193+
* Draws the full source image into a specified rectangular area in the
1194+
* receiver. The image will be stretched or shrunk as needed to exactly fit the
1195+
* destination rectangle.
1196+
*
1197+
* @param image the source image
1198+
* @param destX the x coordinate in the destination
1199+
* @param destY the y coordinate in the destination
1200+
* @param destWidth the width in points of the destination rectangle
1201+
* @param destHeight the height in points of the destination rectangle
1202+
*
1203+
* @exception IllegalArgumentException
1204+
* <ul>
1205+
* <li>ERROR_NULL_ARGUMENT - if the image is
1206+
* null</li>
1207+
* <li>ERROR_INVALID_ARGUMENT - if the image
1208+
* has been disposed</li>
1209+
* <li>ERROR_INVALID_ARGUMENT - if any of
1210+
* the width or height arguments are
1211+
* negative.
1212+
* </ul>
1213+
* @exception SWTException
1214+
* <ul>
1215+
* <li>ERROR_GRAPHIC_DISPOSED - if the
1216+
* receiver has been disposed</li>
1217+
* </ul>
1218+
* @exception SWTError
1219+
* <ul>
1220+
* <li>ERROR_NO_HANDLES - if no handles are
1221+
* available to perform the operation</li>
1222+
* </ul>
1223+
* @since 3.132
1224+
*/
1225+
public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) {
1226+
if (handle == null) {
1227+
SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
1228+
}
1229+
if (destWidth == 0 || destHeight == 0) {
1230+
return;
1231+
}
1232+
if (destWidth < 0 || destHeight < 0) {
1233+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1234+
}
1235+
if (image == null) {
1236+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
1237+
}
1238+
if (image.isDisposed()) {
1239+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1240+
}
1241+
drawImage(image, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false);
1242+
}
1243+
11921244
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
11931245
NSImage imageHandle = srcImage.handle;
11941246
NSSize size = imageHandle.size();
11951247
int imgWidth = (int)size.width;
11961248
int imgHeight = (int)size.height;
1249+
if (srcWidth == 0 && srcHeight == 0) {
1250+
srcWidth = imgWidth;
1251+
srcHeight = imgHeight;
1252+
}
11971253
if (simple) {
11981254
srcWidth = destWidth = imgWidth;
11991255
srcHeight = destHeight = imgHeight;

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -861,16 +861,72 @@ public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeig
861861
}
862862
if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
863863
if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
864-
Rectangle destRect = new Rectangle(destX, destY, destWidth, destHeight);
865-
drawImage(image, srcX, srcY, srcWidth, srcHeight, destRect.x, destRect.y, destRect.width, destRect.height, false);
864+
drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false);
866865
}
866+
867+
/**
868+
* Draws the full source image into a specified rectangular area in the
869+
* receiver. The image will be stretched or shrunk as needed to exactly fit the
870+
* destination rectangle.
871+
*
872+
* @param image the source image
873+
* @param destX the x coordinate in the destination
874+
* @param destY the y coordinate in the destination
875+
* @param destWidth the width in points of the destination rectangle
876+
* @param destHeight the height in points of the destination rectangle
877+
*
878+
* @exception IllegalArgumentException
879+
* <ul>
880+
* <li>ERROR_NULL_ARGUMENT - if the image is
881+
* null</li>
882+
* <li>ERROR_INVALID_ARGUMENT - if the image
883+
* has been disposed</li>
884+
* <li>ERROR_INVALID_ARGUMENT - if any of
885+
* the width or height arguments are
886+
* negative.
887+
* </ul>
888+
* @exception SWTException
889+
* <ul>
890+
* <li>ERROR_GRAPHIC_DISPOSED - if the
891+
* receiver has been disposed</li>
892+
* </ul>
893+
* @exception SWTError
894+
* <ul>
895+
* <li>ERROR_NO_HANDLES - if no handles are
896+
* available to perform the operation</li>
897+
* </ul>
898+
* @since 3.132
899+
*/
900+
public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) {
901+
if (handle == 0) {
902+
SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
903+
}
904+
if (destWidth == 0 || destHeight == 0) {
905+
return;
906+
}
907+
if (destWidth < 0 || destHeight < 0) {
908+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
909+
}
910+
if (image == null) {
911+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
912+
}
913+
if (image.isDisposed()) {
914+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
915+
}
916+
drawImage(image, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false);
917+
}
918+
867919
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
868920
/* Refresh Image as per zoom level, if required. */
869921
srcImage.refreshImageForZoom ();
870922

871923
ImageData srcImageData = srcImage.getImageData();
872924
int imgWidth = srcImageData.width;
873925
int imgHeight = srcImageData.height;
926+
if (srcWidth == 0 && srcHeight == 0) {
927+
srcWidth = imgWidth;
928+
srcHeight = imgHeight;
929+
}
874930
if (simple) {
875931
srcWidth = destWidth = imgWidth;
876932
srcHeight = destHeight = imgHeight;

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,58 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei
11091109
storeAndApplyOperationForExistingHandle(new DrawScalingImageToImageOperation(image, new Rectangle(srcX, srcY, srcWidth, srcHeight), new Rectangle(destX, destY, destWidth, destHeight)));
11101110
}
11111111

1112+
/**
1113+
* Draws the full source image into a specified rectangular area in the
1114+
* receiver. The image will be stretched or shrunk as needed to exactly fit the
1115+
* destination rectangle.
1116+
*
1117+
* @param image the source image
1118+
* @param destX the x coordinate in the destination
1119+
* @param destY the y coordinate in the destination
1120+
* @param destWidth the width in points of the destination rectangle
1121+
* @param destHeight the height in points of the destination rectangle
1122+
*
1123+
* @exception IllegalArgumentException
1124+
* <ul>
1125+
* <li>ERROR_NULL_ARGUMENT - if the image is
1126+
* null</li>
1127+
* <li>ERROR_INVALID_ARGUMENT - if the image
1128+
* has been disposed</li>
1129+
* <li>ERROR_INVALID_ARGUMENT - if any of
1130+
* the width or height arguments are
1131+
* negative.
1132+
* </ul>
1133+
* @exception SWTException
1134+
* <ul>
1135+
* <li>ERROR_GRAPHIC_DISPOSED - if the
1136+
* receiver has been disposed</li>
1137+
* </ul>
1138+
* @exception SWTError
1139+
* <ul>
1140+
* <li>ERROR_NO_HANDLES - if no handles are
1141+
* available to perform the operation</li>
1142+
* </ul>
1143+
* @since 3.132
1144+
*/
1145+
public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) {
1146+
checkNonDisposed();
1147+
if (destWidth == 0 || destHeight == 0) {
1148+
return;
1149+
}
1150+
if (destWidth < 0 || destHeight < 0) {
1151+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1152+
}
1153+
if (image == null) {
1154+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
1155+
}
1156+
if (image.isDisposed()) {
1157+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1158+
}
1159+
1160+
storeAndApplyOperationForExistingHandle(new DrawScalingImageToImageOperation(image, new Rectangle(0, 0, 0, 0),
1161+
new Rectangle(destX, destY, destWidth, destHeight)));
1162+
}
1163+
11121164
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
11131165
storeAndApplyOperationForExistingHandle(new DrawImageToImageOperation(srcImage, new Rectangle(srcX, srcY, srcWidth, srcHeight), new Rectangle(destX, destY, destWidth, destHeight), simple));
11141166
}
@@ -1213,7 +1265,10 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
12131265
long img = gdipImage[0];
12141266
int imgWidth = Gdip.Image_GetWidth(img);
12151267
int imgHeight = Gdip.Image_GetHeight(img);
1216-
1268+
if (srcWidth == 0 && srcHeight == 0) {
1269+
srcWidth = imgWidth;
1270+
srcHeight = imgHeight;
1271+
}
12171272
if (simple) {
12181273
srcWidth = destWidth = imgWidth;
12191274
srcHeight = destHeight = imgHeight;
@@ -1315,6 +1370,10 @@ private void drawIcon(long imageHandle, int srcX, int srcY, int srcWidth, int sr
13151370
OS.GetObject(hBitmap, BITMAP.sizeof, bm);
13161371
int iconWidth = bm.bmWidth, iconHeight = bm.bmHeight;
13171372
if (hBitmap == srcIconInfo.hbmMask) iconHeight /= 2;
1373+
if (srcWidth == 0 && srcHeight == 0) {
1374+
srcWidth = iconWidth;
1375+
srcHeight = iconHeight;
1376+
}
13181377

13191378
if (simple) {
13201379
srcWidth = destWidth = iconWidth;
@@ -1410,6 +1469,10 @@ private void drawBitmap(Image srcImage, long imageHandle, int srcX, int srcY, in
14101469
OS.GetObject(imageHandle, BITMAP.sizeof, bm);
14111470
int imgWidth = bm.bmWidth;
14121471
int imgHeight = bm.bmHeight;
1472+
if (srcWidth == 0 && srcHeight == 0) {
1473+
srcWidth = imgWidth;
1474+
srcHeight = imgHeight;
1475+
}
14131476
if (simple) {
14141477
srcWidth = destWidth = imgWidth;
14151478
srcHeight = destHeight = imgHeight;

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,28 @@ public void test_drawFocusIIII() {
308308
gc.drawFocus(1, 1, 50, 25);
309309
}
310310

311-
@Test
312-
public void test_drawImageLorg_eclipse_swt_graphics_ImageII() {
311+
private static class TestImages {
312+
final Image normal;
313+
final Image transparent;
314+
final Image alpha;
315+
316+
TestImages(Image normal, Image transparent, Image alpha) {
317+
this.normal = normal;
318+
this.transparent = transparent;
319+
this.alpha = alpha;
320+
}
321+
322+
void dispose() {
323+
normal.dispose();
324+
transparent.dispose();
325+
alpha.dispose();
326+
}
327+
}
328+
329+
private TestImages createTestImages(Display display) {
313330
Color c1 = new Color(255, 0, 0);
314331
Color c2 = new Color(0, 0, 0);
315332
Color c3 = new Color(255, 255, 0);
316-
317333
PaletteData paletteData = new PaletteData(c1.getRGB(), c2.getRGB(), c3.getRGB());
318334
ImageData data = new ImageData(30,30, 8, paletteData);
319335
for (int y = 0; y < data.height; y++) {
@@ -334,50 +350,43 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageII() {
334350
}
335351
}
336352
Image imageAlpha = new Image(display, data);
353+
c1.dispose();
354+
c2.dispose();
355+
c3.dispose();
356+
return new TestImages(image, imageTransparent, imageAlpha);
357+
}
337358

338-
gc.drawImage(image, 100, 100);
339-
gc.drawImage(imageTransparent, 130, 100);
340-
gc.drawImage(imageAlpha, 160, 100);
359+
360+
@Test
361+
public void test_drawImageLorg_eclipse_swt_graphics_ImageII() {
362+
TestImages images = createTestImages(display);
363+
364+
gc.drawImage(images.normal, 100, 100);
365+
gc.drawImage(images.transparent, 130, 100);
366+
gc.drawImage(images.alpha, 160, 100);
341367
assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 100, 100));
342-
image.dispose();
343-
imageTransparent.dispose();
344-
imageAlpha.dispose();
368+
images.dispose();
345369
}
346370

347371
@Test
348372
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIIIIIII() {
349-
Color c1 = new Color(255, 0, 0);
350-
Color c2 = new Color(0, 0, 0);
351-
Color c3 = new Color(255, 255, 0);
373+
TestImages images = createTestImages(display);
374+
gc.drawImage(images.normal, 10, 5, 20, 15, 100, 120, 50, 60);
375+
gc.drawImage(images.transparent, 10, 5, 20, 15, 100, 120, 10, 10);
376+
gc.drawImage(images.alpha, 10, 5, 20, 15, 100, 120, 20, 15);
377+
assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 10, 5, 20, 15, 100, 120, 50, 60));
378+
images.dispose();
379+
}
352380

353-
PaletteData paletteData = new PaletteData(c1.getRGB(), c2.getRGB(), c3.getRGB());
354-
ImageData data = new ImageData(30,30, 8, paletteData);
355-
for (int y = 0; y < data.height; y++) {
356-
for (int x = 0; x < data.width; x++) {
357-
if (x > y) data.setPixel(x, y, paletteData.getPixel(c1.getRGB()));
358-
else if (x < y) data.setPixel(x, y, paletteData.getPixel(c2.getRGB()));
359-
else data.setPixel(x, y, paletteData.getPixel(c3.getRGB()));
360-
}
361-
}
362-
Image image = new Image(display, data);
363-
data = image.getImageData();
364-
data.transparentPixel = paletteData.getPixel(c1.getRGB());
365-
Image imageTransparent = new Image(display, data);
366-
data.transparentPixel = -1;
367-
for (int y = 0; y < data.height; y++) {
368-
for (int x = 0; x < data.width; x++) {
369-
data.setAlpha(x, y, 127);
370-
}
371-
}
372-
Image imageAlpha = new Image(display, data);
373381

374-
gc.drawImage(image, 10, 5, 20, 15, 100, 120, 50, 60);
375-
gc.drawImage(imageTransparent, 10, 5, 20, 15, 100, 120, 10, 10);
376-
gc.drawImage(imageAlpha, 10, 5, 20, 15, 100, 120, 20, 15);
377-
assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 10, 5, 20, 15, 100, 120, 50, 60));
378-
image.dispose();
379-
imageAlpha.dispose();
380-
imageTransparent.dispose();
382+
@Test
383+
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII() {
384+
TestImages images = createTestImages(display);
385+
gc.drawImage(images.normal, 100, 120, 50, 60);
386+
gc.drawImage(images.transparent, 100, 120, 10, 10);
387+
gc.drawImage(images.alpha, 100, 120, 20, 15);
388+
assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 100, 120, 50, 60));
389+
images.dispose();
381390
}
382391

383392
@Test

0 commit comments

Comments
 (0)