/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ 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.*; public class ImageList { int /*long*/ [] pixbufs; int width = -1, height = -1; Image [] images; public ImageList() { images = new Image [4]; pixbufs = new int /*long*/ [4]; } public static int /*long*/ convertSurface(Image image) { int /*long*/ newSurface = image.surface; int type = Cairo.cairo_surface_get_type(newSurface); if (type != Cairo.CAIRO_SURFACE_TYPE_IMAGE) { Rectangle bounds = image.getBounds(); int format = Cairo.cairo_surface_get_content(newSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32; newSurface = Cairo.cairo_image_surface_create(format, bounds.width, bounds.height); if (newSurface == 0) SWT.error(SWT.ERROR_NO_HANDLES); int /*long*/ cairo = Cairo.cairo_create(newSurface); if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES); Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE); Cairo.cairo_set_source_surface (cairo, image.surface, 0, 0); Cairo.cairo_paint (cairo); Cairo.cairo_destroy(cairo); } else { Cairo.cairo_surface_reference(newSurface); } return newSurface; } public static int /*long*/ createPixbuf(Image image) { int /*long*/ pixbuf; if (OS.USE_CAIRO) { int /*long*/ surface = convertSurface(image); 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); 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; } 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) { line[offset + 0] = (byte)(((r * 0xFF) + a / 2) / a); line[offset + 1] = (byte)(((g * 0xFF) + a / 2) / a); line[offset + 2] = (byte)(((b * 0xFF) + a / 2) / a); } } 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); } } Cairo.cairo_surface_destroy(surface); } else { int [] w = new int [1], h = new int [1]; if (OS.GTK_VERSION >= OS.VERSION(2, 24, 0)) { OS.gdk_pixmap_get_size(image.pixmap, w, h); } else { OS.gdk_drawable_get_size (image.pixmap, w, h); } int /*long*/ colormap = OS.gdk_colormap_get_system (); boolean hasMask = image.mask != 0 && OS.gdk_drawable_get_depth (image.mask) == 1; if (hasMask) { pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, true, 8, w [0], h [0]); if (pixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); OS.gdk_pixbuf_get_from_drawable (pixbuf, image.pixmap, colormap, 0, 0, 0, 0, w [0], h [0]); int /*long*/ maskPixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, w [0], h [0]); if (maskPixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); OS.gdk_pixbuf_get_from_drawable(maskPixbuf, image.mask, 0, 0, 0, 0, 0, w [0], h [0]); int stride = OS.gdk_pixbuf_get_rowstride(pixbuf); int /*long*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf); byte[] line = new byte[stride]; int maskStride = OS.gdk_pixbuf_get_rowstride(maskPixbuf); int /*long*/ maskPixels = OS.gdk_pixbuf_get_pixels(maskPixbuf); byte[] maskLine = new byte[maskStride]; for (int y=0; y