/******************************************************************************
 * Copyright (c) 2004, 2015, 2021 IBM Corporation and others.
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation
 *    Ansgar Radermacher - bug 312723, revert parts of initial changes for this issue
 ****************************************************************************/


package org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.graphics;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Composite;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.Stack;

import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeTypes;
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.metafile.GdiFont;
import org.eclipse.gmf.runtime.draw2d.ui.render.internal.DrawableRenderedImage;
import org.eclipse.gmf.runtime.draw2d.ui.render.internal.RenderingListener;
import org.eclipse.gmf.runtime.draw2d.ui.text.TextUtilitiesEx;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.LineAttributes;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.PathData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.TextLayout;

/**
 * Objects of this class can be used with draw2d to render to a Graphics2D object.
 * 
 * @author jschofie / sshaw
 */
public class GraphicsToGraphics2DAdaptor extends Graphics implements DrawableRenderedImage {

	private static class State {

		/**
		 * translateX
		 */
		public int translateX = 0;
		
		/**
		 * translateY
		 */
		public int translateY = 0;

		/**
		 * clipping rectangle x coordinate
		 */
		public int clipX = 0;
		/**
		 * clipping rectangle y coordinate
		 */
		public int clipY = 0;
		/**
		 * clipping rectangle width
		 */
		public int clipW = 0;
		/**
		 * clipping rectangle height
		 */
		public int clipH = 0;

		/** Font value **/
		/**
		 * cached font
		 */
		public Font font;
		
		/**
		 * cached xor mode value
		 */
		public boolean XorMode = false;
		/**
		 * cached foreground color
		 */
		public Color fgColor;
		/**
		 * cached background color
		 */
		public Color bgColor;
        
        /**
         * cached alpha value
         */
        public int alpha;
        
        /**
         * Line attributes value
         */
        public LineAttributes lineAttributes = new LineAttributes(1);
        
    	int graphicHints;
    	
		/**
		 * Copy the values from a given state to this state
		 * 
		 * @param state
		 *            the state to copy from
		 */
		public void copyFrom(State state) {

			translateX = state.translateX;
			translateY = state.translateY;

			clipX = state.clipX;
			clipY = state.clipY;
			clipW = state.clipW;
			clipH = state.clipH;
			
			font = state.font;
			fgColor = state.fgColor;
			bgColor = state.bgColor;
			XorMode = state.XorMode;
            alpha = state.alpha;
            graphicHints = state.graphicHints;
            
            lineAttributes = SWTGraphics.clone(state.lineAttributes);
		}
	}

	static final int ADVANCED_GRAPHICS_MASK;
	static final int ADVANCED_SHIFT;
	static final int FILL_RULE_MASK;
	static final int FILL_RULE_SHIFT;
	static final int FILL_RULE_WHOLE_NUMBER = -1;

	/*
	 * It's consistent with SWTGraphics flags in case some other flags from SWTGraphics need to be here
	 */
	static {
		FILL_RULE_SHIFT = 14;
		ADVANCED_SHIFT = 15;
		FILL_RULE_MASK = 1 << FILL_RULE_SHIFT; //If changed to more than 1-bit, check references!
		ADVANCED_GRAPHICS_MASK = 1 << ADVANCED_SHIFT;
	}
	
	private SWTGraphics swtGraphics;
	private Graphics2D graphics2D;
	private BasicStroke stroke;
	private Stack<State> states = new Stack<State>();
	private final State currentState = new State();
	private final State appliedState = new State();
	
	/**
	 * Some strings, Asian string in particular, are painted differently between
	 * SWT and AWT. SWT falls back to some default locale font if Asian string
	 * cannot be painted with the current font - this is done via the platform.
	 * AWT, unlike platform biased SWT, does not. Hence, Asian string widths are
	 * very different between SWT and AWT. To workaround the issue, if the flag
	 * below is set to <code>true</code> then once SWT and AWT string width are
	 * not equal, a bitmap of the SWT string will be painted. Otherwise the
	 * string is always painted with AWT Graphics 2D string rendering.
	 */
	protected boolean paintNotCompatibleStringsAsBitmaps = true;
	
	private static final TextUtilitiesEx TEXT_UTILITIES = new TextUtilitiesEx(MapModeTypes.IDENTITY_MM);
	
	private Rectangle relativeClipRegion;
	
	private org.eclipse.swt.graphics.Rectangle viewBox;
	private Image image;
	
	/**
	 * x coordinate for graphics translation
	 */
	private int transX = 0;
	/**
	 * y coordinate for graphics translation
	 */
	private int transY = 0;

	/**
	 * Constructor
	 * 
	 * @param graphics the <code>Graphics2D</code> object that this object is delegating
	 * calls to.
	 * @param viewPort the <code>Rectangle</code> that defines the logical area being rendered
	 * by the graphics object.
	 */
	public GraphicsToGraphics2DAdaptor( Graphics2D graphics, Rectangle viewPort ) {
		
		this( graphics, new org.eclipse.swt.graphics.Rectangle( viewPort.x,
						viewPort.y,
						viewPort.width,
						viewPort.height) );
	}

