diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java index 9edf33fbf84..4cf29174520 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolderRenderer.java @@ -698,8 +698,7 @@ void drawBackground(GC gc, int[] shape, int x, int y, int width, int height, Col // draw the background image in shape gc.setBackground(defaultBackground); gc.fillRectangle(x, y, width, height); - Rectangle imageRect = image.getBounds(); - gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height, x, y, width, height); + gc.drawImage(image, x, y, width, height); } else if (colors != null) { // draw gradient if (colors.length == 1) { @@ -1646,9 +1645,7 @@ void drawUnselected(int index, GC gc, Rectangle bounds, int state) { int imageY = y + (height - imageHeight) / 2; imageY += parent.onBottom ? -1 : 1; int imageWidth = imageBounds.width * imageHeight / imageBounds.height; - gc.drawImage(image, - imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height, - imageX, imageY, imageWidth, imageHeight); + gc.drawImage(image, imageX, imageY, imageWidth, imageHeight); xDraw += imageWidth + INTERNAL_SPACING; } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java index 6120e1f3cc9..31d122d55c0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java @@ -1189,11 +1189,67 @@ public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeig drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false); } +/** + * Draws the full source image into a specified rectangular area in the + * receiver. The image will be stretched or shrunk as needed to exactly fit the + * destination rectangle. + * + * @param image the source image + * @param destX the x coordinate in the destination + * @param destY the y coordinate in the destination + * @param destWidth the width in points of the destination rectangle + * @param destHeight the height in points of the destination rectangle + * + * @exception IllegalArgumentException + * + * @exception SWTException + * + * @exception SWTError + * + * @since 3.132 + */ +public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) { + if (handle == null) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + if (destWidth == 0 || destHeight == 0) { + return; + } + if (destWidth < 0 || destHeight < 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (image == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (image.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + drawImage(image, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false); +} + void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { NSImage imageHandle = srcImage.handle; NSSize size = imageHandle.size(); int imgWidth = (int)size.width; int imgHeight = (int)size.height; + if (srcWidth == 0 && srcHeight == 0) { + srcWidth = imgWidth; + srcHeight = imgHeight; + } if (simple) { srcWidth = destWidth = imgWidth; srcHeight = destHeight = imgHeight; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index d57191f04c1..1bf1da0dcba 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -861,9 +861,61 @@ public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeig } if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Rectangle destRect = new Rectangle(destX, destY, destWidth, destHeight); - drawImage(image, srcX, srcY, srcWidth, srcHeight, destRect.x, destRect.y, destRect.width, destRect.height, false); + drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false); } + +/** + * Draws the full source image into a specified rectangular area in the + * receiver. The image will be stretched or shrunk as needed to exactly fit the + * destination rectangle. + * + * @param image the source image + * @param destX the x coordinate in the destination + * @param destY the y coordinate in the destination + * @param destWidth the width in points of the destination rectangle + * @param destHeight the height in points of the destination rectangle + * + * @exception IllegalArgumentException + * + * @exception SWTException + * + * @exception SWTError + * + * @since 3.132 + */ +public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) { + if (handle == 0) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + if (destWidth == 0 || destHeight == 0) { + return; + } + if (destWidth < 0 || destHeight < 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (image == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (image.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + drawImage(image, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false); +} + void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { /* Refresh Image as per zoom level, if required. */ srcImage.refreshImageForZoom (); @@ -871,6 +923,10 @@ void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, ImageData srcImageData = srcImage.getImageData(); int imgWidth = srcImageData.width; int imgHeight = srcImageData.height; + if (srcWidth == 0 && srcHeight == 0) { + srcWidth = imgWidth; + srcHeight = imgHeight; + } if (simple) { srcWidth = destWidth = imgWidth; srcHeight = destHeight = imgHeight; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index c62445ebb1e..33b7ad7d4f4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -1109,6 +1109,58 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei storeAndApplyOperationForExistingHandle(new DrawScalingImageToImageOperation(image, new Rectangle(srcX, srcY, srcWidth, srcHeight), new Rectangle(destX, destY, destWidth, destHeight))); } +/** + * Draws the full source image into a specified rectangular area in the + * receiver. The image will be stretched or shrunk as needed to exactly fit the + * destination rectangle. + * + * @param image the source image + * @param destX the x coordinate in the destination + * @param destY the y coordinate in the destination + * @param destWidth the width in points of the destination rectangle + * @param destHeight the height in points of the destination rectangle + * + * @exception IllegalArgumentException + * + * @exception SWTException + * + * @exception SWTError + * + * @since 3.132 + */ +public void drawImage(Image image, int destX, int destY, int destWidth, int destHeight) { + checkNonDisposed(); + if (destWidth == 0 || destHeight == 0) { + return; + } + if (destWidth < 0 || destHeight < 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (image == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (image.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + storeAndApplyOperationForExistingHandle(new DrawScalingImageToImageOperation(image, new Rectangle(0, 0, 0, 0), + new Rectangle(destX, destY, destWidth, destHeight))); +} + void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { storeAndApplyOperationForExistingHandle(new DrawImageToImageOperation(srcImage, new Rectangle(srcX, srcY, srcWidth, srcHeight), new Rectangle(destX, destY, destWidth, destHeight), simple)); } @@ -1213,7 +1265,10 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src long img = gdipImage[0]; int imgWidth = Gdip.Image_GetWidth(img); int imgHeight = Gdip.Image_GetHeight(img); - + if (srcWidth == 0 && srcHeight == 0) { + srcWidth = imgWidth; + srcHeight = imgHeight; + } if (simple) { srcWidth = destWidth = imgWidth; srcHeight = destHeight = imgHeight; @@ -1315,6 +1370,10 @@ private void drawIcon(long imageHandle, int srcX, int srcY, int srcWidth, int sr OS.GetObject(hBitmap, BITMAP.sizeof, bm); int iconWidth = bm.bmWidth, iconHeight = bm.bmHeight; if (hBitmap == srcIconInfo.hbmMask) iconHeight /= 2; + if (srcWidth == 0 && srcHeight == 0) { + srcWidth = iconWidth; + srcHeight = iconHeight; + } if (simple) { srcWidth = destWidth = iconWidth; @@ -1410,6 +1469,10 @@ private void drawBitmap(Image srcImage, long imageHandle, int srcX, int srcY, in OS.GetObject(imageHandle, BITMAP.sizeof, bm); int imgWidth = bm.bmWidth; int imgHeight = bm.bmHeight; + if (srcWidth == 0 && srcHeight == 0) { + srcWidth = imgWidth; + srcHeight = imgHeight; + } if (simple) { srcWidth = destWidth = imgWidth; srcHeight = destHeight = imgHeight; diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java index 7b0233fad94..1bcb0c9ada2 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java @@ -308,12 +308,28 @@ public void test_drawFocusIIII() { gc.drawFocus(1, 1, 50, 25); } -@Test -public void test_drawImageLorg_eclipse_swt_graphics_ImageII() { +private static class TestImages { + final Image normal; + final Image transparent; + final Image alpha; + + TestImages(Image normal, Image transparent, Image alpha) { + this.normal = normal; + this.transparent = transparent; + this.alpha = alpha; + } + + void dispose() { + normal.dispose(); + transparent.dispose(); + alpha.dispose(); + } +} + +private TestImages createTestImages(Display display) { Color c1 = new Color(255, 0, 0); Color c2 = new Color(0, 0, 0); Color c3 = new Color(255, 255, 0); - PaletteData paletteData = new PaletteData(c1.getRGB(), c2.getRGB(), c3.getRGB()); ImageData data = new ImageData(30,30, 8, paletteData); for (int y = 0; y < data.height; y++) { @@ -334,50 +350,43 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageII() { } } Image imageAlpha = new Image(display, data); + c1.dispose(); + c2.dispose(); + c3.dispose(); + return new TestImages(image, imageTransparent, imageAlpha); +} - gc.drawImage(image, 100, 100); - gc.drawImage(imageTransparent, 130, 100); - gc.drawImage(imageAlpha, 160, 100); + +@Test +public void test_drawImageLorg_eclipse_swt_graphics_ImageII() { + TestImages images = createTestImages(display); + + gc.drawImage(images.normal, 100, 100); + gc.drawImage(images.transparent, 130, 100); + gc.drawImage(images.alpha, 160, 100); assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 100, 100)); - image.dispose(); - imageTransparent.dispose(); - imageAlpha.dispose(); + images.dispose(); } @Test public void test_drawImageLorg_eclipse_swt_graphics_ImageIIIIIIII() { - Color c1 = new Color(255, 0, 0); - Color c2 = new Color(0, 0, 0); - Color c3 = new Color(255, 255, 0); + TestImages images = createTestImages(display); + gc.drawImage(images.normal, 10, 5, 20, 15, 100, 120, 50, 60); + gc.drawImage(images.transparent, 10, 5, 20, 15, 100, 120, 10, 10); + gc.drawImage(images.alpha, 10, 5, 20, 15, 100, 120, 20, 15); + assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 10, 5, 20, 15, 100, 120, 50, 60)); + images.dispose(); +} - PaletteData paletteData = new PaletteData(c1.getRGB(), c2.getRGB(), c3.getRGB()); - ImageData data = new ImageData(30,30, 8, paletteData); - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - if (x > y) data.setPixel(x, y, paletteData.getPixel(c1.getRGB())); - else if (x < y) data.setPixel(x, y, paletteData.getPixel(c2.getRGB())); - else data.setPixel(x, y, paletteData.getPixel(c3.getRGB())); - } - } - Image image = new Image(display, data); - data = image.getImageData(); - data.transparentPixel = paletteData.getPixel(c1.getRGB()); - Image imageTransparent = new Image(display, data); - data.transparentPixel = -1; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - data.setAlpha(x, y, 127); - } - } - Image imageAlpha = new Image(display, data); - gc.drawImage(image, 10, 5, 20, 15, 100, 120, 50, 60); - gc.drawImage(imageTransparent, 10, 5, 20, 15, 100, 120, 10, 10); - gc.drawImage(imageAlpha, 10, 5, 20, 15, 100, 120, 20, 15); - assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 10, 5, 20, 15, 100, 120, 50, 60)); - image.dispose(); - imageAlpha.dispose(); - imageTransparent.dispose(); +@Test +public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII() { + TestImages images = createTestImages(display); + gc.drawImage(images.normal, 100, 120, 50, 60); + gc.drawImage(images.transparent, 100, 120, 10, 10); + gc.drawImage(images.alpha, 100, 120, 20, 15); + assertThrows(IllegalArgumentException.class, () -> gc.drawImage(null, 100, 120, 50, 60)); + images.dispose(); } @Test