Skip to content

Commit

Permalink
Adding disable/gray image props in ImageData when rescaled
Browse files Browse the repository at this point in the history
Disabled image do not work when rescaled. Writing a new method copyImageDataForDisabledOrGrayImages and calling it before init image in win32_getHandle
  • Loading branch information
ShahzaibIbrahim committed Jul 17, 2024
1 parent b2c0366 commit 2ec84b8
Showing 1 changed file with 159 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
ElementAtZoom<String> 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 {
Expand Down Expand Up @@ -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 <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code>
* @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<data.height; y++) {
int offset = y * newData.bytesPerLine;
data.getPixels(0, y, data.width, scanline, 0);
if (mask != null) mask.getPixels(0, y, data.width, maskScanline, 0);
for (int x=0; x<data.width; x++) {
int pixel = scanline[x];
if (!((data.transparentPixel != -1 && pixel == data.transparentPixel) || (mask != null && maskScanline[x] == 0))) {
int red, green, blue;
if (palette.isDirect) {
red = pixel & redMask;
red = (redShift < 0) ? red >>> -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<rgbs.length; i++) {
if (data.transparentPixel != i) {
RGB color = rgbs [i];
int red = color.red;
int green = color.green;
int blue = color.blue;
int intensity = (red+red+green+green+green+green+green+blue) >> 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<rgbs.length; i++) {
rgbs[i] = new RGB(i, i, i);
}
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 = 254;

/* Convert the pixels. */
int[] scanline = 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<data.height; y++) {
int offset = y * newData.bytesPerLine;
data.getPixels(0, y, data.width, scanline, 0);
for (int x=0; x<data.width; x++) {
int pixel = scanline[x];
if (pixel != data.transparentPixel) {
int red = pixel & redMask;
red = (redShift < 0) ? red >>> -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;
}

/**
* <b>IMPORTANT:</b> This method is not part of the public
* API for Image. It is marked public only so that it
Expand All @@ -763,20 +907,22 @@ public static Long win32_getHandle (Image image, int zoom) {

if (image.imageFileNameProvider != null) {
ElementAtZoom<String> 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<ImageData> 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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 2ec84b8

Please sign in to comment.