	/**
	 * Alternate Constructor that takes an swt Rectangle
	 * 
	 * @param graphics the <code>Graphics2D</code> object that this object is delegating
	 * calls to.
	 * @param viewPort the <code>org.eclipse.swt.graphics.Rectangle</code> that defines the logical area 
	 * being rendered by the graphics object.
	 */
	public GraphicsToGraphics2DAdaptor(Graphics2D graphics, org.eclipse.swt.graphics.Rectangle viewPort) {

		// Save the ViewPort to add to the root DOM element
		viewBox = viewPort;

		// Create the SWT Graphics Object
		createSWTGraphics();

		// Initialize the SVG Graphics Object
		initSVGGraphics(graphics);

		// Initialize the States
		init();
	}

	/**
	 * This is a helper method used to create the SWT Graphics object
	 */
	private void createSWTGraphics() {
		
		//we need this temp Rect just to instantiate an swt image in order to keep
		//state, the size of this Rect is of no consequence and we just set it to
		//such a small size in order to minimize memory allocation 
		org.eclipse.swt.graphics.Rectangle tempRect = new org.eclipse.swt.graphics.Rectangle(0,
			0,
			10,
			10);
		image = new Image(DisplayUtils.getDisplay(), tempRect);		
		GC gc = new GC(image);
		swtGraphics = new SWTGraphics(gc);
	}

	/**
	 * Create the SVG graphics object and initializes it with the current line
	 * stlye and width
	 */
	private void initSVGGraphics(Graphics2D graphics) {
		this.graphics2D = graphics;

		relativeClipRegion =
			new Rectangle(viewBox.x, viewBox.y, viewBox.width, viewBox.height);

		// Initialize the line style and width
		stroke =
			new BasicStroke(
				swtGraphics.getLineWidth(),
				BasicStroke.CAP_SQUARE,
				BasicStroke.JOIN_ROUND,
				0,
				null,
				0);
		LineAttributes lineAttributes = new LineAttributes(1);
		swtGraphics.getLineAttributes(lineAttributes);
		setLineAttributes(lineAttributes);
		setFillRule(swtGraphics.getFillRule());
		setAdvanced(swtGraphics.getAdvanced());
		getGraphics2D().setStroke(stroke);
	}

	/**
	 * This method should only be called by the constructor. Initializes state
	 * information for the currentState
	 */
	private void init() {

		// Initialize drawing styles
		setForegroundColor(getForegroundColor());
		setBackgroundColor(getBackgroundColor());
		setXORMode(getXORMode());

		// Initialize Font
		setFont(getFont());
		currentState.font = appliedState.font = getFont();

		// Initialize translations
		currentState.translateX = appliedState.translateX = transX;
		currentState.translateY = appliedState.translateY = transY;

		// Initialize Clip Regions
		currentState.clipX = appliedState.clipX = relativeClipRegion.x;
		currentState.clipY = appliedState.clipY = relativeClipRegion.y;
		currentState.clipW = appliedState.clipW = relativeClipRegion.width;
		currentState.clipH = appliedState.clipH = relativeClipRegion.height;

        currentState.alpha = appliedState.alpha = getAlpha();

    }

