blob: b2ef9cd27ed5884e14a68ea50bcb732d6ee0f776 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2003, 2006 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.gmf.tests.runtime.draw2d.ui.render.internal.svg;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import junit.framework.TestCase;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gmf.runtime.draw2d.ui.render.RenderInfo;
import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
import org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.image.ImageConverter;
import org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.svg.ImageTranscoderEx;
import org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.svg.SVGImage;
import org.eclipse.gmf.runtime.draw2d.ui.render.factory.RenderedImageFactory;
import org.eclipse.gmf.runtime.draw2d.ui.render.internal.RenderHelper;
import org.eclipse.gmf.runtime.draw2d.ui.render.internal.RenderingListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.osgi.framework.Bundle;
/**
* @author sshaw
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class SVGImageTest
extends TestCase {
/**
* The icons root directory.
*/
private static final String PREFIX_ROOT = "resources/svg/"; //$NON-NLS-1$
private static final String SVG_BLACKWHITE = PREFIX_ROOT + "blackwhite.svg"; //$NON-NLS-1$
private static final String SVG_SHAPES = PREFIX_ROOT + "shapes.svg";//$NON-NLS-1$
private static final String SVG_UMLSHAPES = PREFIX_ROOT + "uml.svg";//$NON-NLS-1$
private static final String SVG_TRANSPARENCY_TEST = PREFIX_ROOT + "presenter.svg";//$NON-NLS-1$
private final int WIDTH = 200;
private final int HEIGHT = 200;
private final int NEW_WIDTH = 120;
private final int NEW_HEIGHT = 140;
private final RGB NEW_FILL = new RGB(255, 0, 0);
private final RGB NEW_OUTLINE = new RGB(0, 255, 0);
private RenderedImage fixture1;
private RenderedImage fixture2;
private RenderedImage fixture3;
private RenderedImage fixture4;
public SVGImageTest(String name) {
super(name);
}
private RenderedImage getFixture1() {
return fixture1;
}
private RenderedImage getFixture2() {
return fixture2;
}
private RenderedImage getFixture3() {
return fixture3;
}
private RenderedImage getFixture4() {
return fixture4;
}
protected void setUp() {
try {
// Initialize the path the the resources.
Bundle bundle = Platform.getBundle("org.eclipse.gmf.tests.runtime.draw2d.ui.render" ); //$NON-NLS-1$
URL url = FileLocator.find(bundle, new Path(SVG_UMLSHAPES), null);
fixture1 = RenderedImageFactory.getInstance(url);
assertNotNull("Fixture1 shouldn't be null", fixture1); //$NON-NLS-1$
RenderInfo info = RenderedImageFactory.createInfo(WIDTH, HEIGHT,
false, false, (RGB) null, (RGB) null);
url = FileLocator.find(bundle, new Path(SVG_SHAPES), null);
fixture2 = RenderedImageFactory.getInstance(url, info);
assertNotNull("Fixture2 shouldn't be null", fixture2); //$NON-NLS-1$
url = FileLocator.find(bundle, new Path(SVG_BLACKWHITE), null);
fixture3 = RenderedImageFactory.getInstance(url);
assertNotNull("Fixture3 shouldn't be null", fixture3); //$NON-NLS-1$
url = FileLocator.find(bundle, new Path(SVG_TRANSPARENCY_TEST), null);
fixture4 = RenderedImageFactory.getInstance(url);
assertNotNull("Fixture3 shouldn't be null", fixture4); //$NON-NLS-1$
} catch (Exception e) {
fail("The SVGImageTest.setUp method caught an exception - " + e); //$NON-NLS-1$
}
}
public void testGetRenderInfo() {
RenderInfo info = getFixture1().getRenderInfo();
assertTrue("getRenderInfo fixture 1 return null", info != null); //$NON-NLS-1$
info = getFixture2().getRenderInfo();
assertTrue("getRenderInfo fixture 2 return null", info != null); //$NON-NLS-1$
assertTrue("getRenderInfo fixture 2 width / height not correct", //$NON-NLS-1$
info.getWidth() == WIDTH && info.getHeight() == HEIGHT);
}
public void testGetNewRenderedImage() {
RenderInfo info = RenderedImageFactory.createInfo(NEW_WIDTH,
NEW_HEIGHT, true, true, NEW_FILL, NEW_OUTLINE);
assertTrue(info != null);
info = RenderedImageFactory.createInfo(NEW_WIDTH, NEW_HEIGHT, false, false, null,
NEW_OUTLINE);
assertTrue(info != null);
}
private void performBatikRendering(SVGImage svg1, int width, int height) {
InputStream in = new ByteArrayInputStream(svg1.getBuffer());
RenderInfo info = svg1.getRenderInfo();
ImageTranscoderEx transcoder = new ImageTranscoderEx();
if (width > 0)
transcoder.addTranscodingHint(ImageTranscoderEx.KEY_WIDTH,
new Float(width));
if (height > 0)
transcoder.addTranscodingHint(ImageTranscoderEx.KEY_HEIGHT,
new Float(height));
transcoder.addTranscodingHint(
ImageTranscoderEx.KEY_MAINTAIN_ASPECT_RATIO, Boolean.valueOf(info
.shouldMaintainAspectRatio()));
transcoder.addTranscodingHint(ImageTranscoderEx.KEY_ANTI_ALIASING,
Boolean.valueOf(info.shouldAntiAlias()));
if (info.getBackgroundColor() != null) {
transcoder
.addTranscodingHint(ImageTranscoderEx.KEY_FILL_COLOR, new RGB(
info.getBackgroundColor().red,
info.getBackgroundColor().green,
info.getBackgroundColor().blue));
}
if (info.getForegroundColor() != null) {
transcoder
.addTranscodingHint(ImageTranscoderEx.KEY_OUTLINE_COLOR,
new RGB(info.getForegroundColor().red, info
.getForegroundColor().green,
info.getForegroundColor().blue));
}
TranscoderInput input = new TranscoderInput(in);
TranscoderOutput output = new TranscoderOutput();
try {
transcoder.transcode(input, output);
} catch (TranscoderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedImage bufImg = transcoder.getBufferedImage();
Image swtImage = ImageConverter.convert(bufImg);
assertNotNull("swtImage fixture 1 Image invalid", swtImage); //$NON-NLS-1$
}
private void performRenderedImageRendering(SVGImage svg1, int width,
int height) {
RenderInfo info = svg1.getRenderInfo();
info.setValues(width, height, true, true, info.getBackgroundColor(), info
.getForegroundColor());
RenderedImage ri = svg1.getNewRenderedImage(info);
Image img = ri.getSWTImage();
assertNotNull("getSWTImage fixture 1 Image invalid", img); //$NON-NLS-1$
}
final static int START_DIM = 100;
final static int END_DIM = 1000;
final static int INC_DIM = 10;
public void testRenderedImagePerformance() {
SVGImage svg1 = (SVGImage) getFixture1();
int width = START_DIM;
int height = START_DIM;
long batikTime = 0;
long renderTime = 0;
// do one rendering outside to initialize Batik;
performBatikRendering(svg1, width, height);
long startTime = System.currentTimeMillis();
while (width < END_DIM && height < END_DIM) {
performBatikRendering(svg1, width, height);
width += INC_DIM;
height += INC_DIM;
}
long endTime = System.currentTimeMillis();
batikTime = endTime - startTime;
startTime = System.currentTimeMillis();
width = START_DIM;
height = START_DIM;
while (width < END_DIM && height < END_DIM) {
performRenderedImageRendering(svg1, width, height);
width += INC_DIM;
height += INC_DIM;
}
endTime = System.currentTimeMillis();
renderTime = endTime - startTime;
System.out.println("Batik rendering time was: " + batikTime); //$NON-NLS-1$
System.out.println("RenderedImage rendering time was: " + renderTime); //$NON-NLS-1$
System.out
.println("Percentage difference: " + (renderTime - batikTime) / (float) batikTime * 100 + "%"); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue(renderTime < batikTime);
}
static private class RenderingListenerImpl
implements RenderingListener {
boolean done = false;
public RenderingListenerImpl() {
super();
}
boolean isDone() {
return done;
}
/* (non-Javadoc)
* @see org.eclipse.gmf.runtime.draw2d.ui.render.internal.RenderingListener#paintFigureWhileRendering(org.eclipse.draw2d.Graphics)
*/
public void paintFigureWhileRendering(Graphics g) {
// do nothing
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.draw2d.ui.render.RenderingListener#imageRendered(org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage)
*/
synchronized public void imageRendered(RenderedImage rndImg) {
done = true;
assertTrue(rndImg.isRendered());
assertTrue(rndImg.getSWTImage() != null);
}
}
public void testRenderHelper() {
Display display = Display.getDefault();
Image image = new Image(display, new Rectangle(0, 0, 500, 500));
GC gc = new GC(image);
SWTGraphics swtG = new SWTGraphics(gc);
org.eclipse.draw2d.geometry.Rectangle target = new org.eclipse.draw2d.geometry.Rectangle(
50, 50, 94, 94);
RenderInfo info = getFixture1().getRenderInfo();
info.setValues(target.width, target.height, true, true, info.getBackgroundColor(),
info.getForegroundColor());
RenderedImage ri = getFixture1().getNewRenderedImage(info);
// first test with delay render turned off
RenderHelper renderHelper = RenderHelper.getInstance(1.0, false, false,
null);
RenderingListenerImpl listener = new RenderingListenerImpl();
RenderedImage retImage = renderHelper.drawRenderedImage(swtG, ri,
target, listener);
assertTrue(retImage.isRendered());
assertTrue(retImage.getSWTImage() != null);
// second test with delay render turned on
target.width -= 10;
target.height -= 10;
listener = new RenderingListenerImpl();
renderHelper = RenderHelper.getInstance(1.0, false, true, null);
retImage = renderHelper.drawRenderedImage(swtG, retImage, target,
listener);
int i = 0;
while (!retImage.isRendered() && i < 100) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
}
assertTrue(retImage.isRendered() && i < 100);
}
static final private Dimension MAX_RENDER_SIZE = new Dimension(200, 200);
public void testRenderMaxSize() {
Display display = PlatformUI.getWorkbench().getDisplay();
Image image = new Image(display, new Rectangle(0, 0, 500, 500));
GC gc = new GC(image);
SWTGraphics swtG = new SWTGraphics(gc);
org.eclipse.draw2d.geometry.Rectangle target = new org.eclipse.draw2d.geometry.Rectangle(
0, 0, MAX_RENDER_SIZE.width * 2, MAX_RENDER_SIZE.height * 2);
RenderInfo info = getFixture1().getRenderInfo();
info.setValues(MAX_RENDER_SIZE.width * 2, MAX_RENDER_SIZE.height * 2,
false, true, info.getBackgroundColor(), info.getForegroundColor());
RenderedImage ri = getFixture1().getNewRenderedImage(info);
// first test with no maximum render size
RenderHelper renderHelper = RenderHelper.getInstance(1.0, false, false,
null);
RenderingListenerImpl listener = new RenderingListenerImpl();
RenderedImage retImage = renderHelper.drawRenderedImage(swtG, ri,
target, listener);
assertTrue(retImage.isRendered());
assertTrue(retImage.getSWTImage() != null);
assertTrue(Math.abs(retImage.getSWTImage().getBounds().width - (MAX_RENDER_SIZE.width * 2)) <= 5);
assertTrue(Math.abs(retImage.getSWTImage().getBounds().height - (MAX_RENDER_SIZE.height * 2)) <=5);
// now test with maximum render size
renderHelper = RenderHelper.getInstance(1.0, false, false,
MAX_RENDER_SIZE);
retImage = renderHelper.drawRenderedImage(swtG, ri,
target, listener);
assertTrue(retImage.isRendered());
assertTrue(retImage.getSWTImage() != null);
assertTrue(retImage.getSWTImage().getBounds().width <= MAX_RENDER_SIZE.width);
assertTrue(retImage.getSWTImage().getBounds().height <= MAX_RENDER_SIZE.height);
}
private boolean findColor(Image srcImage, RGB colorToFind) {
BufferedImage bufImg = ImageConverter.convert(srcImage);
int width = bufImg.getWidth();
int height = bufImg.getHeight();
// loop over the imagedata and set each pixel in the BufferedImage to
// the appropriate color.
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int color = bufImg.getRGB(x, y);
Color swtColor = integerToColor(color);
RGB checkColor = new RGB(swtColor.getRed(),
swtColor.getGreen(), swtColor.getBlue());
swtColor.dispose();
if (checkColor.equals(colorToFind))
return true;
}
}
return false;
}
/**
* Method integerToColor. converts from an int (from BufferedImage) to a
* Color representation
*
* Note: Normally, colors should be instantiated using the
* AbstractResourceManager.
*
* @param i
* @return Color
*/
private Color integerToColor(int color) {
return new Color(null, (color & 0x00FF0000) >> 16,
(color & 0x0000FF00) >> 8, (color & 0x000000FF));
}
private static RGB BLACK = new RGB(0, 0, 0);
private static RGB WHITE = new RGB(255, 255, 255);
private static RGB RED = new RGB(255, 0, 0);
private static RGB GREEN = new RGB(0, 255, 0);
public void testChangeColors() {
RenderedImage fixture = getFixture3();
RenderInfo info = fixture.getRenderInfo();
Image swtImg1 = fixture.getSWTImage();
assertTrue(findColor(swtImg1, BLACK));
assertTrue(findColor(swtImg1, WHITE));
assertFalse(findColor(swtImg1, RED));
assertFalse(findColor(swtImg1, GREEN));
// ImageLoader imageLoader = new ImageLoader();
// imageLoader.data = new ImageData[] {swtImg1.getImageData()};
// imageLoader.logicalScreenHeight = swtImg1.getBounds().width;
// imageLoader.logicalScreenHeight = swtImg1.getBounds().height;
// imageLoader.save("C:\\originalImg.bmp", SWT.IMAGE_BMP);
// set color first time - red fill, red outline
info.setValues(info.getWidth(), info.getHeight(), true, true, RED, RED);
RenderedImage colorImg1 = fixture.getNewRenderedImage(info);
Image swtImg2 = colorImg1.getSWTImage();
assertNotNull("getSWTImage colorImg1 Image invalid", swtImg1); //$NON-NLS-1$
// imageLoader = new ImageLoader();
// imageLoader.data = new ImageData[] {swtImg2.getImageData()};
// imageLoader.logicalScreenHeight = swtImg2.getBounds().width;
// imageLoader.logicalScreenHeight = swtImg2.getBounds().height;
// imageLoader.save("C:\\redImg.bmp", SWT.IMAGE_BMP);
assertTrue(findColor(swtImg2, RED));
assertFalse(findColor(swtImg2, GREEN));
// set color second time - green fill, green outline
info.setValues(info.getWidth(), info.getHeight(), true,
true, GREEN, GREEN);
RenderedImage colorImg2 = fixture.getNewRenderedImage(info);
Image swtImg3 = colorImg2.getSWTImage();
assertNotNull("getSWTImage colorImg1 Image invalid", swtImg1); //$NON-NLS-1$
assertNotNull("getSWTImage colorImg2 Image invalid", swtImg2); //$NON-NLS-1$
// imageLoader = new ImageLoader();
// imageLoader.data = new ImageData[] {swtImg3.getImageData()};
// imageLoader.logicalScreenHeight = swtImg3.getBounds().width;
// imageLoader.logicalScreenHeight = swtImg3.getBounds().height;
// imageLoader.save("C:\\greenImg.bmp", SWT.IMAGE_BMP);
assertTrue(colorImg1 != colorImg2);
assertTrue(findColor(swtImg3, GREEN));
assertFalse(findColor(swtImg3, RED));
}
// cropping not supported yet
// static final int SHRINK_EXT = 50;
// static final int CROPTEST_START_SIZE = 400;
//
// public void testCroppedImage() {
// org.eclipse.draw2d.geometry.Rectangle target = new
// org.eclipse.draw2d.geometry.Rectangle(0, 0, CROPTEST_START_SIZE,
// CROPTEST_START_SIZE);
// RenderInfo info = getFixture1().getRenderInfo();
// info.setValues(target.width, target.height, info.getBackgroundColor(),
// info.getForegroundColor(), false, true);
//
// RenderedImage first = getFixture1().getNewRenderedImage(info);
// Image firstImage = first.getSWTImage();
// Rectangle firstBounds = firstImage.getBounds();
// assertTrue(firstBounds.width == CROPTEST_START_SIZE && firstBounds.height
// == CROPTEST_START_SIZE);
// ImageLoader imageLoader = new ImageLoader();
// imageLoader.data = new ImageData[] {firstImage.getImageData()};
// imageLoader.logicalScreenHeight = firstImage.getBounds().width;
// imageLoader.logicalScreenHeight = firstImage.getBounds().height;
// imageLoader.save("C:\\originalImg.bmp", SWT.IMAGE_BMP);
//
// RenderedImage cropped = first.getCroppedImage(target.shrink(SHRINK_EXT,
// SHRINK_EXT));
//
// Image croppedImage = cropped.getSWTImage();
// Rectangle croppedBounds = croppedImage.getBounds();
// //assertTrue(croppedBounds.width == CROPTEST_START_SIZE - (SHRINK_EXT *
// 2)
// // && croppedBounds.height == CROPTEST_START_SIZE - (SHRINK_EXT * 2));
//
// imageLoader = new ImageLoader();
// imageLoader.data = new ImageData[] {croppedImage.getImageData()};
// imageLoader.logicalScreenHeight = croppedImage.getBounds().width;
// imageLoader.logicalScreenHeight = croppedImage.getBounds().height;
// imageLoader.save("C:\\croppedImg.bmp", SWT.IMAGE_BMP);
// }
public void testGetSWTImage() {
Image img = getFixture1().getSWTImage();
assertNotNull("getSWTImage fixture 1 Image invalid", img); //$NON-NLS-1$
img = getFixture2().getSWTImage();
assertNotNull("getSWTImage fixture 2 Image invalid", img); //$NON-NLS-1$
}
public void testTransparency() {
Image img = getFixture4().getSWTImage();
ImageData imgData = img.getImageData();
Rectangle bounds = img.getBounds();
// check 4 corners
assertTrue(isTransparentAt(imgData, bounds.x + 1, bounds.y + 1));
assertTrue(isTransparentAt(imgData, bounds.x + bounds.width - 2, bounds.y + 1));
assertTrue(isTransparentAt(imgData, bounds.x + 1, bounds.y + bounds.height - 2));
assertTrue(isTransparentAt(imgData, bounds.x + bounds.width - 2, bounds.y + bounds.height - 2));
}
protected boolean isTransparentAt(ImageData data, int x, int y) {
// boundary checking
if (x < 0 || x >= data.width || y < 0
|| y >= data.height)
return true;
ImageData transMaskData = data.getTransparencyMask();
// check for alpha channel
int transValue = 255;
// check for transparency mask
if (transMaskData != null) {
transValue = transMaskData.getPixel(x, y) == 0 ? 0
: 255;
}
if (transValue != 0) {
if (data.alphaData != null) {
transValue = data.getAlpha(x, y);
}
}
// use a tolerance
boolean trans = false;
if (transValue < 10) {
trans = true;
}
return trans;
}
}