/*****************************************************************************
* Copyright (c) 2010 CEA LIST.
*
*
* 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:
* Saadia Dhouib saadia.dhouib@cea.fr - Adapted from Composite Structure Diagram
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.communication.custom.helper;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
// TODO: Auto-generated Javadoc
/**
* This is a helper for rotating swt figures, it provides a method for computing
* an rotation angle provided two points, and methods for rotating an swt image.
*/
public class RotationHelper {
/**
* Gets the default configuration.
*
* @return the GraphicsConfiguration
*/
public static GraphicsConfiguration getDefaultConfiguration() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
return gd.getDefaultConfiguration();
}
/**
*
* This method calculates the rotation clockwise angle w.r.t the source and
* target connection anchor positions
*
* @param S
* Source connection anchor
* @param T
* Target connection anchor
* @return The rotation clockwise angle w.r.t the source and target
* connection
*/
public static double calculateRotAngle(Point S, Point T) {
double dx = T.x - S.x;
double dy = T.y - S.y;
double angle = 0.0d;
if((dx > 0) && (dy < 0)) {
angle = -Math.atan(Math.abs(dy) / Math.abs(dx));
// System.out.print("(dx > 0) && (dy < 0)\n");
} else if((dx < 0) && (dy < 0)) {
angle = -(Math.PI - Math.atan(Math.abs(dy) / Math.abs(dx)));
// System.out.print("(dx < 0) && (dy < 0)\n");
} else if((dx < 0) && (dy > 0)) {
angle = Math.PI - Math.atan(Math.abs(dy) / Math.abs(dx));
// System.out.print("(dx < 0) && (dy > 0)\n");
} else if((dx > 0) && (dy > 0)) {
angle = Math.atan(Math.abs(dy) / dx);
// System.out.print("((dx > 0) && (dy > 0)\n");
} else if((dx == 0) && (dy < 0)) {
angle = -Math.PI / 2;
// System.out.print("((dx == 0) && (dy < 0))\n");
} else if((dx == 0) && (dy > 0)) {
angle = Math.PI / 2;
// System.out.print("((dx == 0) && (dy > 0))\n");
} else if((dy == 0) && (dx < 0)) {
angle = -Math.PI;
// System.out.print("((dy == 0) && (dx < 0))\n");
}
return Math.toDegrees(angle);
}
/**
* rotates an awt image.
*
* @param image
* awt image
* @param angle
* angle of rotation in radians
* @return swt rotated image
*/
public static ImageData tilt(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(angle);
int w = image.getWidth(), h = image.getHeight();
int neww = w;
int newh = h;
if(((int)sin != 0) || ((int)cos != 0))
{
neww = (int)Math.floor(w * cos + h * sin);
newh = (int)Math.floor(h * cos + w * sin);
}
GraphicsConfiguration gc = getDefaultConfiguration();
BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = result.createGraphics();
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawRenderedImage(image, null);
g.dispose();
return convertToSWT(result);
}
/**
* rotates an awt image using Affine Transform.
*
* @param image
* awt image
* @param degree
* angle of rotation in degrees
* @return swt rotated image
*/
public static ImageData tiltBis(java.awt.Image image, double degree) {
int w = image.getWidth(null);
int h = image.getHeight(null);
double angle = Math.toRadians(degree);
double sin = Math.abs(Math.sin(angle));
double cos = Math.abs(Math.cos(angle));
int neww = (int)Math.floor(w * cos + h * sin);
int newh = (int)Math.floor(h * cos + w * sin);
AffineTransform at = new AffineTransform();
//at.scale((w + 0.0) / (neww + 0.0), (h + 0.0) / (newh + 0.0));
at.translate((neww - w) / 2, (newh - h) / 2);
at.rotate(angle, w / 2, h / 2);
BufferedImage b = new BufferedImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = b.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(image, at, null);
g.dispose();
return convertToSWT(b);
}
/**
* Rotates the swt image.
*
* @param img
* the img
* @param degree
* the degree
* @return the rotated image
*/
public static ImageData rotateImage(Image img, double degree) {
ImageData data = img.getImageData();
BufferedImage bufImg = convertToAWT(data);
//double angle = Math.toRadians(degree);
//return tilt(bufImg, angle);
return tiltBis(bufImg, degree);
}
/**
* convert awt BufferedImage to swt ImageData.
*
* @param bufferedImage
* the buffered image
* @return converted ImageData
*/
public static ImageData convertToSWT(BufferedImage bufferedImage) {
if(bufferedImage.getColorModel() instanceof DirectColorModel) {
DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
for(int y = 0; y < data.height; y++) {
for(int x = 0; x < data.width; x++) {
int rgb = bufferedImage.getRGB(x, y);
int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
data.setPixel(x, y, pixel);
if(colorModel.hasAlpha()) {
data.setAlpha(x, y, (rgb >> 24) & 0xFF);
}
}
}
return data;
} else if(bufferedImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
int size = colorModel.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
colorModel.getReds(reds);
colorModel.getGreens(greens);
colorModel.getBlues(blues);
RGB[] rgbs = new RGB[size];
for(int i = 0; i < rgbs.length; i++) {
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
}
PaletteData palette = new PaletteData(rgbs);
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
data.transparentPixel = colorModel.getTransparentPixel();
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for(int y = 0; y < data.height; y++) {
for(int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
}
return data;
}
return null;
}
/**
* converts swt image to awt.
*
* @param data
* swt ImageData
* @return awt BufferdImage
*/
public static BufferedImage convertToAWT(ImageData data) {
ColorModel colorModel = null;
PaletteData palette = data.palette;
if(palette.isDirect) {
colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask);
BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
for(int y = 0; y < data.height; y++) {
for(int x = 0; x < data.width; x++) {
int pixel = data.getPixel(x, y);
RGB rgb = palette.getRGB(pixel);
bufferedImage.setRGB(x, y, rgb.red << 16 | rgb.green << 8 | rgb.blue);
}
}
return bufferedImage;
} else {
RGB[] rgbs = palette.getRGBs();
byte[] red = new byte[rgbs.length];
byte[] green = new byte[rgbs.length];
byte[] blue = new byte[rgbs.length];
for(int i = 0; i < rgbs.length; i++) {
RGB rgb = rgbs[i];
red[i] = (byte)rgb.red;
green[i] = (byte)rgb.green;
blue[i] = (byte)rgb.blue;
}
if(data.transparentPixel != -1) {
colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel);
} else {
colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue);
}
BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for(int y = 0; y < data.height; y++) {
for(int x = 0; x < data.width; x++) {
int pixel = data.getPixel(x, y);
pixelArray[0] = pixel;
raster.setPixel(x, y, pixelArray);
}
}
return bufferedImage;
}
}
}