package org.jactr.eclipse.runtime.ui.probe.components;
/*
* default logging
*/
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.birt.chart.api.ChartEngine;
import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.exception.ChartException;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.core.framework.PlatformConfig;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.jactr.eclipse.runtime.probe2.ModelProbeData;
/**
* probe container that renders to an AWT.image and copies it to an SWT image
* since SWT out of thread rendering is causing core dumps on macs.
*
* @author harrison
*/
public class AWTProbeContainer extends AbstractBIRTProbeContainer
{
/**
* Logger definition
*/
static final transient Log LOGGER = LogFactory
.getLog(AWTProbeContainer.class);
private BufferedImage _chartImage;
Image _uiImage;
private Graphics2D _chartContext;
public AWTProbeContainer(Composite parent, ModelProbeData mpd)
{
super(parent, mpd);
}
@Override
public void dispose()
{
disposeAWTImage();
if (_uiImage != null && !_uiImage.isDisposed()) _uiImage.dispose();
super.dispose();
}
private void createAWTImage(int width, int height)
{
if (isDisposed()) return;
try
{
_contextLock.lock();
_chartImage = new BufferedImage(width, height,
// BufferedImage.TYPE_BYTE_INDEXED);
BufferedImage.TYPE_INT_ARGB);
_chartBounds = BoundsImpl.create(0, 0, width, height);
_chartBounds.scale(72d / _chartRenderer.getDisplayServer()
.getDpiResolution());
_chartContext = _chartImage.createGraphics();
_chartRenderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT,
_chartContext);
}
finally
{
_contextLock.unlock();
}
}
private void disposeAWTImage()
{
try
{
_contextLock.lock();
if (_chartImage != null) _chartImage = null;
if (_chartContext != null)
{
_chartContext.dispose();
_chartContext = null;
}
}
finally
{
_contextLock.unlock();
}
}
@Override
protected void swapImage()
{
try
{
_contextLock.lock();
if (_uiImage != null && !_uiImage.isDisposed()) _uiImage.dispose();
_uiImage = new Image(getDisplay(), convertToSWT(_chartImage));
}
finally
{
_contextLock.unlock();
}
}
@Override
protected IDeviceRenderer getDeviceRenderer()
{
try
{
return ChartEngine.instance(new PlatformConfig()).getRenderer("dv.SWING");
}
catch (ChartException e)
{
LOGGER.error(
"AWTProbeContainer.getDeviceRenderer threw ChartException : ", e);
return null;
}
}
@Override
protected void updateRenderContext()
{
if (isDisposed()) return;
try
{
_contextLock.lock();
disposeAWTImage();
/*
* copy the old image to the new one
*/
Rectangle bounds = getClientArea();
if (bounds.width == 0 || bounds.height == 0)
{
/*
* give it something to work with at least
*/
bounds.width = 800;
bounds.height = 500;
}
createAWTImage(bounds.width, bounds.height);
}
finally
{
_contextLock.unlock();
}
}
/**
* AWT -> SWT conversion copied from
* http://git.eclipse.org/c/platform/eclipse.
* platform.swt.git/tree/examples/org
* .eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet156.java
*
* @param bufferedImage
* @return
*/
private 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[data.width];
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++)
// {
// raster.getPixels(0, y, data.width, 1, pixelArray);
// data.setPixels(0, y, data.width, pixelArray, 0);
// }
for (int x = 0; x < data.width; x++)
{
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
return data;
}
return null;
}
@Override
protected Image getUIImage()
{
return _uiImage;
}
}