diff options
author | Silenio Quarti <Silenio_Quarti@ca.ibm.com> | 2011-10-20 13:08:33 -0400 |
---|---|---|
committer | Silenio Quarti <Silenio_Quarti@ca.ibm.com> | 2011-10-20 13:08:33 -0400 |
commit | a3c8e8904451b6db108629003e63438cb42170e1 (patch) | |
tree | 27eca76f5991f0130d72a37d4db67775be7e6eb7 | |
parent | 97620fe3667502da9f174b22a0db4534a8d8f70b (diff) | |
download | eclipse.platform.swt-a3c8e8904451b6db108629003e63438cb42170e1.tar.gz eclipse.platform.swt-a3c8e8904451b6db108629003e63438cb42170e1.tar.xz eclipse.platform.swt-a3c8e8904451b6db108629003e63438cb42170e1.zip |
create opaque image surfaces; target cairo 1.2 APIs; remove surfaceData field
7 files changed, 216 insertions, 92 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c index 3d475ab49f..1b775b5dda 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c @@ -559,6 +559,46 @@ JNIEXPORT jintLong JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1create_1for_1da } #endif +#ifndef NO__1cairo_1image_1surface_1get_1data +JNIEXPORT jintLong JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1data) + (JNIEnv *env, jclass that, jintLong arg0) +{ + jintLong rc = 0; + Cairo_NATIVE_ENTER(env, that, _1cairo_1image_1surface_1get_1data_FUNC); +/* + rc = (jintLong)cairo_image_surface_get_data((cairo_surface_t *)arg0); +*/ + { + Cairo_LOAD_FUNCTION(fp, cairo_image_surface_get_data) + if (fp) { + rc = (jintLong)((jintLong (CALLING_CONVENTION*)(cairo_surface_t *))fp)((cairo_surface_t *)arg0); + } + } + Cairo_NATIVE_EXIT(env, that, _1cairo_1image_1surface_1get_1data_FUNC); + return rc; +} +#endif + +#ifndef NO__1cairo_1image_1surface_1get_1format +JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1format) + (JNIEnv *env, jclass that, jintLong arg0) +{ + jint rc = 0; + Cairo_NATIVE_ENTER(env, that, _1cairo_1image_1surface_1get_1format_FUNC); +/* + rc = (jint)cairo_image_surface_get_format((cairo_surface_t *)arg0); +*/ + { + Cairo_LOAD_FUNCTION(fp, cairo_image_surface_get_format) + if (fp) { + rc = (jint)((jint (CALLING_CONVENTION*)(cairo_surface_t *))fp)((cairo_surface_t *)arg0); + } + } + Cairo_NATIVE_EXIT(env, that, _1cairo_1image_1surface_1get_1format_FUNC); + return rc; +} +#endif + #ifndef NO__1cairo_1image_1surface_1get_1height JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1height) (JNIEnv *env, jclass that, jintLong arg0) @@ -571,6 +611,26 @@ JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1height) } #endif +#ifndef NO__1cairo_1image_1surface_1get_1stride +JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1stride) + (JNIEnv *env, jclass that, jintLong arg0) +{ + jint rc = 0; + Cairo_NATIVE_ENTER(env, that, _1cairo_1image_1surface_1get_1stride_FUNC); +/* + rc = (jint)cairo_image_surface_get_stride((cairo_surface_t *)arg0); +*/ + { + Cairo_LOAD_FUNCTION(fp, cairo_image_surface_get_stride) + if (fp) { + rc = (jint)((jint (CALLING_CONVENTION*)(cairo_surface_t *))fp)((cairo_surface_t *)arg0); + } + } + Cairo_NATIVE_EXIT(env, that, _1cairo_1image_1surface_1get_1stride_FUNC); + return rc; +} +#endif + #ifndef NO__1cairo_1image_1surface_1get_1width JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1image_1surface_1get_1width) (JNIEnv *env, jclass that, jintLong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h index 9d08cda12d..b2cb701fd7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h @@ -32,4 +32,7 @@ #define cairo_pdf_surface_set_size_LIB LIB_CAIRO #define cairo_ps_surface_set_size_LIB LIB_CAIRO #define cairo_surface_set_fallback_resolution_LIB LIB_CAIRO -#define cairo_surface_get_type_LIB LIB_CAIRO
\ No newline at end of file +#define cairo_surface_get_type_LIB LIB_CAIRO +#define cairo_image_surface_get_data_LIB LIB_CAIRO +#define cairo_image_surface_get_format_LIB LIB_CAIRO +#define cairo_image_surface_get_stride_LIB LIB_CAIRO
\ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c index 4404269235..a15bcea6b4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c @@ -24,8 +24,8 @@ #ifdef NATIVE_STATS -int Cairo_nativeFunctionCount = 146; -int Cairo_nativeFunctionCallCount[146]; +int Cairo_nativeFunctionCount = 149; +int Cairo_nativeFunctionCallCount[149]; char * Cairo_nativeFunctionNames[] = { "CAIRO_1VERSION_1ENCODE", "_1cairo_1append_1path", @@ -71,7 +71,10 @@ char * Cairo_nativeFunctionNames[] = { "_1cairo_1identity_1matrix", "_1cairo_1image_1surface_1create", "_1cairo_1image_1surface_1create_1for_1data", + "_1cairo_1image_1surface_1get_1data", + "_1cairo_1image_1surface_1get_1format", "_1cairo_1image_1surface_1get_1height", + "_1cairo_1image_1surface_1get_1stride", "_1cairo_1image_1surface_1get_1width", "_1cairo_1in_1fill", "_1cairo_1in_1stroke", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h index b3a532b299..78d398ea9d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h @@ -79,7 +79,10 @@ typedef enum { _1cairo_1identity_1matrix_FUNC, _1cairo_1image_1surface_1create_FUNC, _1cairo_1image_1surface_1create_1for_1data_FUNC, + _1cairo_1image_1surface_1get_1data_FUNC, + _1cairo_1image_1surface_1get_1format_FUNC, _1cairo_1image_1surface_1get_1height_FUNC, + _1cairo_1image_1surface_1get_1stride_FUNC, _1cairo_1image_1surface_1get_1width_FUNC, _1cairo_1in_1fill_FUNC, _1cairo_1in_1stroke_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java index 1e2e2553ac..465b2dab73 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java @@ -552,6 +552,32 @@ public static final int /*long*/ cairo_image_surface_create_for_data(int /*long* lock.unlock(); } } +/** + * @method flags=dynamic + * @param surface cast=(cairo_surface_t *) + */ +public static final native int /*long*/ _cairo_image_surface_get_data(int /*long*/ surface); +public static final int /*long*/ cairo_image_surface_get_data(int /*long*/ surface) { + lock.lock(); + try { + return _cairo_image_surface_get_data(surface); + } finally { + lock.unlock(); + } +} +/** + * @method flags=dynamic + * @param surface cast=(cairo_surface_t *) + */ +public static final native int _cairo_image_surface_get_format(int /*long*/ surface); +public static final int cairo_image_surface_get_format(int /*long*/ surface) { + lock.lock(); + try { + return _cairo_image_surface_get_format(surface); + } finally { + lock.unlock(); + } +} /** @param surface cast=(cairo_surface_t *) */ public static final native int _cairo_image_surface_get_height(int /*long*/ surface); public static final int cairo_image_surface_get_height(int /*long*/ surface) { @@ -572,6 +598,19 @@ public static final int cairo_image_surface_get_width(int /*long*/ surface) { lock.unlock(); } } +/** + * @method flags=dynamic + * @param surface cast=(cairo_surface_t *) + */ +public static final native int _cairo_image_surface_get_stride(int /*long*/ surface); +public static final int cairo_image_surface_get_stride(int /*long*/ surface) { + lock.lock(); + try { + return _cairo_image_surface_get_stride(surface); + } finally { + lock.unlock(); + } +} /** @param cr cast=(cairo_t *) */ public static final native int _cairo_in_fill(int /*long*/ cr, double x, double y); public static final int cairo_in_fill(int /*long*/ cr, double x, double y) { 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 38cff3f4ab..73c602871b 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 @@ -112,7 +112,7 @@ public final class Image extends Resource implements Drawable { */ public int /*long*/ mask; - public int /*long*/ surface, surfaceData; + public int /*long*/ surface; /** * specifies the transparent pixel @@ -596,20 +596,18 @@ void createFromPixbuf(int type, int /*long*/ pixbuf) { int stride = OS.gdk_pixbuf_get_rowstride(pixbuf); int /*long*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf); int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24; - int cairoStride = Cairo.cairo_format_stride_for_width(format, width); - int /*long*/ data = surfaceData = OS.g_malloc(cairoStride * height); - if (surfaceData == 0) SWT.error(SWT.ERROR_NO_HANDLES); - surface = Cairo.cairo_image_surface_create_for_data(surfaceData, format, width, height, cairoStride); + surface = Cairo.cairo_image_surface_create(format, width, height); if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); - byte[] line = new byte[stride]; + int /*long*/ data = Cairo.cairo_image_surface_get_data(surface); + int cairoStride = Cairo.cairo_image_surface_get_stride(surface); int oa = 0, or = 0, og = 0, ob = 0; if (OS.BIG_ENDIAN) { oa = 0; or = 1; og = 2; ob = 3; } else { oa = 3; or = 2; og = 1; ob = 0; } + byte[] line = new byte[stride]; if (hasAlpha) { - byte[] cairoLine = new byte[cairoStride]; alphaData = new byte[width * height]; for (int y = 0, alphaOffset = 0; y < height; y++) { OS.memmove(line, pixels + (y * stride), stride); @@ -621,13 +619,13 @@ void createFromPixbuf(int type, int /*long*/ pixbuf) { g = (g + (g >> 8)) >> 8; int b = ((line[offset + 2] & 0xFF) * a) + 128; b = (b + (b >> 8)) >> 8; - cairoLine[offset + oa] = (byte)a; - cairoLine[offset + or] = (byte)r; - cairoLine[offset + og] = (byte)g; - cairoLine[offset + ob] = (byte)b; + line[offset + oa] = (byte)a; + line[offset + or] = (byte)r; + line[offset + og] = (byte)g; + line[offset + ob] = (byte)b; alphaData[alphaOffset++] = (byte)a; } - OS.memmove(data + (y * cairoStride), cairoLine, cairoStride); + OS.memmove(data + (y * stride), line, stride); } } else { byte[] cairoLine = new byte[cairoStride]; @@ -637,7 +635,6 @@ void createFromPixbuf(int type, int /*long*/ pixbuf) { int r = line[offset + 0] & 0xFF; int g = line[offset + 1] & 0xFF; int b = line[offset + 2] & 0xFF; - cairoLine[cairoOffset + oa] = (byte)0xFF; cairoLine[cairoOffset + or] = (byte)r; cairoLine[cairoOffset + og] = (byte)g; cairoLine[cairoOffset + ob] = (byte)b; @@ -684,8 +681,8 @@ void createMask() { if (OS.USE_CAIRO_SURFACE) { int width = this.width; int height = this.height; - int stride = Cairo.cairo_format_stride_for_width(Cairo.CAIRO_FORMAT_ARGB32, width); - byte[] srcData = new byte[stride * height]; + int stride = Cairo.cairo_image_surface_get_stride(surface); + int /*long*/ surfaceData = Cairo.cairo_image_surface_get_data(surface); int oa, or, og, ob, tr, tg, tb; if (OS.BIG_ENDIAN) { oa = 0; or = 1; og = 2; ob = 3; @@ -698,7 +695,8 @@ void createMask() { tg = (transparentPixel >> 8) & 0xFF; tb = (transparentPixel >> 0) & 0xFF; } - OS.memmove(srcData, this.surfaceData, srcData.length); + byte[] srcData = new byte[stride * height]; + OS.memmove(srcData, surfaceData, srcData.length); int offset = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, offset += 4) { @@ -717,7 +715,7 @@ void createMask() { srcData[offset + ob] = (byte)b; } } - OS.memmove(this.surfaceData, srcData, srcData.length); + OS.memmove(surfaceData, srcData, srcData.length); return; } if (mask != 0) return; @@ -847,9 +845,9 @@ void createSurface() { offset += stride; } } - surfaceData = OS.g_malloc(stride * height); - OS.memmove(surfaceData, pixels, stride * height); - surface = Cairo.cairo_image_surface_create_for_data(surfaceData, Cairo.CAIRO_FORMAT_ARGB32, width, height, stride); + surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height); + int /*long*/ data = Cairo.cairo_image_surface_get_data(surface); + OS.memmove(data, pixels, stride * height); OS.g_object_unref(pixbuf); } else { int /*long*/ xDisplay = OS.GDK_DISPLAY(); @@ -875,8 +873,7 @@ void destroy() { if (pixmap != 0) OS.g_object_unref(pixmap); if (mask != 0) OS.g_object_unref(mask); if (surface != 0) Cairo.cairo_surface_destroy(surface); - if (surfaceData != 0) OS.g_free(surfaceData); - surfaceData = surface = pixmap = mask = 0; + surface = pixmap = mask = 0; memGC = null; } @@ -966,50 +963,53 @@ public ImageData getImageData() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); ImageData data; if (OS.USE_CAIRO_SURFACE) { - int width = this.width; - int height = this.height; - int stride = Cairo.cairo_format_stride_for_width(Cairo.CAIRO_FORMAT_ARGB32, width); - byte[] srcData = new byte[stride * height]; + int format = Cairo.cairo_image_surface_get_format(surface); + int width = Cairo.cairo_image_surface_get_width(surface); + int height = Cairo.cairo_image_surface_get_height(surface); + int stride = Cairo.cairo_image_surface_get_stride(surface); + int /*long*/ surfaceData = Cairo.cairo_image_surface_get_data(surface); + boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32; int oa, or, og, ob; if (OS.BIG_ENDIAN) { oa = 0; or = 1; og = 2; ob = 3; } else { oa = 3; or = 2; og = 1; ob = 0; } - OS.memmove(srcData, this.surfaceData, srcData.length); + byte[] srcData = new byte[stride * height]; + OS.memmove(srcData, surfaceData, srcData.length); PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); data = new ImageData(width, height, 32, palette, 4, srcData); - for (int y = 0, offset = 0; y < height; y++) { - for (int x = 0; x < width; x++, offset += 4) { - int a = srcData[offset + oa] & 0xFF; - int r = srcData[offset + or] & 0xFF; - int g = srcData[offset + og] & 0xFF; - int b = srcData[offset + ob] & 0xFF; - srcData[offset + 0] = (byte)a; - if (a != 0) { - srcData[offset + 1] = (byte)(((r) / (float)a) * 0xFF); - srcData[offset + 2] = (byte)(((g) / (float)a) * 0xFF); - srcData[offset + 3] = (byte)(((b) / (float)a) * 0xFF); + if (hasAlpha) { + byte[] alphaData = data.alphaData = new byte[width * height]; + for (int y = 0, offset = 0, alphaOffset = 0; y < height; y++) { + for (int x = 0; x < width; x++, offset += 4) { + int a = srcData[offset + oa] & 0xFF; + int r = srcData[offset + or] & 0xFF; + int g = srcData[offset + og] & 0xFF; + int b = srcData[offset + ob] & 0xFF; + srcData[offset + 0] = 0; + alphaData[alphaOffset++] = (byte)a; + if (a != 0) { + //TODO write this without floating point math + srcData[offset + 1] = (byte)(((r) / (float)a) * 0xFF); + srcData[offset + 2] = (byte)(((g) / (float)a) * 0xFF); + srcData[offset + 3] = (byte)(((b) / (float)a) * 0xFF); + } } } - } - - /* - * TODO is it impossible to retrieve the RGB values when alpha is zero? If this is true - * then this code is necessary because the transparent pixel needs the RGB values to work. - */ - if (transparentPixel != -1) { - byte[] alphaData = data.alphaData = new byte[width * height]; - for (int y = 0, offset = 3, alphaOffset = 0; y < height; y++) { + } else { + for (int y = 0, offset = 0; y < height; y++) { for (int x = 0; x < width; x++, offset += 4) { - alphaData[alphaOffset++] = srcData[offset]; + byte r = srcData[offset + or]; + byte g = srcData[offset + og]; + byte b = srcData[offset + ob]; + srcData[offset + 0] = 0; + srcData[offset + 1] = r; + srcData[offset + 2] = g; + srcData[offset + 3] = b; } } } - - for (int i = 0; i < srcData.length; i+= 4) { - srcData[i] = 0; - } } else { int[] w = new int[1], h = new int[1]; OS.gdk_drawable_get_size(pixmap, w, h); @@ -1057,11 +1057,11 @@ public ImageData getImageData() { data.maskData = maskData; } data.transparentPixel = transparentPixel; - } - data.alpha = alpha; - if (alpha == -1 && alphaData != null) { - data.alphaData = new byte[alphaData.length]; - System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); + data.alpha = alpha; + if (alpha == -1 && alphaData != null) { + data.alphaData = new byte[alphaData.length]; + System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); + } } return data; } @@ -1140,11 +1140,10 @@ void init(int width, int height) { /* Create the pixmap */ if (OS.USE_CAIRO_SURFACE) { - int stride = Cairo.cairo_format_stride_for_width(Cairo.CAIRO_FORMAT_RGB24, width); - int /*long*/ data = surfaceData = OS.g_malloc(stride * height); - if (surfaceData == 0) SWT.error(SWT.ERROR_NO_HANDLES); - surface = Cairo.cairo_image_surface_create_for_data(surfaceData, Cairo.CAIRO_FORMAT_RGB24, width, height, stride); + surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_RGB24, width, height); if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int stride = Cairo.cairo_image_surface_get_stride(surface); + int /*long*/ data = Cairo.cairo_image_surface_get_data(surface); OS.memset(data, 0xff, stride * height); this.width = width; this.height = height; @@ -1175,11 +1174,12 @@ void init(ImageData image) { ((image.depth == 8) || (image.depth == 16 || image.depth == 24 || image.depth == 32) && palette.isDirect))) SWT.error (SWT.ERROR_UNSUPPORTED_DEPTH); if (OS.USE_CAIRO_SURFACE) { - int stride = Cairo.cairo_format_stride_for_width(Cairo.CAIRO_FORMAT_ARGB32, width); - int /*long*/ data = surfaceData = OS.g_malloc(stride * height); - if (surfaceData == 0) SWT.error(SWT.ERROR_NO_HANDLES); - surface = Cairo.cairo_image_surface_create_for_data(surfaceData, Cairo.CAIRO_FORMAT_ARGB32, width, height, stride); + boolean hasAlpha = image.transparentPixel != -1 || image.alpha != -1 || image.maskData != null || image.alphaData != null; + int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24; + surface = Cairo.cairo_image_surface_create(format, width, height); if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int stride = Cairo.cairo_image_surface_get_stride(surface); + int /*long*/ data = Cairo.cairo_image_surface_get_data(surface); int oa = 0, or = 0, og = 0, ob = 0; int redMask, greenMask, blueMask, destDepth = 32, destOrder; if (OS.BIG_ENDIAN) { @@ -1297,12 +1297,6 @@ void init(ImageData image) { buffer[offset + ob] = (byte)b; } } - } else { - for (int y = 0, offset = 0; y < height; y++) { - for (int x=0; x<width; x++, offset += 4) { - buffer[offset + oa] = (byte)0xFF; - } - } } } OS.memmove(data, buffer, stride * height); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java index 1702cfc4c8..ce9acd2df3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java @@ -12,6 +12,7 @@ package org.eclipse.swt.internal; import org.eclipse.swt.SWT; +import org.eclipse.swt.internal.cairo.*; import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.graphics.*; @@ -28,35 +29,56 @@ public ImageList() { public static int /*long*/ createPixbuf(Image image) { int /*long*/ pixbuf; if (OS.USE_CAIRO_SURFACE) { - Rectangle bounds = image.getBounds(); - int w = bounds.width, h = bounds.height; - pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, true, 8, w, h); + int /*long*/ surface = image.surface; + int format = Cairo.cairo_image_surface_get_format(surface); + int width = Cairo.cairo_image_surface_get_width(surface); + int height = Cairo.cairo_image_surface_get_height(surface); + boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32; + pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, hasAlpha, 8, width, height); if (pixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); int stride = OS.gdk_pixbuf_get_rowstride (pixbuf); int /*long*/ pixels = OS.gdk_pixbuf_get_pixels (pixbuf); - byte[] line = new byte[stride]; int oa, or, og, ob; if (OS.BIG_ENDIAN) { oa = 0; or = 1; og = 2; ob = 3; } else { oa = 3; or = 2; og = 1; ob = 0; } - int /*long*/ surfaceData = image.surfaceData; - for (int y = 0; y < h; y++) { - OS.memmove (line, surfaceData + (y * stride), stride); - for (int x = 0, offset = 0; x < w; x++, offset += 4) { - int a = line[offset + oa] & 0xFF; - int r = line[offset + or] & 0xFF; - int g = line[offset + og] & 0xFF; - int b = line[offset + ob] & 0xFF; - line[offset + 3] = (byte)a; - if (a != 0) { - line[offset + 0] = (byte)(((r) / (float)a) * 0xFF); - line[offset + 1] = (byte)(((g) / (float)a) * 0xFF); - line[offset + 2] = (byte)(((b) / (float)a) * 0xFF); + byte[] line = new byte[stride]; + int /*long*/ surfaceData = Cairo.cairo_image_surface_get_data(surface); + if (hasAlpha) { + for (int y = 0; y < height; y++) { + OS.memmove (line, surfaceData + (y * stride), stride); + for (int x = 0, offset = 0; x < width; x++, offset += 4) { + int a = line[offset + oa] & 0xFF; + int r = line[offset + or] & 0xFF; + int g = line[offset + og] & 0xFF; + int b = line[offset + ob] & 0xFF; + line[offset + 3] = (byte)a; + if (a != 0) { + //TODO write this without floating point math + line[offset + 0] = (byte)(((r) / (float)a) * 0xFF); + line[offset + 1] = (byte)(((g) / (float)a) * 0xFF); + line[offset + 2] = (byte)(((b) / (float)a) * 0xFF); + } + } + OS.memmove (pixels + (y * stride), line, stride); + } + } else { + int cairoStride = Cairo.cairo_image_surface_get_stride(surface); + byte[] cairoLine = new byte[cairoStride]; + for (int y = 0; y < height; y++) { + OS.memmove (cairoLine, surfaceData + (y * cairoStride), cairoStride); + for (int x = 0, offset = 0, cairoOffset = 0; x < width; x++, offset += 3, cairoOffset += 4) { + byte r = cairoLine[cairoOffset + or]; + byte g = cairoLine[cairoOffset + og]; + byte b = cairoLine[cairoOffset + ob]; + line[offset + 0] = r; + line[offset + 1] = g; + line[offset + 2] = b; } + OS.memmove (pixels + (y * stride), line, stride); } - OS.memmove (pixels + (y * stride), line, stride); } } else { int [] w = new int [1], h = new int [1]; |