diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java index 7d0ff95942d..8040df584bf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java @@ -903,8 +903,17 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height) } private ImageData drawWithImageGcDrawer(ImageGcDrawer imageGcDrawer, int width, int height, int zoom) { - Image image = new Image(device, width, height); - GC gc = new GC(image); + int gcStyle = imageGcDrawer.getGcStyle(); + Image image; + if ((gcStyle & SWT.TRANSPARENT) != 0) { + /* Create a 24 bit image data with alpha channel */ + final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); + resultData.alphaData = new byte [width * height]; + image = new Image(device, resultData); + } else { + image = new Image(device, width, height); + } + GC gc = new GC(image, gcStyle); try { imageGcDrawer.drawOn(gc, width, height); ImageData imageData = image.getImageData(zoom); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java index 10a60eb0048..7b197fa6e3f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java @@ -306,16 +306,21 @@ private static ImageData autoScaleImageData (Device device, final ImageData imag boolean useSmoothScaling = isSmoothScalingEnabled() && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK; if (useSmoothScaling) { Image original = new Image (device, (ImageDataProvider) zoom -> imageData); - /* Create a 24 bit image data with alpha channel */ - final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); - resultData.alphaData = new byte [scaledWidth * scaledHeight]; - Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData); - GC gc = new GC (resultImage); - gc.setAntialias (SWT.ON); - Image.drawScaled(gc, original, width, height, scaleFactor); - gc.dispose (); + ImageGcDrawer drawer = new ImageGcDrawer() { + @Override + public void drawOn(GC gc, int imageWidth, int imageHeight) { + gc.setAntialias (SWT.ON); + Image.drawScaled(gc, original, width, height, scaleFactor); + }; + + @Override + public int getGcStyle() { + return SWT.TRANSPARENT; + } + }; + Image resultImage = new Image (device, drawer, scaledWidth, scaledHeight); + ImageData result = resultImage.getImageData (100); original.dispose (); - ImageData result = resultImage.getImageData (getDeviceZoom ()); resultImage.dispose (); return result; } else { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index c73e4dfe873..f174e431738 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -437,11 +437,14 @@ public Image(Device device, Rectangle bounds) { * @see #dispose() */ public Image(Device device, ImageData data) { + this(device, DPIUtil.autoScaleUp(device, data), DPIUtil.getDeviceZoom()); +} + +private Image(Device device, ImageData data, int zoom) { super(device); if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - currentDeviceZoom = DPIUtil.getDeviceZoom(); - data = DPIUtil.autoScaleUp (device, data); - init(data); + currentDeviceZoom = zoom; + init(data, zoom); init(); } @@ -695,9 +698,9 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height) SWT.error(SWT.ERROR_NULL_ARGUMENT); } this.imageGcDrawer = imageGcDrawer; - currentDeviceZoom = DPIUtil.getDeviceZoom(); + currentDeviceZoom = 100; ImageData imageData = drawWithImageGcDrawer(width, height, currentDeviceZoom); - init (imageData); + init (imageData, currentDeviceZoom); init (); } @@ -1162,8 +1165,17 @@ public ImageData getImageData (int zoom) { } private ImageData drawWithImageGcDrawer(int width, int height, int zoom) { - Image image = new Image(device, width, height); - GC gc = new GC(image); + int gcStyle = imageGcDrawer.getGcStyle(); + Image image; + if ((gcStyle & SWT.TRANSPARENT) != 0) { + /* Create a 24 bit image data with alpha channel */ + final ImageData resultData = new ImageData(width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); + resultData.alphaData = new byte [width * height]; + image = new Image(device, resultData, zoom); + } else { + image = new Image(device, width, height); + } + GC gc = new GC(image, gcStyle); try { imageGcDrawer.drawOn(gc, width, height); ImageData imageData = image.getImageData(zoom); @@ -1274,6 +1286,10 @@ void init(int width, int height) { } void init(ImageData image) { + init(image, DPIUtil.getDeviceZoom()); +} + +private void init(ImageData image, int zoom) { if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); PaletteData palette = image.palette; @@ -1286,7 +1302,7 @@ void init(ImageData image) { int imageDataHeight = image.height; // Scale dimensions of Image object to 100% scale factor - double scaleFactor = DPIUtil.getDeviceZoom() / 100f; + double scaleFactor = zoom / 100f; this.width = (int) Math.round(imageDataWidth / scaleFactor); this.height = (int) Math.round(imageDataHeight / scaleFactor); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 4c6b8532f16..f2b96c560b1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -380,6 +380,15 @@ public Image(Device device, ImageData data) { this.device.registerResourceWithZoomSupport(this); } +private Image(Device device, ImageData data, int zoom) { + super(device); + if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + initialNativeZoom = zoom; + this.imageProvider = new PlainImageDataProviderWrapper(data, zoom); + init(); + this.device.registerResourceWithZoomSupport(this); +} + /** * Constructs an instance of this class, whose type is * SWT.ICON, from the two given ImageData @@ -1956,27 +1965,34 @@ private ImageHandle initializeHandleFromSource(int zoom) { } private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper { - private ImageData imageDataAt100; + private ImageData imageDataAtBaseZoom; + private int baseZoom; PlainImageDataProviderWrapper(ImageData imageData) { - this.imageDataAt100 = (ImageData) imageData.clone(); + this(imageData, 100); + } + + private PlainImageDataProviderWrapper(ImageData imageData, int zoom) { + this.imageDataAtBaseZoom = (ImageData) imageData.clone(); + this.baseZoom = zoom; initImage(); } @Override protected Rectangle getBounds(int zoom) { - Rectangle rectangle = new Rectangle(0, 0, imageDataAt100.width, imageDataAt100.height); + Rectangle rectangle = new Rectangle(0, 0, imageDataAtBaseZoom.width, imageDataAtBaseZoom.height); + rectangle = DPIUtil.scaleDown(rectangle, baseZoom); return DPIUtil.scaleUp(rectangle, zoom); } @Override protected ElementAtZoom loadImageData(int zoom) { - return new ElementAtZoom<>(imageDataAt100, 100); + return new ElementAtZoom<>(imageDataAtBaseZoom, baseZoom); } @Override AbstractImageProviderWrapper createCopy(Image image) { - return image.new PlainImageDataProviderWrapper(this.imageDataAt100); + return image.new PlainImageDataProviderWrapper(this.imageDataAtBaseZoom); } } @@ -2478,8 +2494,19 @@ ImageData newImageData(int zoom) { @Override protected ImageHandle newImageHandle(int zoom) { initialNativeZoom = zoom; - Image image = new Image(device, width, height, zoom); - GC gc = new GC(image, drawer.getGcStyle()); + int gcStyle = drawer.getGcStyle(); + Image image; + if ((gcStyle & SWT.TRANSPARENT) != 0) { + int scaledHeight = DPIUtil.scaleUp(height, zoom); + int scaledWidth = DPIUtil.scaleUp(width, zoom); + /* Create a 24 bit image data with alpha channel */ + final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); + resultData.alphaData = new byte [scaledWidth * scaledHeight]; + image = new Image(device, resultData, zoom); + } else { + image = new Image(device, width, height, zoom); + } + GC gc = new GC(image, gcStyle); try { gc.data.nativeZoom = zoom; drawer.drawOn(gc, width, height); diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java index fc5b6aee5b5..54b53dc1d39 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java @@ -36,6 +36,8 @@ public class Snippet367 { private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200; public static void main (String [] args) { + final Display display = new Display (); + final ImageFileNameProvider filenameProvider = zoom -> { switch (zoom) { case 100: @@ -65,7 +67,17 @@ public static void main (String [] args) { gc.drawLine(3, 3, width - 3, height - 3); }; - final Display display = new Display (); + Image imageWithDataProvider = new Image (display, imageDataProvider); + final ImageGcDrawer transparentImageGcDrawer = new ImageGcDrawer() { + @Override + public void drawOn(GC gc, int width, int height) { + gc.drawImage(imageWithDataProvider, 0, 0); + } + @Override + public int getGcStyle() { + return SWT.TRANSPARENT; + } + }; final Shell shell = new Shell (display); shell.setText("Snippet367"); shell.setLayout (new GridLayout (3, false)); @@ -99,13 +111,17 @@ public static void main (String [] args) { new Button(shell, SWT.NONE).setImage (new Image (display, filenameProvider)); new Label (shell, SWT.NONE).setText ("ImageDataProvider:"); - new Label (shell, SWT.NONE).setImage (new Image (display, imageDataProvider)); - new Button(shell, SWT.NONE).setImage (new Image (display, imageDataProvider)); + new Label (shell, SWT.NONE).setImage (imageWithDataProvider); + new Button(shell, SWT.NONE).setImage (imageWithDataProvider); new Label (shell, SWT.NONE).setText ("ImageGcDrawer:"); new Label (shell, SWT.NONE).setImage (new Image (display, imageGcDrawer, 20, 20)); new Button(shell, SWT.NONE).setImage (new Image (display, imageGcDrawer, 20, 20)); + new Label (shell, SWT.NONE).setText ("Transparent ImageGcDrawer:"); + new Label (shell, SWT.NONE).setImage (new Image (display, transparentImageGcDrawer, 20, 20)); + new Button(shell, SWT.NONE).setImage (new Image (display, transparentImageGcDrawer, 20, 20)); + createSeparator(shell); new Label (shell, SWT.NONE).setText ("1. Canvas\n(PaintListener)"); diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java index 821cfcec277..bb639b08287 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java @@ -64,6 +64,18 @@ public static void main (String [] args) { final Display display = new Display (); + final Image imageWithFileNameProvider = new Image (display, filenameProvider); + final Image disabledImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_DISABLE); + final Image greyImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_GRAY); + + final Image imageWithDataProvider = new Image (display, imageDataProvider); + final Image disabledImageWithDataProvider = new Image (display,imageWithDataProvider, SWT.IMAGE_DISABLE); + final Image greyImageWithDataProvider = new Image (display,imageWithDataProvider, SWT.IMAGE_GRAY); + + final Image imageWithData = new Image (display, IMAGE_PATH_100); + final Image disabledImageWithData = new Image (display,imageWithData, SWT.IMAGE_DISABLE); + final Image greyImageWithData = new Image (display,imageWithData, SWT.IMAGE_GRAY); + final ImageGcDrawer imageGcDrawer = (gc, width, height) -> { gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillRectangle(0, 0, width, height); @@ -71,6 +83,25 @@ public static void main (String [] args) { gc.drawRectangle(4, 4, width - 8, height - 8); }; + final Image imageWithGcDrawer = new Image (display, imageGcDrawer, 16, 16); + final Image disabledImageWithGcDrawer = new Image (display, imageWithGcDrawer, SWT.IMAGE_DISABLE); + final Image greyImageWithGcDrawer = new Image (display, imageWithGcDrawer, SWT.IMAGE_GRAY); + + final ImageGcDrawer transparentImageGcDrawer = new ImageGcDrawer() { + @Override + public void drawOn(GC gc, int width, int height) { + gc.drawImage(imageWithDataProvider, 0, 0); + } + @Override + public int getGcStyle() { + return SWT.TRANSPARENT; + } + }; + + final Image imageWithTransparentGcDrawer = new Image (display, transparentImageGcDrawer, 16, 16); + final Image disabledImageWithTransparentGcDrawer = new Image (display, imageWithTransparentGcDrawer, SWT.IMAGE_DISABLE); + final Image greyImageWithTransparentGcDrawer = new Image (display, imageWithTransparentGcDrawer, SWT.IMAGE_GRAY); + final Shell shell = new Shell (display); shell.setText("Snippet382"); shell.setLayout (new GridLayout (3, false)); @@ -80,21 +111,7 @@ public void handleEvent(Event e) { if (e.type == SWT.Paint) { GC mainGC = e.gc; GCData gcData = mainGC.getGCData(); - final Image imageWithFileNameProvider = new Image (display, filenameProvider); - final Image disabledImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_DISABLE); - final Image greyImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_GRAY); - final Image imageWithDataProvider = new Image (display, imageDataProvider); - final Image disabledImageWithDataProvider = new Image (display,imageWithDataProvider, SWT.IMAGE_DISABLE); - final Image greyImageWithDataProvider = new Image (display,imageWithDataProvider, SWT.IMAGE_GRAY); - - final Image imageWithData = new Image (display, IMAGE_PATH_100); - final Image disabledImageWithData = new Image (display,imageWithData, SWT.IMAGE_DISABLE); - final Image greyImageWithData = new Image (display,imageWithData, SWT.IMAGE_GRAY); - - final Image imageWithGcDrawer = new Image (display, imageGcDrawer, 16, 16); - final Image disabledImageWithGcDrawer = new Image (display, imageWithGcDrawer, SWT.IMAGE_DISABLE); - final Image greyImageWithGcDrawer = new Image (display, imageWithGcDrawer, SWT.IMAGE_GRAY); try { drawImages(mainGC, gcData, "Normal",40, imageWithFileNameProvider); @@ -112,6 +129,10 @@ public void handleEvent(Event e) { drawImages(mainGC, gcData, "Normal", 400, imageWithGcDrawer); drawImages(mainGC, gcData, "Disabled", 440, disabledImageWithGcDrawer); drawImages(mainGC, gcData, "Greyed", 480, greyImageWithGcDrawer); + + drawImages(mainGC, gcData, "Normal", 520, imageWithTransparentGcDrawer); + drawImages(mainGC, gcData, "Disabled", 560, disabledImageWithTransparentGcDrawer); + drawImages(mainGC, gcData, "Greyed", 600, greyImageWithTransparentGcDrawer); } finally { mainGC.dispose (); } @@ -130,7 +151,7 @@ private void drawImages(GC mainGC, GCData gcData, String text, int y, final Imag }; shell.addListener(SWT.Paint, l); - shell.setSize(400, 550); + shell.setSize(400, 750); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep ();