/*******************************************************************************
 * Copyright (c) 2000, 2010 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.draw2d;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;
import org.eclipse.draw2d.rap.swt.graphics.LineAttributes;
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.Image;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.PathData;
import org.eclipse.swt.graphics.Pattern;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Display;

/**
 * A Graphics object able to scale all operations based on the current scale
 * factor.
 */
public class ScaledGraphics extends Graphics {

	private static class FontHeightCache {
		Font font;
		int height;
	}

	static class FontKey {
		Font font;
		int height;

		protected FontKey() {
		}

		protected FontKey(Font font, int height) {
			this.font = font;
			this.height = height;
		}

		public boolean equals(Object obj) {
			return (((FontKey) obj).font.equals(font) && ((FontKey) obj).height == height);
		}

		public int hashCode() {
			return font.hashCode() ^ height;
		}

		protected void setValues(Font font, int height) {
			this.font = font;
			this.height = height;
		}
	}

	/**
	 * The internal state of the scaled graphics.
	 */
	protected static class State {
		private double appliedX;
		private double appliedY;
		private Font font;
		private float lineWidth;
		private double zoom;

		/**
		 * Constructs a new, uninitialized State object.
		 */
		protected State() {
		}

		/**
		 * Constructs a new State object and initializes the properties based on
		 * the given values.
		 * 
		 * @param zoom
		 *            the zoom factor
		 * @param x
		 *            the x offset
		 * @param y
		 *            the y offset
		 * @param font
		 *            the font
		 * @param lineWidth
		 *            the line width
		 */
		protected State(double zoom, double x, double y, Font font,
				int lineWidth) {
			this(zoom, x, y, font, (float) lineWidth);
		}

		/**
		 * Constructs a new State object and initializes the properties based on
		 * the given values.
		 * 
		 * @param zoom
		 *            the zoom factor
		 * @param x
		 *            the x offset
		 * @param y
		 *            the y offset
		 * @param font
		 *            the font
		 * @param lineWidth
		 *            the line width
		 * 
		 * @since 3.5
		 */
		protected State(double zoom, double x, double y, Font font,
				float lineWidth) {
			this.zoom = zoom;
			this.appliedX = x;
			this.appliedY = y;
			this.font = font;
			this.lineWidth = lineWidth;
		}

		/**
		 * Sets all the properties of the state object.
		 * 
		 * @param zoom
		 *            the zoom factor
		 * @param x
		 *            the x offset
		 * @param y
		 *            the y offset
		 * @param font
		 *            the font
		 * @param lineWidth
		 *            the line width
		 */
		protected void setValues(double zoom, double x, double y, Font font,
				int lineWidth) {
			setValues(zoom, x, y, font, (float) lineWidth);
		}

		/**
		 * Sets all the properties of the state object.
		 * 
		 * @param zoom
		 *            the zoom factor
		 * @param x
		 *            the x offset
		 * @param y
		 *            the y offset
		 * @param font
		 *            the font
		 * @param lineWidth
		 *            the line width
		 * 
		 * @since 3.5
		 */
		protected void setValues(double zoom, double x, double y, Font font,
				float lineWidth) {
			this.zoom = zoom;
			this.appliedX = x;
			this.appliedY = y;
			this.font = font;
			this.lineWidth = lineWidth;
		}
	}

	private static int[][] intArrayCache = new int[8][];
	private final Rectangle tempRECT = new Rectangle();

	static {
		for (int i = 0; i < intArrayCache.length; i++) {
			intArrayCache[i] = new int[i + 1];
		}
	}

	private boolean allowText = true;
	// private static final Point PT = new Point();
	private Map fontCache = new HashMap();
	private Map fontDataCache = new HashMap();
	private FontKey fontKey = new FontKey();
	private double fractionalX;
	private double fractionalY;
	private Graphics graphics;
	private FontHeightCache localCache = new FontHeightCache();
	private Font localFont;
	private float localLineWidth;
	private List stack = new ArrayList();
	private int stackPointer = 0;
	private FontHeightCache targetCache = new FontHeightCache();

	double zoom = 1.0;

	/**
	 * Constructs a new ScaledGraphics based on the given Graphics object.
	 * 
	 * @param g
	 *            the base graphics object
	 */
	public ScaledGraphics(Graphics g) {
		graphics = g;
		localFont = g.getFont();
		localLineWidth = g.getLineWidthFloat();
	}

	/** @see Graphics#clipRect(Rectangle) */
	public void clipRect(Rectangle r) {
		graphics.clipRect(zoomClipRect(r));
	}

	Font createFont(FontData data) {
		return new Font(Display.getCurrent(), data);
	}

	/**
	 * Scales given path by zoom factor
	 * 
	 * @param path
	 *            Path to be scaled
	 * @return Scaled path
	 */
	private Path createScaledPath(Path path) {
		PathData p = path.getPathData();
		for (int i = 0; i < p.points.length; i += 2) {
			p.points[i] = (float) (p.points[i] * zoom + fractionalX);
			p.points[i + 1] = (float) (p.points[i + 1] * zoom + fractionalY);
		}
		Path scaledPath = new Path(path.getDevice());
		int index = 0;
		for (int i = 0; i < p.types.length; i++) {
			byte type = p.types[i];
			switch (type) {
			case SWT.PATH_MOVE_TO:
				scaledPath.moveTo(p.points[index], p.points[index + 1]);
				index += 2;
				break;
			case SWT.PATH_LINE_TO:
				scaledPath.lineTo(p.points[index], p.points[index + 1]);
				index += 2;
				break;
			case SWT.PATH_CUBIC_TO:
				scaledPath.cubicTo(p.points[index], p.points[index + 1],
						p.points[index + 2], p.points[index + 3],
						p.points[index + 4], p.points[index + 5]);
				index += 6;
				break;
			case SWT.PATH_QUAD_TO:
				scaledPath.quadTo(p.points[index], p.points[index + 1],
						p.points[index + 2], p.points[index + 3]);
				index += 4;
				break;
			case SWT.PATH_CLOSE:
				scaledPath.close();
				break;
			}
		}
		return scaledPath;
	}

	/** @see Graphics#dispose() */
	public void dispose() {
		// Remove all states from the stack
		while (stackPointer > 0) {
			popState();
		}

		// UNSUPPORTED - RAP does not allow the disposing of factory created fonts
		// Dispose fonts
		// Iterator iter = fontCache.values().iterator();
		// while (iter.hasNext()) {
		// Font font = ((Font) iter.next());
		// font.dispose();
		// }

	}

	/** @see Graphics#drawArc(int, int, int, int, int, int) */
	public void drawArc(int x, int y, int w, int h, int offset, int sweep) {
		Rectangle z = zoomRect(x, y, w, h);
		if (z.isEmpty() || sweep == 0)
			return;
		graphics.drawArc(z, offset, sweep);
	}

	/** @see Graphics#drawFocus(int, int, int, int) */
	public void drawFocus(int x, int y, int w, int h) {
		graphics.drawFocus(zoomRect(x, y, w, h));
	}

	/** @see Graphics#drawImage(Image, int, int) */
	public void drawImage(Image srcImage, int x, int y) {
		org.eclipse.swt.graphics.Rectangle size = srcImage.getBounds();
		graphics.drawImage(srcImage, 0, 0, size.width, size.height,
				(int) (Math.floor((x * zoom + fractionalX))),
				(int) (Math.floor((y * zoom + fractionalY))),
				(int) (Math.floor((size.width * zoom + fractionalX))),
				(int) (Math.floor((size.height * zoom + fractionalY))));
	}

	/** @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int) */
	public void drawImage(Image srcImage, int sx, int sy, int sw, int sh,
			int tx, int ty, int tw, int th) {
		// "t" == target rectangle, "s" = source

		Rectangle t = zoomRect(tx, ty, tw, th);
		if (!t.isEmpty())
			graphics.drawImage(srcImage, sx, sy, sw, sh, t.x, t.y, t.width,
					t.height);
	}

	/** @see Graphics#drawLine(int, int, int, int) */
	public void drawLine(int x1, int y1, int x2, int y2) {
		graphics.drawLine((int) (Math.floor((x1 * zoom + fractionalX))),
				(int) (Math.floor((y1 * zoom + fractionalY))),
				(int) (Math.floor((x2 * zoom + fractionalX))),
				(int) (Math.floor((y2 * zoom + fractionalY))));
	}

	/** @see Graphics#drawOval(int, int, int, int) */
	public void drawOval(int x, int y, int w, int h) {
		graphics.drawOval(zoomRect(x, y, w, h));
	}

	/** @see Graphics#drawPath(Path) */
	public void drawPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.drawPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}

	/** @see Graphics#drawPoint(int, int) */
	public void drawPoint(int x, int y) {
		graphics.drawPoint((int) Math.floor(x * zoom + fractionalX),
				(int) Math.floor(y * zoom + fractionalY));
	}

	/**
	 * @see Graphics#drawPolygon(int[])
	 */
	public void drawPolygon(int[] points) {
		graphics.drawPolygon(zoomPointList(points));
	}

	/** @see Graphics#drawPolygon(PointList) */
	public void drawPolygon(PointList points) {
		graphics.drawPolygon(zoomPointList(points.toIntArray()));
	}

	/**
	 * @see Graphics#drawPolyline(int[])
	 */
	public void drawPolyline(int[] points) {
		graphics.drawPolyline(zoomPointList(points));
	}

	/** @see Graphics#drawPolyline(PointList) */
	public void drawPolyline(PointList points) {
		graphics.drawPolyline(zoomPointList(points.toIntArray()));
	}

	/** @see Graphics#drawRectangle(int, int, int, int) */
	public void drawRectangle(int x, int y, int w, int h) {
		graphics.drawRectangle(zoomRect(x, y, w, h));
	}

	/** @see Graphics#drawRoundRectangle(Rectangle, int, int) */
	public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) {
		graphics.drawRoundRectangle(zoomRect(r.x, r.y, r.width, r.height),
				(int) (arcWidth * zoom), (int) (arcHeight * zoom));
	}

	/** @see Graphics#drawString(String, int, int) */
	public void drawString(String s, int x, int y) {
		if (allowText)
			graphics.drawString(s, zoomTextPoint(x, y));
	}

	/** @see Graphics#drawText(String, int, int) */
	public void drawText(String s, int x, int y) {
		if (allowText)
			graphics.drawText(s, zoomTextPoint(x, y));
	}

	/**
	 * @see Graphics#drawText(String, int, int, int)
	 */
	public void drawText(String s, int x, int y, int style) {
		if (allowText)
			graphics.drawText(s, zoomTextPoint(x, y), style);
	}

	/**
	 * @see Graphics#drawTextLayout(TextLayout, int, int, int, int, Color,
	 *      Color)
	 */
	public void drawTextLayout(TextLayout layout, int x, int y,
			int selectionStart, int selectionEnd, Color selectionForeground,
			Color selectionBackground) {
		TextLayout scaled = zoomTextLayout(layout);
		if (scaled == null) {
			return;
		}
		try {
			graphics.drawTextLayout(scaled,
					(int) Math.floor(x * zoom + fractionalX),
					(int) Math.floor(y * zoom + fractionalY), selectionStart,
					selectionEnd, selectionBackground, selectionForeground);
		} finally {
			scaled.dispose();
		}
	}

	/** @see Graphics#fillArc(int, int, int, int, int, int) */
	public void fillArc(int x, int y, int w, int h, int offset, int sweep) {
		Rectangle z = zoomFillRect(x, y, w, h);
		if (z.isEmpty() || sweep == 0)
			return;
		graphics.fillArc(z, offset, sweep);
	}

	/** @see Graphics#fillGradient(int, int, int, int, boolean) */
	public void fillGradient(int x, int y, int w, int h, boolean vertical) {
		graphics.fillGradient(zoomFillRect(x, y, w, h), vertical);
	}

	/** @see Graphics#fillOval(int, int, int, int) */
	public void fillOval(int x, int y, int w, int h) {
		graphics.fillOval(zoomFillRect(x, y, w, h));
	}

	/** @see Graphics#fillPath(Path) */
	public void fillPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.fillPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}

	/**
	 * @see Graphics#fillPolygon(int[])
	 */
	public void fillPolygon(int[] points) {
		graphics.fillPolygon(zoomPointList(points));
	}

	/** @see Graphics#fillPolygon(PointList) */
	public void fillPolygon(PointList points) {
		graphics.fillPolygon(zoomPointList(points.toIntArray()));
	}

	/** @see Graphics#fillRectangle(int, int, int, int) */
	public void fillRectangle(int x, int y, int w, int h) {
		graphics.fillRectangle(zoomFillRect(x, y, w, h));
	}

	/** @see Graphics#fillRoundRectangle(Rectangle, int, int) */
	public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) {
		graphics.fillRoundRectangle(zoomFillRect(r.x, r.y, r.width, r.height),
				(int) (arcWidth * zoom), (int) (arcHeight * zoom));
	}

	/** @see Graphics#fillString(String, int, int) */
	public void fillString(String s, int x, int y) {
		if (allowText)
			graphics.fillString(s, zoomTextPoint(x, y));
	}

	/** @see Graphics#fillText(String, int, int) */
	public void fillText(String s, int x, int y) {
		if (allowText)
			graphics.fillText(s, zoomTextPoint(x, y));
	}

	/**
	 * @see Graphics#getAbsoluteScale()
	 */
	public double getAbsoluteScale() {
		return zoom * graphics.getAbsoluteScale();
	}

	/**
	 * @see Graphics#getAlpha()
	 */
	public int getAlpha() {
		return graphics.getAlpha();
	}

	/**
	 * @see Graphics#getAntialias()
	 */
	public int getAntialias() {
		return graphics.getAntialias();
	}

	/** @see Graphics#getBackgroundColor() */
	public Color getBackgroundColor() {
		return graphics.getBackgroundColor();
	}

	Font getCachedFont(FontKey key) {
		Font font = (Font) fontCache.get(key);
		if (font != null) {
			return font;
		}
		key = new FontKey(key.font, key.height);
		FontData data = key.font.getFontData()[0];
		data.setHeight(key.height);
		Font zoomedFont = createFont(data);
		fontCache.put(key, zoomedFont);
		return zoomedFont;
	}

	FontData getCachedFontData(Font f) {
		FontData data = (FontData) fontDataCache.get(f);
		if (data == null) {
			data = getLocalFont().getFontData()[0];
			fontDataCache.put(f, data);
		}
		return data;
	}

	/** @see Graphics#getClip(Rectangle) */
	public Rectangle getClip(Rectangle rect) {
		graphics.getClip(rect);
		int x = (int) (rect.x / zoom);
		int y = (int) (rect.y / zoom);
		/*
		 * If the clip rectangle is queried, perform an inverse zoom, and take
		 * the ceiling of the resulting double. This is necessary because
		 * forward scaling essentially performs a floor() function. Without
		 * this, figures will think that they don't need to paint when actually
		 * they do.
		 */
		rect.width = (int) Math.ceil(rect.right() / zoom) - x;
		rect.height = (int) Math.ceil(rect.bottom() / zoom) - y;
		rect.x = x;
		rect.y = y;
		return rect;
	}

	/**
	 * @see Graphics#getAdvanced()
	 */
	public boolean getAdvanced() {
		return graphics.getAdvanced();
	}

	/**
	 * @see Graphics#getFillRule()
	 */
	public int getFillRule() {
		return graphics.getFillRule();
	}

	/** @see Graphics#getFont() */
	public Font getFont() {
		return getLocalFont();
	}

	/** @see Graphics#getFontMetrics() */
	public FontMetrics getFontMetrics() {
		return FigureUtilities.getFontMetrics(localFont);
	}

	/** @see Graphics#getForegroundColor() */
	public Color getForegroundColor() {
		return graphics.getForegroundColor();
	}

	/**
	 * @see Graphics#getInterpolation()
	 */
	public int getInterpolation() {
		return graphics.getInterpolation();
	}

	/**
	 * @see Graphics#getLineCap()
	 */
	public int getLineCap() {
		return graphics.getLineCap();
	}

	/**
	 * @see Graphics#getLineJoin()
	 */
	public int getLineJoin() {
		return graphics.getLineJoin();
	}

	/** @see Graphics#getLineStyle() */
	public int getLineStyle() {
		return graphics.getLineStyle();
	}

	/** @see Graphics#getLineMiterLimit() */
	public float getLineMiterLimit() {
		return graphics.getLineMiterLimit();
	}

	/** @see Graphics#getLineWidth() */
	public int getLineWidth() {
		return (int) getLineWidthFloat();
	}

	/** @see Graphics#getLineWidthFloat() */
	public float getLineWidthFloat() {
		return getLocalLineWidth();
	}

	/** @see Graphics#getLineAttributes() */
	public LineAttributes getLineAttributes() {
		LineAttributes a = graphics.getLineAttributes();
		a.width = getLocalLineWidth();
		return a;
	}

	private Font getLocalFont() {
		return localFont;
	}

	private float getLocalLineWidth() {
		return localLineWidth;
	}

	/**
	 * @see Graphics#getTextAntialias()
	 */
	public int getTextAntialias() {
		return graphics.getTextAntialias();
	}

	/** @see Graphics#getXORMode() */
	public boolean getXORMode() {
		return graphics.getXORMode();
	}

	/** @see Graphics#popState() */
	public void popState() {
		graphics.popState();
		stackPointer--;
		restoreLocalState((State) stack.get(stackPointer));
	}

	/** @see Graphics#pushState() */
	public void pushState() {
		State s;
		if (stack.size() > stackPointer) {
			s = (State) stack.get(stackPointer);
			s.setValues(zoom, fractionalX, fractionalY, getLocalFont(),
					localLineWidth);
		} else {
			stack.add(new State(zoom, fractionalX, fractionalY, getLocalFont(),
					localLineWidth));
		}
		stackPointer++;

		graphics.pushState();
	}

	private void restoreLocalState(State state) {
		this.fractionalX = state.appliedX;
		this.fractionalY = state.appliedY;
		setScale(state.zoom);
		setLocalFont(state.font);
		setLocalLineWidth(state.lineWidth);
	}

	/** @see Graphics#restoreState() */
	public void restoreState() {
		graphics.restoreState();
		restoreLocalState((State) stack.get(stackPointer - 1));
	}

	/** @see Graphics#rotate(float) */
	public void rotate(float degrees) {
		graphics.rotate(degrees);
	}

	/** @see Graphics#scale(double) */
	public void scale(double amount) {
		setScale(zoom * amount);
	}

	/** @see Graphics#setAdvanced(boolean) */
	public void setAdvanced(boolean advanced) {
		graphics.setAdvanced(advanced);
	}

	/**
	 * @see Graphics#setAlpha(int)
	 */
	public void setAlpha(int alpha) {
		graphics.setAlpha(alpha);
	}

	/**
	 * @see Graphics#setAntialias(int)
	 */
	public void setAntialias(int value) {
		graphics.setAntialias(value);
	}

	/** @see Graphics#setBackgroundColor(Color) */
	public void setBackgroundColor(Color rgb) {
		graphics.setBackgroundColor(rgb);
	}

	/** @see Graphics#setClip(Path) */
	public void setClip(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.setClip(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}

	/** @see Graphics#setBackgroundPattern(Pattern) */
	public void setBackgroundPattern(Pattern pattern) {
		graphics.setBackgroundPattern(pattern);
	}

	/** @see Graphics#setClip(Rectangle) */
	public void setClip(Rectangle r) {
		graphics.setClip(zoomClipRect(r));
	}

	/**
	 * @see org.eclipse.draw2d.Graphics#clipPath(org.eclipse.swt.graphics.Path)
	 */
	public void clipPath(Path path) {
		Path scaledPath = createScaledPath(path);
		try {
			graphics.clipPath(scaledPath);
		} finally {
			scaledPath.dispose();
		}
	}

	/**
	 * @see Graphics#setFillRule(int)
	 */
	public void setFillRule(int rule) {
		graphics.setFillRule(rule);
	}

	/** @see Graphics#setFont(Font) */
	public void setFont(Font f) {
		setLocalFont(f);
	}

	/** @see Graphics#setForegroundColor(Color) */
	public void setForegroundColor(Color rgb) {
		graphics.setForegroundColor(rgb);
	}

	/** @see Graphics#setForegroundPattern(Pattern) */
	public void setForegroundPattern(Pattern pattern) {
		graphics.setForegroundPattern(pattern);
	}

	/** @see org.eclipse.draw2d.Graphics#setInterpolation(int) */
	public void setInterpolation(int interpolation) {
		graphics.setInterpolation(interpolation);
	}

	/**
	 * @see Graphics#setLineCap(int)
	 */
	public void setLineCap(int cap) {
		graphics.setLineCap(cap);
	}

	/**
	 * @see Graphics#setLineDash(int[])
	 */
	public void setLineDash(int[] dash) {
		graphics.setLineDash(dash);
	}

	/**
	 * @see org.eclipse.draw2d.Graphics#setLineDash(float[])
	 */
	public void setLineDash(float[] dash) {
		graphics.setLineDash(dash);
	}

	/**
	 * @see Graphics#setLineJoin(int)
	 */
	public void setLineJoin(int join) {
		graphics.setLineJoin(join);
	}

	/** @see Graphics#setLineStyle(int) */
	public void setLineStyle(int style) {
		graphics.setLineStyle(style);
	}

	/** @see Graphics#setLineMiterLimit(float) */
	public void setLineMiterLimit(float value) {
		graphics.setLineMiterLimit(value);
	}

	/** @see Graphics#setLineWidth(int) */
	public void setLineWidth(int width) {
		setLineWidthFloat(width);
	}

	/** @see Graphics#setLineWidthFloat(float) */
	public void setLineWidthFloat(float width) {
		setLocalLineWidth(width);
	}

	/** @see Graphics#setLineAttributes(LineAttributes) */
	public void setLineAttributes(LineAttributes attributes) {
		graphics.setLineAttributes(attributes);
		setLocalLineWidth(attributes.width);
	}

	private void setLocalFont(Font f) {
		localFont = f;
		graphics.setFont(zoomFont(f));
	}

	private void setLocalLineWidth(float width) {
		localLineWidth = width;
		graphics.setLineWidthFloat(zoomLineWidth(width));
	}

	void setScale(double value) {
		if (zoom != value) {
			this.zoom = value;
			graphics.setFont(zoomFont(getLocalFont()));
			graphics.setLineWidthFloat(zoomLineWidth(localLineWidth));
		}
	}

	/**
	 * @see Graphics#setTextAntialias(int)
	 */
	public void setTextAntialias(int value) {
		graphics.setTextAntialias(value);
	}

	/** @see Graphics#setXORMode(boolean) */
	public void setXORMode(boolean b) {
		graphics.setXORMode(b);
	}

	/** @see Graphics#translate(int, int) */
	public void translate(int dx, int dy) {
		// fractionalX/Y is the fractional part left over from previous
		// translates that gets lost in the integer approximation.
		double dxFloat = dx * zoom + fractionalX;
		double dyFloat = dy * zoom + fractionalY;
		fractionalX = dxFloat - Math.floor(dxFloat);
		fractionalY = dyFloat - Math.floor(dyFloat);
		graphics.translate((int) Math.floor(dxFloat), (int) Math.floor(dyFloat));
	}

	/** @see Graphics#translate(float, float) */
	public void translate(float dx, float dy) {
		double dxFloat = dx * zoom + fractionalX;
		double dyFloat = dy * zoom + fractionalY;
		fractionalX = dxFloat - Math.floor(dxFloat);
		fractionalY = dyFloat - Math.floor(dyFloat);
		graphics.translate((int) Math.floor(dxFloat), (int) Math.floor(dyFloat));
	}

	private Rectangle zoomClipRect(Rectangle r) {
		tempRECT.x = (int) (Math.floor(r.x * zoom + fractionalX));
		tempRECT.y = (int) (Math.floor(r.y * zoom + fractionalY));
		tempRECT.width = (int) (Math
				.ceil(((r.x + r.width) * zoom + fractionalX))) - tempRECT.x;
		tempRECT.height = (int) (Math
				.ceil(((r.y + r.height) * zoom + fractionalY))) - tempRECT.y;
		return tempRECT;
	}

	private Rectangle zoomFillRect(int x, int y, int w, int h) {
		tempRECT.x = (int) (Math.floor((x * zoom + fractionalX)));
		tempRECT.y = (int) (Math.floor((y * zoom + fractionalY)));
		tempRECT.width = (int) (Math.floor(((x + w - 1) * zoom + fractionalX)))
				- tempRECT.x + 1;
		tempRECT.height = (int) (Math.floor(((y + h - 1) * zoom + fractionalY)))
				- tempRECT.y + 1;
		return tempRECT;
	}

	Font zoomFont(Font f) {
		if (f == null) {
			f = Display.getCurrent().getSystemFont();
		}
		FontData data = getCachedFontData(f);
		int zoomedFontHeight = zoomFontHeight(data.getHeight());
		allowText = zoomedFontHeight > 0;
		fontKey.setValues(f, zoomedFontHeight);
		return getCachedFont(fontKey);
	}

	int zoomFontHeight(int height) {
		return (int) (zoom * height);
	}

	float zoomLineWidth(float w) {
		return (float) (w * zoom);
	}

	private int[] zoomPointList(int[] points) {
		int[] scaled = null;

		// Look in cache for a integer array with the same length as 'points'
		for (int i = 0; i < intArrayCache.length; i++) {
			if (intArrayCache[i].length == points.length) {
				scaled = intArrayCache[i];

				// Move this integer array up one notch in the array
				if (i != 0) {
					int[] temp = intArrayCache[i - 1];
					intArrayCache[i - 1] = scaled;
					intArrayCache[i] = temp;
				}
			}
		}

		// If no match is found, take the one that is last and resize it.
		if (scaled == null) {
			intArrayCache[intArrayCache.length - 1] = new int[points.length];
			scaled = intArrayCache[intArrayCache.length - 1];
		}

		// Scale the points
		for (int i = 0; (i + 1) < points.length; i += 2) {
			scaled[i] = (int) (Math.floor((points[i] * zoom + fractionalX)));
			scaled[i + 1] = (int) (Math
					.floor((points[i + 1] * zoom + fractionalY)));
		}
		return scaled;
	}

	private Rectangle zoomRect(int x, int y, int w, int h) {
		tempRECT.x = (int) (Math.floor(x * zoom + fractionalX));
		tempRECT.y = (int) (Math.floor(y * zoom + fractionalY));
		tempRECT.width = (int) (Math.floor(((x + w) * zoom + fractionalX)))
				- tempRECT.x;
		tempRECT.height = (int) (Math.floor(((y + h) * zoom + fractionalY)))
				- tempRECT.y;
		return tempRECT;
	}

	private TextLayout zoomTextLayout(TextLayout layout) {
		TextLayout zoomed = new TextLayout(Display.getCurrent());
		zoomed.setText(layout.getText());

		int zoomWidth = -1;

		if (layout.getWidth() != -1)
			zoomWidth = ((int) (layout.getWidth() * zoom));

		if (zoomWidth < -1 || zoomWidth == 0)
			return null;

		zoomed.setFont(zoomFont(layout.getFont()));
		zoomed.setAlignment(layout.getAlignment());
		zoomed.setAscent(layout.getAscent());
		zoomed.setDescent(layout.getDescent());
		zoomed.setOrientation(layout.getOrientation());
		zoomed.setSegments(layout.getSegments());
		zoomed.setSpacing(layout.getSpacing());
		zoomed.setTabs(layout.getTabs());

		zoomed.setWidth(zoomWidth);
		int length = layout.getText().length();
		if (length > 0) {
			int start = 0, offset = 1;
			TextStyle style = null, lastStyle = layout.getStyle(0);
			for (; offset <= length; offset++) {
				if (offset != length
						&& (style = layout.getStyle(offset)) == lastStyle)
					continue;
				int end = offset - 1;

				if (lastStyle != null) {
					TextStyle zoomedStyle = new TextStyle(
							zoomFont(lastStyle.font), lastStyle.foreground,
							lastStyle.background);
					// UNSUPPORTED - api is not implemented in RAP
					// zoomedStyle.metrics = lastStyle.metrics;
					zoomedStyle.rise = lastStyle.rise;
					zoomedStyle.strikeout = lastStyle.strikeout;
					zoomedStyle.underline = lastStyle.underline;
					zoomed.setStyle(zoomedStyle, start, end);
				}
				lastStyle = style;
				start = offset;
			}
		}
		return zoomed;
	}

	private Point zoomTextPoint(int x, int y) {
		// UNSUPPORTED - api is not implemented in RAP
		// if (localCache.font != localFont) {
		// // Font is different, re-calculate its height
		// FontMetrics metric = FigureUtilities.getFontMetrics(localFont);
		// localCache.height = metric.getHeight() - metric.getDescent();
		// localCache.font = localFont;
		// }
		// if (targetCache.font != graphics.getFont()) {
		// FontMetrics metric = graphics.getFontMetrics();
		// targetCache.font = graphics.getFont();
		// targetCache.height = metric.getHeight() - metric.getDescent();
		// }
		return new Point(((int) (Math.floor((x * zoom) + fractionalX))),
				(int) (Math.floor((y + localCache.height - 1) * zoom
						- targetCache.height + 1 + fractionalY)));
	}
}