From 2ec84b8456d38e81795b460b4d4201407f279b33 Mon Sep 17 00:00:00 2001 From: "shahzaib.ibrahim" Date: Wed, 17 Jul 2024 11:23:58 +0200 Subject: [PATCH] Adding disable/gray image props in ImageData when rescaled Disabled image do not work when rescaled. Writing a new method copyImageDataForDisabledOrGrayImages and calling it before init image in win32_getHandle --- .../win32/org/eclipse/swt/graphics/Image.java | 169 ++++++++++++++++-- 1 file changed, 159 insertions(+), 10 deletions(-) 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 b5100858bb7..d6c11f2ecbb 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 @@ -685,7 +685,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) { initialNativeZoom = DPIUtil.getNativeDeviceZoom(); ElementAtZoom fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, getZoom()); if (fileName.zoom() == getZoom()) { - long handle = initNative (fileName.element(), getZoom()); + long handle = initNative (fileName.element(), getZoom(), SWT.IMAGE_COPY); if (handle == 0) { init(new ImageData (fileName.element()), getZoom()); } else { @@ -737,6 +737,150 @@ public Image(Device device, ImageDataProvider imageDataProvider) { init(); } + +/** + * Upon zoom update, this method copies the image data and add disabled or grayed image depending on the flag + * + * @param device the device on which to create the image + * @param data the image data to create the image from (must not be null) + * @param flag the style, either IMAGE_COPY, IMAGE_DISABLE or IMAGE_GRAY + * @return new image data with valid styling properties as per the flag + */ +private ImageData copyImageDataForDisabledOrGrayImages(Device device, ImageData data, int flag) { + ImageData returnImageData = null; + switch (flag) { + case SWT.IMAGE_COPY: { + returnImageData = data; + break; + } + case SWT.IMAGE_DISABLE: { + 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(data.width, data.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[data.width]; + int[] maskScanline = null; + ImageData mask = null; + if (data.maskData != null) mask = data.getTransparencyMask(); + if (mask != null) maskScanline = new int[data.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++; + } + } + returnImageData = newData; + break; + } + case SWT.IMAGE_GRAY: { + 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++; + } + } + } + returnImageData = newData; + break; + } + default: + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + return returnImageData; +} + /** * IMPORTANT: This method is not part of the public * API for Image. It is marked public only so that it @@ -763,20 +907,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); + long handle = image.initNative(imageCandidate.element(), zoom, image.styleFlag); + if (handle == 0) image.init(imageData, zoom); image.init(); } else { - ImageData resizedData = DPIUtil.autoScaleImageData (image.device, new ImageData (imageCandidate.element()), zoom, imageCandidate.zoom()); - image.init(resizedData, zoom); - image.init (); + ImageData resizedData = DPIUtil.autoScaleImageData (image.device, imageData, zoom, imageCandidate.zoom()); + ImageData newData = image.copyImageDataForDisabledOrGrayImages(image.getDevice(), resizedData, image.styleFlag); + image.init( newData, zoom); } } else if (image.imageDataProvider != null) { ElementAtZoom imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (image.imageDataProvider, zoom); ImageData resizedData = DPIUtil.autoScaleImageData (image.device, imageCandidate.element(), zoom, imageCandidate.zoom()); - image.init(resizedData, zoom); + ImageData newData = image.copyImageDataForDisabledOrGrayImages(image.getDevice(), resizedData, image.styleFlag); + image.init(newData, zoom); image.init(); } else { if (image.dataAtBaseZoom == null && image.memGC == null) { @@ -785,14 +931,15 @@ 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.copyImageDataForDisabledOrGrayImages(image.getDevice(), resizedData, image.styleFlag); + image.init(newData, zoom); image.init(); } } return image.zoomLevelToHandle.get(zoom); } -long initNative(String filename, int zoom) { +long initNative(String filename, int zoom, int imageStyle) { long handle = 0; device.checkGDIP(); boolean gdip = true; @@ -943,7 +1090,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 = copyImageDataForDisabledOrGrayImages(device, img, imageStyle); + init(newData, zoom); handle = zoomLevelToHandle.get(zoom); } Gdip.Bitmap_UnlockBits(bitmap, lockedBitmapData);