| /****************************************************************************** |
| * Copyright (c) 2002, 2009 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.runtime.draw2d.ui.render.internal.image; |
| |
| import java.io.ByteArrayInputStream; |
| import java.security.InvalidParameterException; |
| |
| import org.eclipse.gmf.runtime.common.core.util.Trace; |
| import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.AbstractRenderedImage; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.Draw2dRenderDebugOptions; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.Draw2dRenderPlugin; |
| import org.eclipse.gmf.runtime.draw2d.ui.render.internal.factory.RenderedImageKey; |
| import org.eclipse.jface.resource.CompositeImageDescriptor; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.ImageData; |
| import org.eclipse.swt.graphics.ImageLoader; |
| import org.eclipse.swt.graphics.PaletteData; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.RGB; |
| import org.eclipse.swt.widgets.Display; |
| |
| /** |
| * Class that represents a Image image. This is a useful abstraction so that it |
| * can be used similar to an SWT Image object. |
| * |
| * @author sshaw |
| * @canBeSeenBy org.eclipse.gmf.runtime.draw2d.ui.render.* |
| */ |
| public final class ImageRenderedImage extends AbstractRenderedImage { |
| |
| private final RGB TRANSPARENT_COLOR = new RGB(0,0,0); |
| |
| /** |
| * Draws two images, one that represents the background, and another one |
| * centered within the bounds of the first one. |
| * |
| * @author lgrahek |
| * |
| */ |
| private static class TwoImageDescriptor extends CompositeImageDescriptor { |
| |
| /** size of the combined image */ |
| private Point size; |
| /** background image (transparent) */ |
| private ImageData bgImgData; |
| /** image to be drawn on top of it */ |
| private ImageData actualImgData; |
| |
| |
| /** |
| * @param bgImgData |
| * Image to drawn first |
| * @param actualImgData |
| * Image to be drawn second |
| * @param bufferWidth |
| * Width of the final image |
| * @param bufferHeight |
| * Height of the final image |
| */ |
| public TwoImageDescriptor(ImageData bgImgData, ImageData actualImgData, |
| int bufferWidth, int bufferHeight) { |
| this.bgImgData = bgImgData; |
| this.actualImgData = actualImgData; |
| this.size = new Point(bufferWidth, bufferHeight); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int) |
| */ |
| protected void drawCompositeImage(int width, int height) { |
| // draw the base image |
| drawImage(bgImgData, 0, 0); |
| drawImage(actualImgData, |
| (size.x - actualImgData.width) / 2, (size.y - actualImgData.height) / 2); |
| } |
| |
| /** |
| * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize() |
| */ |
| protected Point getSize() { |
| return size; |
| } |
| } |
| |
| /** |
| * Constructor for SVGImage |
| * |
| * @param buffer |
| * byte[] array containing an cached SVG image file. |
| * @param key |
| * ImageKey instance which is unique for the byte array. |
| */ |
| public ImageRenderedImage(byte[] buff, RenderedImageKey key) { |
| super(buff, key); |
| } |
| |
| /** |
| * loadImageFromBuffer |
| * Utility to load the image file. Throws an exception if the image |
| * buffer is not legitimate. |
| * |
| * @throws Exception indicating that the buffer is not a legitimate or recognizable |
| * to the SWT ImageLoader class. |
| */ |
| protected Image renderImage() { |
| try { |
| ImageLoader loader = new ImageLoader(); |
| ByteArrayInputStream byteIS = new ByteArrayInputStream(getBuffer()); |
| // otherwise render the image. |
| ImageData[] origImgData = loader.load(byteIS); |
| if (origImgData == null) |
| throw new InvalidParameterException(); |
| |
| int origWidth = origImgData[0].width; |
| int origHeight = origImgData[0].height; |
| |
| int bufferWidth = getKey().getWidth() == 0 ? origWidth : getKey().getWidth(); |
| int bufferHeight = getKey().getHeight() == 0 ? origHeight : getKey().getHeight(); |
| |
| int newWidth = bufferWidth; |
| int newHeight = bufferHeight; |
| |
| Display display = DisplayUtils.getDisplay(); |
| |
| if (getKey().shouldMaintainAspectRatio()) { |
| double origAspectRatio = origHeight / (double)origWidth; |
| if (origAspectRatio > newHeight / (double)newWidth) { |
| newWidth = (int)Math.round(newHeight / origAspectRatio); |
| } else { |
| newHeight = (int)Math.round(newWidth * origAspectRatio); |
| } |
| |
| double scale = 1.0; |
| if (newWidth > bufferWidth) |
| scale = bufferWidth / newWidth; |
| if (newHeight > bufferHeight) |
| scale = Math.min(scale, bufferHeight / (double)newHeight); |
| |
| newWidth *= scale; |
| newHeight *= scale; |
| |
| // Ensure that pixels outside of the actual image are |
| // transparent by creating a background image which is transparent. |
| // TransparentBgImageDescriptor does the job. |
| PaletteData paletteData = new PaletteData(0xFF, 0xFF00, 0xFF0000); |
| ImageData imgData = new ImageData(bufferWidth, bufferHeight, 24, paletteData); |
| imgData.transparentPixel = paletteData.getPixel(TRANSPARENT_COLOR); |
| TwoImageDescriptor desc = new TwoImageDescriptor( |
| imgData, origImgData[0].scaledTo(newWidth, newHeight), bufferWidth, bufferHeight); |
| return desc.createImage(); |
| } |
| else { |
| ImageData scaledImgData = origImgData[0].scaledTo(newWidth, newHeight); |
| return new Image(display, scaledImgData); |
| } |
| } catch (Exception e) { |
| Trace.throwing(Draw2dRenderPlugin.getInstance(), Draw2dRenderDebugOptions.EXCEPTIONS_THROWING, ImageRenderedImage.class, |
| "ImageRenderedImage.renderImage() : couldn't load image from buffer", //$NON-NLS-1$ |
| e); |
| return null; |
| } |
| |
| } |
| } |