diff options
author | Eric Williams | 2019-07-02 19:58:51 +0000 |
---|---|---|
committer | Eric Williams | 2019-07-04 17:49:00 +0000 |
commit | d6ae8b74de3b5b8e0b7a12eccf27300c755e9672 (patch) | |
tree | 60e1b24b7abd22f622299ff2347e6e4d9993570f | |
parent | 29744c3324413c8033adbd500c84ae08d6a211fb (diff) | |
download | eclipse.platform.swt-d6ae8b74de3b5b8e0b7a12eccf27300c755e9672.tar.gz eclipse.platform.swt-d6ae8b74de3b5b8e0b7a12eccf27300c755e9672.tar.xz eclipse.platform.swt-d6ae8b74de3b5b8e0b7a12eccf27300c755e9672.zip |
Bug 545032: [GTK] Implement native ImageLoader
Most ImageData's created on GTK have an RGB byte order, however some
exceptions do exist. Specifically, ImageData's created from JFace's
CompositeImageDescriptor can have a BGR byte order. Because of
this, it's necessary to check the PaletteData in ImageLoader.save().
If the PaletteData indicates a negative blue shift, we are dealing with
BGR byte ordering and must adjust the offsets accordingly.
Revert some smaller changes from the original ImageLoader patch, as they
are not needed (causes the white background on breadcrumb icons).
Verified with the relevant bug snippets, JUnits, and with the JDT icons
in a child Eclipse.
Change-Id: I8d6e1cea4c1559689e42dedf334c550435cd7533
Signed-off-by: Eric Williams <ericwill@redhat.com>
4 files changed, 25 insertions, 13 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java index 58a8649530..ae4a1031c8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java @@ -667,7 +667,7 @@ protected void init () { surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_RGB24, 10, 10); } else { gdkResource = GDK.gdk_get_default_root_window(); - surface = GDK.gdk_window_create_similar_surface(gdkResource, Cairo.CAIRO_CONTENT_COLOR_ALPHA, 10, 10); + surface = GDK.gdk_window_create_similar_surface(gdkResource, Cairo.CAIRO_CONTENT_COLOR, 10, 10); } Cairo.cairo_surface_get_device_scale(surface, sx, sy); DPIUtil.setUseCairoAutoScale((sx[0]*100) == scaleFactor); 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 da7ed3aad7..d865552281 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 @@ -1252,7 +1252,7 @@ void init(int width, int height) { if (GTK.GTK4) { surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_RGB24, width, height); } else { - surface = GDK.gdk_window_create_similar_surface(GDK.gdk_get_default_root_window(), Cairo.CAIRO_CONTENT_COLOR_ALPHA, width, height); + surface = GDK.gdk_window_create_similar_surface(GDK.gdk_get_default_root_window(), Cairo.CAIRO_CONTENT_COLOR, width, height); } if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); // When we create a blank image we need to set it to 100 in GTK3 as we draw using 100% scale. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java index a6612becd3..248ccf1afd 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java @@ -469,11 +469,25 @@ public void save(OutputStream stream, int format) { int bytes_per_pixel = imgData.bytesPerLine / width; // n_channels for original ImageData (width * height * bytes_per_pixel) = imgData.length /* - * Destination offsets, ImageData data provided is in RGBA format. + * Destination offsets, GdkPixbuf data is stored in RGBA format. + */ + int da = 3; int dr = 0; int dg = 1; int db = 2; + + /* + * ImageData offsets. These can vary depending on how the ImageData.data + * field was populated. In most cases it will be RGB format, so this case + * is assumed (blue shift is 0). * + * If blue is negatively shifted, then we are dealing with BGR byte ordering, so + * adjust the offsets accordingly. */ - int da, dr, dg, db; - da = 3; dr = 0; dg = 1; db = 2; + int or = 0; int og = 1; int ob = 2; + PaletteData palette = imgData.palette; + if (palette.isDirect && palette.blueShift < 0) { + or = 2; + og = 1; + ob = 0; + } if (has_alpha && bytes_per_pixel == 3) { bytes_per_pixel = 4; @@ -487,10 +501,9 @@ public void save(OutputStream stream, int format) { for (int y = 0, offset = 0, new_offset = 0, alphaOffset = 0; y < height; y++) { for (int x = 0; x < width; x++, offset += n_channels, new_offset += bytes_per_pixel) { byte a = imgData.alphaData[alphaOffset++]; - // ImageData data is stored in RGBA format - byte r = imgData.data[offset + alpha_offset + 0]; - byte g = imgData.data[offset + alpha_offset + 1]; - byte b = imgData.data[offset + alpha_offset + 2]; + byte r = imgData.data[offset + alpha_offset + or]; + byte g = imgData.data[offset + alpha_offset + og]; + byte b = imgData.data[offset + alpha_offset + ob]; // GdkPixbuf expects RGBA format srcData[new_offset + db] = b; @@ -502,9 +515,9 @@ public void save(OutputStream stream, int format) { } else { for (int y = 0, offset = 0, new_offset = 0; y < height; y++) { for (int x = 0; x < width; x++, offset += n_channels, new_offset += bytes_per_pixel) { - byte r = imgData.data[offset + alpha_offset + 0]; - byte g = imgData.data[offset + alpha_offset + 1]; - byte b = imgData.data[offset + alpha_offset + 2]; + byte r = imgData.data[offset + alpha_offset + or]; + byte g = imgData.data[offset + alpha_offset + og]; + byte b = imgData.data[offset + alpha_offset + ob]; byte a = (byte) 255; srcData[new_offset + db] = b; diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_ImageLoader.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_ImageLoader.java index 5100bde26c..875e8a7f20 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_ImageLoader.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_ImageLoader.java @@ -200,7 +200,6 @@ public void test_bug547529() { */ if (SwtTestUtil.isGTK) { imageDepth = 32; - } else { imageDepth = 24; } |