	/**
	 * Verifies that the applied state is up to date with the current state and updates
	 * the applied state accordingly.  
	 */
	protected void checkState() {

		if( appliedState.font != currentState.font ) {
			appliedState.font = currentState.font;
			
			setFont(currentState.font);
		}

		if (appliedState.clipX != currentState.clipX
			|| appliedState.clipY != currentState.clipY
			|| appliedState.clipW != currentState.clipW
			|| appliedState.clipH != currentState.clipH) {

			appliedState.clipX = currentState.clipX;
			appliedState.clipY = currentState.clipY;
			appliedState.clipW = currentState.clipW;
			appliedState.clipH = currentState.clipH;

			// Adjust the clip for SVG
			getGraphics2D().setClip(
				currentState.clipX - 1,
				currentState.clipY - 1,
				currentState.clipW + 2,
				currentState.clipH + 2);
		}
        
        if( appliedState.alpha != currentState.alpha ) {
            appliedState.alpha = currentState.alpha;
            
            setAlpha(currentState.alpha);
        }
        
        appliedState.graphicHints = currentState.graphicHints;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#clipRect(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void clipRect(Rectangle rect) {
		relativeClipRegion.intersect(rect);
		setClipAbsolute(
			relativeClipRegion.x + transX,
			relativeClipRegion.y + transY,
			relativeClipRegion.width,
			relativeClipRegion.height);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#dispose()
	 */
	public void dispose() {
		swtGraphics.dispose();
		
		if (image != null) {
			image.dispose();
		}
		
		states.clear();
	}

	/**
	 * This method is used to convert an SWT Color to an AWT Color.
	 * 
	 * @param toConvert
	 *            SWT Color to convert
	 * @return AWT Color
	 */
	protected java.awt.Color getColor(Color toConvert) {

		return new java.awt.Color(
			toConvert.getRed(),
			toConvert.getGreen(),
			toConvert.getBlue());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawArc(int, int, int, int, int, int)
	 */
	public void drawArc(
		int x,
		int y,
		int width,
		int height,
		int startAngle,
		int endAngle) {

		Arc2D arc =
			new Arc2D.Float(
				x + transX,
				y + transY,
				width - 1,
				height,
				startAngle,
				endAngle,
				Arc2D.OPEN);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(arc);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillArc(int, int, int, int, int, int)
	 */
	public void fillArc(int x, int y, int w, int h, int offset, int length) {

		Arc2D arc =
			new Arc2D.Float(
				x + transX,
				y + transY,
				w,
				h,
				offset,
				length,
				Arc2D.OPEN);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(arc);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawFocus(int, int, int, int)
	 */
	public void drawFocus(int x, int y, int w, int h) {
		drawRectangle(x, y, w, h);
	}

	@Override
	public void drawTextLayout(TextLayout layout, int x, int y,
			int selectionStart, int selectionEnd, Color selectionForeground,
			Color selectionBackground) {		
		checkState();
		if (!layout.getBounds().isEmpty()) {
			Image image = new Image(DisplayUtils.getDisplay(), layout.getBounds().width, layout.getBounds().height);
			GC gc = new GC(image);
			cloneGC(gc);
			layout.draw(gc, 0, 0, selectionStart, selectionEnd, selectionForeground, selectionBackground);
			
			ImageData imageData = image.getImageData();
			imageData.transparentPixel = imageData.palette.getPixel(getBackgroundColor().getRGB());
	
			gc.dispose();
			image.dispose();
			
			getGraphics2D().drawImage(ImageConverter.convertFromImageData(imageData), x + transX, y + transY, null);
		}
	}
	
	private void cloneGC(GC gc) {
		gc.setAdvanced(getAdvanced());
		gc.setAlpha(getAlpha());
		gc.setAntialias(getAntialias());
		gc.setFillRule(getFillRule());
		gc.setFont(getFont());
		gc.setInterpolation(getInterpolation());
		gc.setLineAttributes(getLineAttributes());
		gc.setTextAntialias(getTextAntialias());
		gc.setBackground(getBackgroundColor());
		gc.setForeground(getForegroundColor());
	}
	
	@Override
	public int getInterpolation() {
		return swtGraphics.getInterpolation();
	}

	@Override
	public LineAttributes getLineAttributes() {
		LineAttributes la = new LineAttributes(1);
		swtGraphics.getLineAttributes(la);
		return la;
	}

	@Override
	public int getTextAntialias() {
		return swtGraphics.getTextAntialias();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image,
	 *      int, int)
	 */
	public void drawImage(Image srcImage, int xpos, int ypos) {

		// Translate the Coordinates
		xpos += transX;
		ypos += transY;

		// Convert the SWT Image into an AWT BufferedImage
		BufferedImage toDraw = ImageConverter.convert(srcImage);

		checkState();
		getGraphics2D().drawImage(
			toDraw,
			new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos),
			null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image,
	 *      int, int, int, int, int, int, int, int)
	 */
	public void drawImage(
		Image srcImage,
		int x1,
		int y1,
		int w1,
		int h1,
		int x2,
		int y2,
		int w2,
		int h2) {

		x2 += transX;
		y2 += transY;

		BufferedImage toDraw = ImageConverter.convert(srcImage);
		checkState();
		getGraphics2D().drawImage(toDraw, x2, y2, w2, h2, null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawLine(int, int, int, int)
	 */
	public void drawLine(int x1, int y1, int x2, int y2) {

		Line2D line =
			new Line2D.Float(
				x1 + transX,
				y1 + transY,
				x2 + transX,
				y2 + transY);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(line);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawOval(int, int, int, int)
	 */
	public void drawOval(int x, int y, int w, int h) {

		Ellipse2D ellipse =
			new Ellipse2D.Float(x + transX, y + transY, w, h);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(ellipse);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillOval(int, int, int, int)
	 */
	public void fillOval(int x, int y, int w, int h) {
	
		Ellipse2D ellipse =
			new Ellipse2D.Float(x + transX, y + transY, w-1, h-1);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(ellipse);
	}

	private Polygon createPolygon(PointList pointList) {

		Polygon toCreate = new Polygon();

		for (int i = 0; i < pointList.size(); i++) {
			Point pt = pointList.getPoint(i);

			toCreate.addPoint(pt.x + transX, pt.y + transY);
		}

		return toCreate;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawPolygon(org.eclipse.draw2d.geometry.PointList)
	 */
	public void drawPolygon(PointList pointList) {
		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(createPolygon(pointList));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillPolygon(org.eclipse.draw2d.geometry.PointList)
	 */
	public void fillPolygon(PointList pointList) {

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(createPolygon(pointList));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawPolyline(org.eclipse.draw2d.geometry.PointList)
	 */
	public void drawPolyline(PointList pointList) {

		// Draw polylines as a series of lines
		for (int x = 1; x < pointList.size(); x++) {

			Point p1 = pointList.getPoint(x - 1);
			Point p2 = pointList.getPoint(x);

			drawLine(p1.x, p1.y, p2.x, p2.y);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawRectangle(int, int, int, int)
	 */
	public void drawRectangle(int x, int y, int w, int h) {

		Rectangle2D rect =
			new Rectangle2D.Float(x + transX, y + transY, w, h);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(rect);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillRectangle(int, int, int, int)
	 */
	public void fillRectangle(int x, int y, int width, int height) {

		Rectangle2D rect =
			new Rectangle2D.Float(
				x + transX,
				y + transY,
				width,
				height);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(rect);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawRoundRectangle(org.eclipse.draw2d.geometry.Rectangle,
	 *      int, int)
	 */
	public void drawRoundRectangle(
		Rectangle rect,
		int arcWidth,
		int arcHeight) {

		RoundRectangle2D roundRect =
			new RoundRectangle2D.Float(
				rect.x + transX,
				rect.y + transY,
				rect.width,
				rect.height,
				arcWidth,
				arcHeight);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(roundRect);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillRoundRectangle(org.eclipse.draw2d.geometry.Rectangle,
	 *      int, int)
	 */
	public void fillRoundRectangle(
		Rectangle rect,
		int arcWidth,
		int arcHeight) {

		RoundRectangle2D roundRect =
			new RoundRectangle2D.Float(
				rect.x + transX,
				rect.y + transY,
				rect.width,
				rect.height,
				arcWidth,
				arcHeight);

		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(roundRect);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawText(java.lang.String, int, int)
	 */
	public void drawText(String s, int x, int y) {
		drawString(s, x, y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#drawString(java.lang.String, int, int)
	 */
	public void drawString(String s, int x, int y) {

		if (s == null || s.length() == 0)
			return;

		java.awt.FontMetrics metrics = getGraphics2D().getFontMetrics();
		int stringLength = metrics.stringWidth(s);
		Dimension swtStringSize = TEXT_UTILITIES.getStringExtents(s, swtGraphics.getFont());

		float xpos = x + transX;
		float ypos = y + transY;
		int lineWidth;
		
		
		String drawStringAsImageProperty = System.getProperty("drawStringAsImage");//$NON-NLS-1$		
		boolean drawStringAsImage = drawStringAsImageProperty == null ? false: drawStringAsImageProperty.equals("true"); //$NON-NLS-1$		
		if (drawStringAsImage || (paintNotCompatibleStringsAsBitmaps && (getGraphics2D().getFont().canDisplayUpTo(s) != -1)) ) {
			// create SWT bitmap of the string then
			Image image = new Image(DisplayUtils.getDisplay(),
					swtStringSize.width, swtStringSize.height);
			GC gc = new GC(image);
			gc.setForeground(getForegroundColor());
			gc.setBackground(getBackgroundColor());
			gc.setAntialias(getAntialias());
			gc.setFont(getFont());
			gc.drawString(s, 0, 0);
			gc.dispose();
			ImageData data = image.getImageData();
			image.dispose();
			RGB backgroundRGB = getBackgroundColor().getRGB();
			for (int i = 0; i < data.width; i++) {
				for (int j = 0; j < data.height; j++) {
					if (data.palette.getRGB(data.getPixel(i, j)).equals(
							backgroundRGB)) {
						data.setAlpha(i, j, 0);
					} else {
						data.setAlpha(i, j, 255);
					}
				}
			}
			checkState();
			getGraphics2D().drawImage(
					ImageConverter.convertFromImageData(data),
					new AffineTransform(1f, 0f, 0f, 1f, xpos, ypos), null);
			stringLength = swtStringSize.width;
		} else {

			ypos += metrics.getAscent();

			checkState();
			getGraphics2D()
					.setPaint(getColor(swtGraphics.getForegroundColor()));
			getGraphics2D().drawString(s, xpos, ypos);
		}

		if (isFontUnderlined(getFont())) {
			int baseline = y + metrics.getAscent();
			lineWidth = getLineWidth();

			setLineWidth(1);
			drawLine(x, baseline, x + stringLength, baseline);
			setLineWidth(lineWidth);
		}
		
		if (isFontStrikeout(getFont())) {
			int strikeline = y + (metrics.getHeight() / 2);
			lineWidth = getLineWidth();

			setLineWidth(1);
			drawLine(x, strikeline, x + stringLength, strikeline);
			setLineWidth(lineWidth);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillString(java.lang.String, int, int)
	 */
	public void fillString(String s, int x, int y) {
		// Not implemented
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#fillText(java.lang.String, int, int)
	 */
	public void fillText(String s, int x, int y) {
		// Not implemented
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getBackgroundColor()
	 */
	public Color getBackgroundColor() {
		return swtGraphics.getBackgroundColor();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getClip(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public Rectangle getClip(Rectangle rect) {
		rect.setBounds(relativeClipRegion);
		return rect;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getFont()
	 */
	public Font getFont() {
		return swtGraphics.getFont();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getFontMetrics()
	 */
	public FontMetrics getFontMetrics() {
		return swtGraphics.getFontMetrics();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getForegroundColor()
	 */
	public Color getForegroundColor() {
		return swtGraphics.getForegroundColor();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getLineStyle()
	 */
	public int getLineStyle() {
		return swtGraphics.getLineStyle();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getLineWidth()
	 */
	public int getLineWidth() {
		return swtGraphics.getLineWidth();
	}
	
	public float getLineWidthFloat() {
		return swtGraphics.getLineWidthFloat();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#getXORMode()
	 */
	public boolean getXORMode() {
		return swtGraphics.getXORMode();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#popState()
	 */
	public void popState() {
		swtGraphics.popState();

		restoreState(states.pop());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#pushState()
	 */
	public void pushState() {
		swtGraphics.pushState();

		// Make a copy of the current state and push it onto the stack
		State toPush = new State();
		toPush.copyFrom(currentState);
		states.push(toPush);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#restoreState()
	 */
	public void restoreState() {
		swtGraphics.restoreState();

		restoreState(states.peek());
	}

	private void restoreState(State state) {
		
		setBackgroundColor(state.bgColor);
		setForegroundColor(state.fgColor);
		setLineAttributes(state.lineAttributes);
		setXORMode(state.XorMode);
		
		setClipAbsolute(state.clipX, state.clipY, state.clipW, state.clipH);

		transX = currentState.translateX = state.translateX;
		transY = currentState.translateY = state.translateY;

		relativeClipRegion.x = state.clipX - transX;
		relativeClipRegion.y = state.clipY - transY;
		relativeClipRegion.width = state.clipW;
		relativeClipRegion.height = state.clipH;
		
		currentState.font = state.font;
        currentState.alpha = state.alpha;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#scale(double)
	 */
	public void scale(double amount) {
		swtGraphics.scale(amount);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setBackgroundColor(org.eclipse.swt.graphics.Color)
	 */
	public void setBackgroundColor(Color rgb) {
		currentState.bgColor = rgb;
		swtGraphics.setBackgroundColor(rgb);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setClip(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void setClip(Rectangle rect) {

		relativeClipRegion.x = rect.x;
		relativeClipRegion.y = rect.y;
		relativeClipRegion.width = rect.width;
		relativeClipRegion.height = rect.height;

		setClipAbsolute(
			rect.x + transX,
			rect.y + transY,
			rect.width,
			rect.height);
	}

	/**
	 * Sets the current clip values
	 * 
	 * @param x
	 *            the x value
	 * @param y
	 *            the y value
	 * @param width
	 *            the width value
	 * @param height
	 *            the height value
	 */
	private void setClipAbsolute(int x, int y, int width, int height) {
		currentState.clipX = x;
		currentState.clipY = y;
		currentState.clipW = width;
		currentState.clipH = height;
	}

	private boolean isFontUnderlined(Font f) {
		return false;
	}

	private boolean isFontStrikeout(Font f) {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setFont(org.eclipse.swt.graphics.Font)
	 */
	@Override
	public void setFont(Font f) {

		swtGraphics.setFont(f);
		currentState.font = f;

		FontData[] fontInfo = f.getFontData();

		if (fontInfo[0] != null) {

			int height = fontInfo[0].getHeight();
			
			int dpi = Integer.getInteger("org.eclipse.gmf.runtime.draw2d.ui.render.dpi", DisplayUtils.getDisplay().getDPI().x);
			float fsize = (float) height * (float) dpi / 72.0f;        // display DPI / AWT DPI
			height = (int) fsize;
			
			int style = fontInfo[0].getStyle();
			boolean bItalic = (style & SWT.ITALIC) == SWT.ITALIC;
			boolean bBold = (style & SWT.BOLD) == SWT.BOLD;
			String faceName = fontInfo[0].getName();
			int escapement = 0;

			boolean bUnderline = isFontUnderlined(f);
			boolean bStrikeout = isFontStrikeout(f);
			
			GdiFont font =
				new GdiFont(
					height,
					bItalic,
					bUnderline,
					bStrikeout,
					bBold,
					faceName,
					escapement);

			getGraphics2D().setFont(font.getFont());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setForegroundColor(org.eclipse.swt.graphics.Color)
	 */
	@Override
	public void setForegroundColor(Color rgb) {
		currentState.fgColor = rgb;
		swtGraphics.setForegroundColor(rgb);
	}

	/**
	 * Sets the dash pattern when the custom line style is in use. Because this
	 * feature is rarely used, the dash pattern may not be preserved when calling
	 * {@link #pushState()} and {@link #popState()}.
	 * @param dash the pixel pattern
	 * 
	 */
	@Override
	public void setLineDash(int[] dash) {
		float dashFlt[] = new float[dash.length];
		for (int i=0; i<dash.length; i++) {
			dashFlt[i] = dash[i];
		}
		setLineDash(dashFlt);
	}
	
	@Override
	public void setLineDash(float[] dash) {
		currentState.lineAttributes.dash = dash;
		setLineStyle(SWTGraphics.LINE_CUSTOM);
		swtGraphics.setLineDash(dash);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setLineStyle(int)
	 */
	@Override
	public void setLineStyle(int style) {
		currentState.lineAttributes.style = style;		
		swtGraphics.setLineStyle(style);
	}
	
	/**
	 * ignored
	 */
	@Override
	public void setLineMiterLimit(float miterLimit) {
		// do nothing
	}
	
	/**
	 * ignored
	 */
	@Override
	public void setLineCap(int cap) {
		// do nothing
	}
	
	/**
	 * ignored
	 */
	@Override
	public void setLineJoin(int join) {
		// do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setLineWidth(int)
	 */
	@Override
	public void setLineWidth(int width) {
		setLineWidthFloat(width);
	}
	
	@Override
	public void setLineWidthFloat(float width) {
		currentState.lineAttributes.width = width;
		swtGraphics.setLineWidthFloat(width);
	}
	
	@Override
	public void setLineAttributes(LineAttributes lineAttributes) {
		SWTGraphics.copyLineAttributes(currentState.lineAttributes, lineAttributes);
		swtGraphics.setLineAttributes(lineAttributes);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Graphics#setXORMode(boolean)
	 */
	@Override
	public void setXORMode(boolean xorMode) {
		currentState.XorMode = xorMode;
		swtGraphics.setXORMode(xorMode);
	}

	/**
	 * Sets the current translation values
	 * 
	 * @param x
	 *            the x translation value
	 * @param y
	 *            the y translation value
	 */
	private void setTranslation(int x, int y) {
		transX = currentState.translateX = x;
		transY = currentState.translateY = y;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#translate(int, int)
	 */
	@Override
	public void translate(int dx, int dy) {
		swtGraphics.translate(dx, dy);

		setTranslation(transX + dx, transY + dy);
		relativeClipRegion.x -= dx;
		relativeClipRegion.y -= dy;
	}

	/**
	 * @return the <code>Graphics2D</code> that this is delegating to.
	 */
	protected Graphics2D getGraphics2D() {
		return graphics2D;
	}
	
	/**
	 * @return Returns the swtGraphics.
	 */
	private SWTGraphics getSWTGraphics() {
		return swtGraphics;
	}
	
	/* 
	 * (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#fillGradient(int, int, int, int, boolean)
	 */
	@Override
	public void fillGradient(int x, int y, int w, int h, boolean vertical) {
		GradientPaint gradient;
		
		checkState();

		// Gradients in SWT start with Foreground Color and end at Background
		java.awt.Color start = getColor( getSWTGraphics().getForegroundColor() );
		java.awt.Color stop = getColor( getSWTGraphics().getBackgroundColor() );

		// Create the Gradient based on horizontal or vertical
		if( vertical ) {
			gradient = new GradientPaint(x+transX,y+transY, start, x+transX, y+h+transY, stop);
		} else {
			gradient = new GradientPaint(x+transX,y+transY, start, x+w+transX, y+transY, stop);			
		}
        
        Paint oldPaint = getGraphics2D().getPaint();
        getGraphics2D().setPaint(gradient);
        getGraphics2D().fill(new Rectangle2D.Double(x+transX, y+transY, w, h));
        getGraphics2D().setPaint(oldPaint);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#drawPath(org.eclipse.swt.graphics.Path)
	 */
	public void drawPath(Path path) {
		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getForegroundColor()));
		getGraphics2D().setStroke(createStroke());
		getGraphics2D().draw(createPathAWT(path));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#fillPath(org.eclipse.swt.graphics.Path)
	 */
	public void fillPath(Path path) {
		checkState();
		getGraphics2D().setPaint(getColor(swtGraphics.getBackgroundColor()));
		getGraphics2D().fill(createPathAWT(path));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#setClip(org.eclipse.swt.graphics.Path)
	 */
	public void setClip(Path path) {
		if (((appliedState.graphicHints ^ currentState.graphicHints) & FILL_RULE_MASK) != 0) {
			//If there is a pending change to the fill rule, apply it first.
			//As long as the FILL_RULE is stored in a single bit, just toggling it works.
			appliedState.graphicHints ^= FILL_RULE_MASK;
		}
		getGraphics2D().setClip(createPathAWT(path));
		appliedState.clipX = currentState.clipX = 0;
		appliedState.clipY = currentState.clipY = 0;
		appliedState.clipW = currentState.clipW = 0;
		appliedState.clipH = currentState.clipH = 0;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#getFillRule()
	 */
	public int getFillRule() {
		return ((currentState.graphicHints & FILL_RULE_MASK) >> FILL_RULE_SHIFT) - FILL_RULE_WHOLE_NUMBER; 
	}

	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.Graphics#setFillRule(int)
	 */
	public void setFillRule(int rule) {
		currentState.graphicHints &= ~FILL_RULE_MASK;
		currentState.graphicHints |= (rule + FILL_RULE_WHOLE_NUMBER) << FILL_RULE_SHIFT;
	}

	private GeneralPath createPathAWT(Path path) {
		GeneralPath pathAWT = new GeneralPath();
		PathData pathData = path.getPathData();
		int idx = 0;
		for (int i = 0; i < pathData.types.length; i++) {
			switch (pathData.types[i]) {
			case SWT.PATH_MOVE_TO:
				pathAWT.moveTo(pathData.points[idx++] + transX,
						pathData.points[idx++] + transY);
				break;
			case SWT.PATH_LINE_TO:
				pathAWT.lineTo(pathData.points[idx++] + transX,
						pathData.points[idx++] + transY);
				break;
			case SWT.PATH_CUBIC_TO:
				pathAWT.curveTo(pathData.points[idx++] + transX,
						pathData.points[idx++] + transY, pathData.points[idx++]
								+ transX, pathData.points[idx++] + transY,
						pathData.points[idx++] + transX, pathData.points[idx++]
								+ transY);
				break;
			case SWT.PATH_QUAD_TO:
				pathAWT.quadTo(pathData.points[idx++] + transX,
						pathData.points[idx++] + transY, pathData.points[idx++]
								+ transX, pathData.points[idx++] + transY);
				break;
			case SWT.PATH_CLOSE:
				pathAWT.closePath();
				break;
			default:
				dispose();
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
		}
		int swtWindingRule = ((appliedState.graphicHints & FILL_RULE_MASK) >> FILL_RULE_SHIFT)
				- FILL_RULE_WHOLE_NUMBER;
		if (swtWindingRule == SWT.FILL_WINDING) {
			pathAWT.setWindingRule(GeneralPath.WIND_NON_ZERO);
		} else if (swtWindingRule == SWT.FILL_EVEN_ODD) {
			pathAWT.setWindingRule(GeneralPath.WIND_EVEN_ODD);
		} else {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		return pathAWT;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.DrawableRenderedImage#drawRenderedImage(org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage, org.eclipse.draw2d.geometry.Rectangle, org.eclipse.gmf.runtime.draw2d.ui.render.RenderingListener)
	 */
	public RenderedImage drawRenderedImage(RenderedImage srcImage, Rectangle rect, RenderingListener listener) {
		RenderInfo info = srcImage.getRenderInfo();
		info.setValues(rect.width, rect.height,  
						info.shouldMaintainAspectRatio(), info.shouldAntiAlias(),
						info.getBackgroundColor(), info.getForegroundColor());
		
		RenderedImage img = srcImage.getNewRenderedImage(info);
		
		BufferedImage bufImg = (BufferedImage)img.getAdapter(BufferedImage.class);
		if (bufImg == null) {
			bufImg = ImageConverter.convert(img.getSWTImage());
		}
		
		// Translate the Coordinates
		int x = rect.x + transX;
		int y = rect.y + transY + rect.height - bufImg.getHeight();

		checkState();
		getGraphics2D().drawImage(
			bufImg,
			new AffineTransform(1f, 0f, 0f, 1f, x, y),
			null);
		
		return img;
	}

	/* 
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.DrawableRenderedImage#allowDelayRender()
	 */
	public boolean shouldAllowDelayRender() {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.DrawableRenderedImage#getMaximumRenderSize()
	 */
	public Dimension getMaximumRenderSize() {
		return null;
	}

	/**
	 * Accessor method to return the translation offset for the graphics object
	 * 
	 * @return <code>Point</code> x coordinate for graphics translation
	 */
	protected Point getTranslationOffset() {
		return new Point(transX, transY);
	}
    
    /* 
     * (non-Javadoc)
     * @see org.eclipse.draw2d.Graphics#getAntialias()
     */
	@Override
    public int getAntialias() {
        Object antiAlias = getGraphics2D().getRenderingHint(RenderingHints.KEY_ANTIALIASING);
        if (antiAlias != null) {
            if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_ON))
                return SWT.ON;
            else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_OFF))
                return SWT.OFF;
            else if (antiAlias.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT))
                return SWT.DEFAULT;
        }
        
        return SWT.DEFAULT;
    }
    
    /* 
     * (non-Javadoc)
     * @see org.eclipse.draw2d.Graphics#setAntialias(int)
     */
	@Override
    public void setAntialias(int value) {
        if (value == SWT.ON) {
            getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        }
        else if (value == SWT.OFF) {
            getGraphics2D().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        }
        setAdvanced(true);
    }

	@Override
    public int getAlpha() {
        return swtGraphics.getAlpha();
    }

	@Override
    public void setAlpha(int alpha) {
        swtGraphics.setAlpha(alpha);
        currentState.alpha = alpha;
        
        Composite composite = getGraphics2D().getComposite();
        if (composite instanceof AlphaComposite) {
            AlphaComposite newComposite = AlphaComposite.getInstance(
                ((AlphaComposite) composite).getRule(), (float) alpha / (float) 255);
            getGraphics2D().setComposite(newComposite);
        }
    }
    
    protected BasicStroke getStroke(){
    	return stroke;
    }
    
    protected void setStroke(BasicStroke stroke){
    	this.stroke = stroke;
    	getGraphics2D().setStroke(stroke);
    }
    
    /**
	 * Sets and retirns AWT Stroke based on the value of
	 * <code>LineAttributes</code> within the current state object
	 * 
	 * @return the new AWT stroke
	 */
    private Stroke createStroke() {    	
    	float factor = currentState.lineAttributes.width > 0 ? currentState.lineAttributes.width : 3;
    	float awt_dash[];
    	int awt_cap;
    	int awt_join;
    	
		switch (currentState.lineAttributes.style) {
			case SWTGraphics.LINE_DASH :
				awt_dash = new float[]{ factor * 6, factor * 3 };
				break;
			case SWTGraphics.LINE_DASHDOT :
				awt_dash = new float[] { factor * 3, factor, factor, factor };
				break;
			case SWTGraphics.LINE_DASHDOTDOT :
				awt_dash = new float[] { factor * 3, factor, factor, factor, factor, factor };
				break;
			case SWTGraphics.LINE_DOT :
				awt_dash = new float[] { factor, factor };
				break;
			case SWTGraphics.LINE_CUSTOM :
				awt_dash = currentState.lineAttributes.dash;
				break;
			default :
				awt_dash = null;
		}
		
		switch (currentState.lineAttributes.cap) {
			case SWT.CAP_FLAT:
				awt_cap = BasicStroke.CAP_BUTT;
				break;
			case SWT.CAP_ROUND:
				awt_cap = BasicStroke.CAP_ROUND;
				break;
			case SWT.CAP_SQUARE:
				awt_cap = BasicStroke.CAP_SQUARE;
				break;
			default:
				awt_cap = BasicStroke.CAP_BUTT;				
		}
		
		switch (currentState.lineAttributes.join) {
			case SWT.JOIN_BEVEL:
				awt_join = BasicStroke.JOIN_BEVEL;
				break;
			case SWT.JOIN_MITER:
				awt_join = BasicStroke.JOIN_MITER;
				break;
			case SWT.JOIN_ROUND:
				awt_join = BasicStroke.JOIN_ROUND;
				break;
			default:
				awt_join = BasicStroke.JOIN_MITER;
		}
		
		/*
		 * SWT paints line width == 0 as if it is == 1, so AWT is synced up with that below.
		 */
		stroke =
			new BasicStroke(
				currentState.lineAttributes.width != 0 ? currentState.lineAttributes.width : 1,
				awt_cap,
				awt_join,
				currentState.lineAttributes.miterLimit,
				awt_dash,
				currentState.lineAttributes.dashOffset);
		return stroke;
    }

    public boolean getAdvanced() {
    	return (currentState.graphicHints & ADVANCED_GRAPHICS_MASK) != 0;
    }

    public void setAdvanced(boolean value) {
    	if(value) {
    		currentState.graphicHints |= ADVANCED_GRAPHICS_MASK;
    	} else {
    		currentState.graphicHints &= ~ADVANCED_GRAPHICS_MASK;
    	}
    }

	@Override
	public void clipPath(Path path) {
		if (((appliedState.graphicHints ^ currentState.graphicHints) & FILL_RULE_MASK) != 0) {
			//If there is a pending change to the fill rule, apply it first.
			//As long as the FILL_RULE is stored in a single bit, just toggling it works.
			appliedState.graphicHints ^= FILL_RULE_MASK;
		}
		setClip(path);
		getGraphics2D().clipRect(relativeClipRegion.x + transX, relativeClipRegion.y + transY, relativeClipRegion.width, relativeClipRegion.height);
		java.awt.Rectangle bounds = getGraphics2D().getClip().getBounds();
		relativeClipRegion = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
	}

}
