All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javafx.embed.swt.SWTFXUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javafx.embed.swt;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;

import java.lang.reflect.Method;
import java.lang.reflect.Field;

import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.image.Image;
import javafx.scene.image.WritablePixelFormat;

/**
 * This class provides utility methods for converting data types between
 * SWT and JavaFX formats.
 * @since JavaFX 2.2
 */
public class SWTFXUtils {
    private SWTFXUtils() {} // no instances

    /**
     * Snapshots the specified {@link ImageData} and stores a copy of
     * its pixels into a JavaFX {@link Image} object, creating a new
     * object if needed.
     * The returned {@code Image} will be a static snapshot of the state
     * of the pixels in the {@code ImageData} at the time the method
     * completes.  Further changes to the {@code ImageData} will not
     * be reflected in the {@code Image}.
     * 

* The optional JavaFX {@link WritableImage} parameter may be reused * to store the copy of the pixels. * A new {@code Image} will be created if the supplied object is null, * is too small or of a type which the image pixels cannot be easily * converted into. * * @param imageData the {@code ImageData} object to be converted * @param image an optional {@code WritableImage} object that can be * used to store the returned pixel data * @return an {@code Image} object representing a snapshot of the * current pixels in the {@code ImageData}, or null if * the {@code Image} is not readable. */ public static WritableImage toFXImage(ImageData imageData, WritableImage image) { byte[] data = convertImage(imageData); if (data == null) return null; int width = imageData.width; int height = imageData.height; if (image != null) { int iw = (int) image.getWidth(); int ih = (int) image.getHeight(); if (iw < width || ih < height) { image = null; } else if (width < iw || height < ih) { int empty[] = new int[iw]; PixelWriter pw = image.getPixelWriter(); PixelFormat pf = PixelFormat.getIntArgbPreInstance(); if (width < iw) { pw.setPixels(width, 0, iw-width, height, pf, empty, 0, 0); } if (height < ih) { pw.setPixels(0, height, iw, ih-height, pf, empty, 0, 0); } } } if (image == null) { image = new WritableImage(width, height); } PixelWriter pw = image.getPixelWriter(); int scan = width * 4; PixelFormat pf = PixelFormat.getByteBgraInstance(); pw.setPixels(0, 0, width, height, pf, data, 0, scan); return image; } /** * Snapshots the specified JavaFX {@link Image} object and stores a * copy of its pixels into a new {@link ImageData} object. * The method will only convert a JavaFX {@code Image} that is readable * as per the conditions on the * {@link Image#getPixelReader() Image.getPixelReader()} * method. * If the {@code Image} is not readable, as determined by its * {@code getPixelReader()} method, then this method will return null. * If the {@code Image} is a writable, or other dynamic image, then * the {@code ImageData} will only be set to the current state of * the pixels in the image as determined by its {@link PixelReader}. * Further changes to the pixels of the {@code Image} will not be * reflected in the returned {@code ImageData}. *

* The optional {@code ImageData} parameter may be reused to store * the copy of the pixels. * A new {@code ImageData} will be created if the supplied object * is null, is too small or of a type which the image pixels cannot * be easily converted into. * * @param image the JavaFX {@code Image} to be converted * @param imageData an optional {@code ImageData} object that may be * used to store the returned pixel data * @return a {@code ImageData} containing a snapshot of the JavaFX * {@code Image}, or null if the {@code Image} is not readable. */ public static ImageData fromFXImage(Image image, ImageData imageData) { PixelReader pr = image.getPixelReader(); if (pr == null) { return null; } int width = (int) image.getWidth(); int height = (int) image.getHeight(); int bpr = width * 4; int dataSize = bpr * height; byte[] buffer = new byte[dataSize]; WritablePixelFormat pf = PixelFormat.getByteBgraInstance(); pr.getPixels(0, 0, width, height, pf, buffer, 0, bpr); byte[] 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) { byte alpha = buffer[offset+3]; buffer[offset+3] = 0; alphaData[alphaOffset++] = alpha; } } PaletteData palette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); imageData = new ImageData(width, height, 32, palette, 4, buffer); imageData.alphaData = alphaData; return imageData; } private static int blitSrc; private static boolean blitSrcCache; private static int BLIT_SRC() throws Exception { if (!blitSrcCache) { blitSrc = readValue("BLIT_SRC"); blitSrcCache = true; } return blitSrc; } private static int alphaOpaque; private static boolean alphaOpaqueCache; private static int ALPHA_OPAQUE() throws Exception { if (!alphaOpaqueCache) { alphaOpaque = readValue("ALPHA_OPAQUE"); alphaOpaqueCache = true; } return alphaOpaque; } private static int msbFirst; private static boolean msbFirstCache; private static int MSB_FIRST() throws Exception { if (!msbFirstCache) { msbFirst = readValue("MSB_FIRST"); msbFirstCache = true; } return msbFirst; } private static int readValue(final String name) throws Exception { final Class clazz = ImageData.class; return AccessController.doPrivileged( new PrivilegedExceptionAction() { public Integer run() throws Exception { Field field = clazz.getDeclaredField(name); field.setAccessible(true); return field.getInt(clazz); } }); } private static Method blitDirect; private static void blit(int op, byte[] srcData, int srcDepth, int srcStride, int srcOrder, int srcX, int srcY, int srcWidth, int srcHeight, int srcRedMask, int srcGreenMask, int srcBlueMask, int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, byte[] destData, int destDepth, int destStride, int destOrder, int destX, int destY, int destWidth, int destHeight, int destRedMask, int destGreenMask, int destBlueMask, boolean flipX, boolean flipY) throws Exception { final Class clazz = ImageData.class; if (blitDirect == null) { Class I = Integer.TYPE, B = Boolean.TYPE, BA = byte[].class; final Class[] argClasses = {I, BA, I, I, I, I, I, I, I, I, I, I, I, BA, I, I, I, BA, I, I, I, I, I, I, I, I, I, I, B, B}; blitDirect = AccessController.doPrivileged( new PrivilegedExceptionAction() { public Method run() throws Exception { Method method = clazz. getDeclaredMethod("blit", argClasses); method.setAccessible(true); return method; } }); } if (blitDirect != null) { blitDirect.invoke(clazz, op, srcData, srcDepth, srcStride, srcOrder, srcX, srcY, srcWidth, srcHeight, srcRedMask, srcGreenMask, srcBlueMask, alphaMode, alphaData, alphaStride, alphaX, alphaY, destData, destDepth, destStride, destOrder, destX, destY, destWidth, destHeight, destRedMask, destGreenMask, destBlueMask, flipX, flipY); } } private static Method blitPalette; private static void blit(int op, byte[] srcData, int srcDepth, int srcStride, int srcOrder, int srcX, int srcY, int srcWidth, int srcHeight, byte[] srcReds, byte[] srcGreens, byte[] srcBlues, int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, byte[] destData, int destDepth, int destStride, int destOrder, int destX, int destY, int destWidth, int destHeight, int destRedMask, int destGreenMask, int destBlueMask, boolean flipX, boolean flipY) throws Exception { final Class clazz = ImageData.class; if (blitPalette == null) { Class I = Integer.TYPE, B = Boolean.TYPE, BA = byte[].class; final Class[] argClasses = {I, BA, I, I, I, I, I, I, I, BA, BA, BA, I, BA, I, I, I, BA, I, I, I, I, I, I, I, I, I, I, B, B}; blitPalette = AccessController.doPrivileged( new PrivilegedExceptionAction() { public Method run() throws Exception { Method method = clazz. getDeclaredMethod("blit", argClasses); method.setAccessible(true); return method; } }); } if (blitPalette != null) { blitPalette.invoke(clazz, op, srcData, srcDepth, srcStride, srcOrder, srcX, srcY, srcWidth, srcHeight, srcReds, srcGreens, srcBlues, alphaMode, alphaData, alphaStride, alphaX, alphaY, destData, destDepth, destStride, destOrder, destX, destY, destWidth, destHeight, destRedMask, destGreenMask, destBlueMask, flipX, flipY); } } private static Method getByteOrderMethod; private static int getByteOrder(ImageData image) throws Exception { final Class clazz = ImageData.class; if (getByteOrderMethod != null) { getByteOrderMethod = AccessController.doPrivileged( new PrivilegedExceptionAction() { public Method run() throws Exception { Method method = clazz.getDeclaredMethod("getByteOrder"); method.setAccessible(true); return method; } }); } if (getByteOrderMethod != null) { return (Integer)getByteOrderMethod.invoke(image); } return MSB_FIRST(); } private static byte[] convertImage(ImageData image) { byte[] buffer = null; try { PaletteData palette = image.palette; if (!(((image.depth == 1 || image.depth == 2 || image.depth == 4 || image.depth == 8) && !palette.isDirect) || ((image.depth == 8) || (image.depth == 16 || image.depth == 24 || image.depth == 32) && palette.isDirect))) { return null; } final int BLIT_SRC = BLIT_SRC(); final int ALPHA_OPAQUE = ALPHA_OPAQUE(); final int MSB_FIRST = MSB_FIRST(); int width = image.width; int height = image.height; int byteOrder = getByteOrder(image); int ao = 3; int redMask = 0xFF00; int greenMask = 0xFF0000; int blueMask = 0xFF000000; int dataSize = width * height * 4; int bpr = width * 4; buffer = new byte[dataSize]; if (palette.isDirect) { blit(BLIT_SRC, image.data, image.depth, image.bytesPerLine, byteOrder, 0, 0, width, height, palette.redMask, palette.greenMask, palette.blueMask, ALPHA_OPAQUE, null, 0, 0, 0, buffer, 32, bpr, MSB_FIRST, 0, 0, width, height, redMask, greenMask, blueMask, false, false); } else { RGB[] rgbs = palette.getRGBs(); int length = rgbs.length; byte[] srcReds = new byte[length]; byte[] srcGreens = new byte[length]; byte[] srcBlues = new byte[length]; for (int i = 0; i < rgbs.length; i++) { RGB rgb = rgbs[i]; if (rgb == null) continue; srcReds[i] = (byte)rgb.red; srcGreens[i] = (byte)rgb.green; srcBlues[i] = (byte)rgb.blue; } blit(BLIT_SRC, image.data, image.depth, image.bytesPerLine, byteOrder, 0, 0, width, height, srcReds, srcGreens, srcBlues, ALPHA_OPAQUE, null, 0, 0, 0, buffer, 32, bpr, MSB_FIRST, 0, 0, width, height, redMask, greenMask, blueMask, false, false); } /* Initialize transparency */ int transparency = image.getTransparencyType(); boolean hasAlpha = transparency != SWT.TRANSPARENCY_NONE; if (transparency == SWT.TRANSPARENCY_MASK || image.transparentPixel != -1) { ImageData maskImage = image.getTransparencyMask(); byte[] maskData = maskImage.data; int maskBpl = maskImage.bytesPerLine; int offset = 0, maskOffset = 0; for (int y = 0; y> 3)]; int v = 1 << (7 - (x & 0x7)); buffer[offset + ao] = (m & v) != 0 ? (byte)0xff : 0; offset += 4; } maskOffset += maskBpl; } } else { if (image.alpha != -1) { hasAlpha = true; int alpha = image.alpha; byte a = (byte)alpha; for (int offset=0; offset





© 2015 - 2024 Weber Informatics LLC | Privacy Policy