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 df01ceb47e6..835497b8e1c 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 @@ -297,124 +297,13 @@ public Image(Device device, Image srcImage, int flag) { } case SWT.IMAGE_DISABLE: { ImageData data = srcImage.getImageData(srcImage.getZoom()); - PaletteData palette = data.palette; - RGB[] rgbs = new RGB[3]; - rgbs[0] = device.getSystemColor(SWT.COLOR_BLACK).getRGB(); - rgbs[1] = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW).getRGB(); - rgbs[2] = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB(); - ImageData newData = new ImageData(rect.width, rect.height, 8, new PaletteData(rgbs)); - newData.alpha = data.alpha; - newData.alphaData = data.alphaData; - newData.maskData = data.maskData; - newData.maskPad = data.maskPad; - if (data.transparentPixel != -1) newData.transparentPixel = 0; - - /* Convert the pixels. */ - int[] scanline = new int[rect.width]; - int[] maskScanline = null; - ImageData mask = null; - if (data.maskData != null) mask = data.getTransparencyMask(); - if (mask != null) maskScanline = new int[rect.width]; - int redMask = palette.redMask; - int greenMask = palette.greenMask; - int blueMask = palette.blueMask; - int redShift = palette.redShift; - int greenShift = palette.greenShift; - int blueShift = palette.blueShift; - for (int y=0; y>> -redShift : red << redShift; - green = pixel & greenMask; - green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; - blue = pixel & blueMask; - blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; - } else { - red = palette.colors[pixel].red; - green = palette.colors[pixel].green; - blue = palette.colors[pixel].blue; - } - int intensity = red * red + green * green + blue * blue; - if (intensity < 98304) { - newData.data[offset] = (byte)1; - } else { - newData.data[offset] = (byte)2; - } - } - offset++; - } - } + ImageData newData = applyDisableImageData(data, rect.height, rect.width); init (newData, getZoom()); break; } case SWT.IMAGE_GRAY: { ImageData data = srcImage.getImageData(srcImage.getZoom()); - PaletteData palette = data.palette; - ImageData newData = data; - if (!palette.isDirect) { - /* Convert the palette entries to gray. */ - RGB [] rgbs = palette.getRGBs(); - for (int i=0; i> 3; - color.red = color.green = color.blue = intensity; - } - } - newData.palette = new PaletteData(rgbs); - } else { - /* Create a 8 bit depth image data with a gray palette. */ - RGB[] rgbs = new RGB[256]; - for (int i=0; i>> -redShift : red << redShift; - int green = pixel & greenMask; - green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; - int blue = pixel & blueMask; - blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; - int intensity = (red+red+green+green+green+green+green+blue) >> 3; - if (newData.transparentPixel == intensity) intensity = 255; - newData.data[offset] = (byte)intensity; - } else { - newData.data[offset] = (byte)254; - } - offset++; - } - } - } + ImageData newData = applyGrayImageData(data, rect.height, rect.width); init (newData, getZoom()); break; } @@ -738,6 +627,150 @@ public Image(Device device, ImageDataProvider imageDataProvider) { init(); } +private ImageData adaptImageDataIfDisabledOrGray(ImageData data) { + ImageData returnImageData = null; + switch (this.styleFlag) { + case SWT.IMAGE_DISABLE: { + ImageData newData = applyDisableImageData(data, data.height, data.width); + returnImageData = newData; + break; + } + case SWT.IMAGE_GRAY: { + ImageData newData = applyGrayImageData(data, data.height, data.width); + returnImageData = newData; + break; + } + default: { + returnImageData = data; + break; + } + } + + return returnImageData; +} + +private ImageData applyDisableImageData(ImageData data, int height, int width) { + PaletteData palette = data.palette; + RGB[] rgbs = new RGB[3]; + rgbs[0] = this.device.getSystemColor(SWT.COLOR_BLACK).getRGB(); + rgbs[1] = this.device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW).getRGB(); + rgbs[2] = this.device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB(); + ImageData newData = new ImageData(width, height, 8, new PaletteData(rgbs)); + newData.alpha = data.alpha; + newData.alphaData = data.alphaData; + newData.maskData = data.maskData; + newData.maskPad = data.maskPad; + if (data.transparentPixel != -1) newData.transparentPixel = 0; + + /* Convert the pixels. */ + int[] scanline = new int[width]; + int[] maskScanline = null; + ImageData mask = null; + if (data.maskData != null) mask = data.getTransparencyMask(); + if (mask != null) maskScanline = new int[width]; + int redMask = palette.redMask; + int greenMask = palette.greenMask; + int blueMask = palette.blueMask; + int redShift = palette.redShift; + int greenShift = palette.greenShift; + int blueShift = palette.blueShift; + for (int y=0; y>> -redShift : red << redShift; + green = pixel & greenMask; + green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; + blue = pixel & blueMask; + blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; + } else { + red = palette.colors[pixel].red; + green = palette.colors[pixel].green; + blue = palette.colors[pixel].blue; + } + int intensity = red * red + green * green + blue * blue; + if (intensity < 98304) { + newData.data[offset] = (byte)1; + } else { + newData.data[offset] = (byte)2; + } + } + offset++; + } + } + return newData; +} + +private ImageData applyGrayImageData(ImageData data, int pHeight, int pWidth) { + PaletteData palette = data.palette; + ImageData newData = data; + if (!palette.isDirect) { + /* Convert the palette entries to gray. */ + RGB [] rgbs = palette.getRGBs(); + for (int i=0; i> 3; + color.red = color.green = color.blue = intensity; + } + } + newData.palette = new PaletteData(rgbs); + } else { + /* Create a 8 bit depth image data with a gray palette. */ + RGB[] rgbs = new RGB[256]; + for (int i=0; i>> -redShift : red << redShift; + int green = pixel & greenMask; + green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; + int blue = pixel & blueMask; + blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; + int intensity = (red+red+green+green+green+green+green+blue) >> 3; + if (newData.transparentPixel == intensity) intensity = 255; + newData.data[offset] = (byte)intensity; + } else { + newData.data[offset] = (byte)254; + } + offset++; + } + } + } + return newData; +} + + /** * IMPORTANT: This method is not part of the public * API for Image. It is marked public only so that it @@ -764,20 +797,22 @@ public static Long win32_getHandle (Image image, int zoom) { if (image.imageFileNameProvider != null) { ElementAtZoom imageCandidate = DPIUtil.validateAndGetImagePathAtZoom (image.imageFileNameProvider, zoom); + ImageData imageData = new ImageData (imageCandidate.element()); if (imageCandidate.zoom() == zoom) { /* Release current native resources */ long handle = image.initNative(imageCandidate.element(), zoom); - if (handle == 0) image.init(new ImageData (imageCandidate.element()), zoom); + if (handle == 0) image.init(imageData, zoom); image.init(); } else { - ImageData resizedData = DPIUtil.scaleImageData (image.device, new ImageData (imageCandidate.element()), zoom, imageCandidate.zoom()); - image.init(resizedData, zoom); - image.init (); + ImageData resizedData = DPIUtil.scaleImageData(image.device, imageData, zoom, imageCandidate.zoom()); + ImageData newData = image.adaptImageDataIfDisabledOrGray(resizedData); + image.init(newData, zoom); } } else if (image.imageDataProvider != null) { ElementAtZoom imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (image.imageDataProvider, zoom); ImageData resizedData = DPIUtil.scaleImageData (image.device, imageCandidate.element(), zoom, imageCandidate.zoom()); - image.init(resizedData, zoom); + ImageData newData = image.adaptImageDataIfDisabledOrGray(resizedData); + image.init(newData, zoom); image.init(); } else { if (image.dataAtBaseZoom == null && image.memGC == null) { @@ -786,7 +821,8 @@ public static Long win32_getHandle (Image image, int zoom) { } if (image.dataAtBaseZoom != null) { ImageData resizedData = image.getImageData(zoom); - image.init(resizedData, zoom); + ImageData newData = image.adaptImageDataIfDisabledOrGray(resizedData); + image.init(newData, zoom); image.init(); } } @@ -944,7 +980,9 @@ long initNative(String filename, int zoom) { ImageData img = new ImageData(width, height, depth, paletteData, scanlinePad, data); img.transparentPixel = transparentPixel; img.alphaData = alphaData; - init(img, zoom); + + ImageData newData = adaptImageDataIfDisabledOrGray(img); + init(newData, zoom); handle = zoomLevelToHandle.get(zoom); } Gdip.Bitmap_UnlockBits(bitmap, lockedBitmapData); diff --git a/examples/org.eclipse.swt.snippets/Snippets.md b/examples/org.eclipse.swt.snippets/Snippets.md index 531641ad9ec..6229a212c8d 100644 --- a/examples/org.eclipse.swt.snippets/Snippets.md +++ b/examples/org.eclipse.swt.snippets/Snippets.md @@ -213,6 +213,7 @@ To contribute a new snippet, [create a snippet contribution as a pull request](h - [draw a reflection of an image](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet279.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet279.png "Preview for Snippet 279") - [draw an image scaled to half size and double size](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet355.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet355.png "Preview for Snippet 355") - [draw an image at various zoom/dpi levels](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet367.png "Preview for Snippet 367") +- [draw a disabled/grayed image at various zoom levels](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet382.png "Preview for Snippet 382") ### **ImageData** - [display an animated GIF](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet141.java) diff --git a/examples/org.eclipse.swt.snippets/previews/Snippet382.png b/examples/org.eclipse.swt.snippets/previews/Snippet382.png new file mode 100644 index 00000000000..d29d8822655 Binary files /dev/null and b/examples/org.eclipse.swt.snippets/previews/Snippet382.png differ 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 new file mode 100644 index 00000000000..8a1b5273577 --- /dev/null +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2024 Yatta Solutions + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Yatta Solutions - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.snippets; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +/** + * Snippet to test the use of the DPI-aware Image constructors with disabled and gray images + * Work in progress in https://bugs.eclipse.org/399786 + *

+ * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + *

+ */ +public class Snippet382 { + private static final String IMAGE_100 = "eclipse16.png"; + private static final String IMAGE_150 = "eclipse24.png"; + private static final String IMAGE_200 = "eclipse32.png"; + private static final String IMAGES_ROOT = "bin/org/eclipse/swt/snippets/"; + + private static final String IMAGE_PATH_100 = IMAGES_ROOT + IMAGE_100; + private static final String IMAGE_PATH_150 = IMAGES_ROOT + IMAGE_150; + private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200; + + public static void main (String [] args) { + final ImageFileNameProvider filenameProvider = zoom -> { + switch (zoom) { + case 100: + return IMAGE_PATH_100; + case 150: + return IMAGE_PATH_150; + case 200: + return IMAGE_PATH_200; + default: + return null; + } + }; + final ImageDataProvider imageDataProvider = zoom -> { + switch (zoom) { + case 100: + return new ImageData (IMAGE_PATH_100); + case 150: + return new ImageData (IMAGE_PATH_150); + case 200: + return new ImageData (IMAGE_PATH_200); + default: + return null; + } + }; + + final Display display = new Display (); + final Shell shell = new Shell (display); + shell.setText("Snippet382"); + shell.setLayout (new GridLayout (3, false)); + Listener l = new Listener() { + @Override + 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); + + try { + drawImages(mainGC, gcData, "Normal",40, imageWithFileNameProvider); + drawImages(mainGC, gcData, "Disabled",80, disabledImageWithFileNameProvider); + drawImages(mainGC, gcData, "Greyed",120, greyImageWithFileNameProvider); + + drawImages(mainGC, gcData, "Normal",160, imageWithDataProvider); + drawImages(mainGC, gcData, "Disabled",200, disabledImageWithDataProvider); + drawImages(mainGC, gcData, "Greyed",240, greyImageWithDataProvider); + + drawImages(mainGC, gcData, "Normal",280, imageWithDataProvider); + drawImages(mainGC, gcData, "Disabled",320, disabledImageWithData); + drawImages(mainGC, gcData, "Greyed",360, greyImageWithData); + } finally { + mainGC.dispose (); + } + } + } + + private void drawImages(GC mainGC, GCData gcData, String text, int y, final Image imageWithFileNameProvider) { + gcData.nativeZoom = 100; + mainGC.drawText(text, 0, y); + mainGC.drawImage(imageWithFileNameProvider, 50, y); + gcData.nativeZoom = 150; + mainGC.drawImage(imageWithFileNameProvider, 100, (int) (y/1.5)); + gcData.nativeZoom = 200; + mainGC.drawImage(imageWithFileNameProvider, 150, y/2); + } + }; + shell.addListener(SWT.Paint, l); + + shell.setSize(400, 500); + shell.open (); + while (!shell.isDisposed ()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); + } + +}