/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.gef.draw2d.graphics; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.LineAttributes; import org.eclipse.swt.graphics.Path; import org.eclipse.swt.graphics.PathData; import org.eclipse.swt.graphics.Pattern; import org.eclipse.swt.graphics.TextLayout; /** * Rotate the coordinate 90 degrees clockwise. * * @author frankshaka */ public class Rotate90Graphics extends Graphics { private Graphics graphics; private Pattern lastBgPattern = null; private Pattern lastFgPattern = null; public Rotate90Graphics(Graphics realGraphics) { this.graphics = realGraphics; } protected Graphics getGraphics() { return graphics; } protected float[] rotate(float x, float y) { return new float[] { -y, x }; } protected int[] rotate(int x, int y) { return new int[] { -y, x }; } protected Rectangle rotate(Rectangle r) { return new Rectangle(-r.y - r.height, r.x, r.height, r.width); } protected Point rotate(Point p) { return new Point(-p.y, p.x); } protected Path rotate(Path path) { PathData data = path.getPathData(); Path newPath = new Path(path.getDevice()); int index = 0; float[] points = data.points; float x, y, cx1, cy1, cx2, cy2; for (byte type : data.types) { switch (type) { case SWT.PATH_MOVE_TO: x = points[index++]; y = points[index++]; newPath.moveTo(-y, x); break; case SWT.PATH_LINE_TO: x = points[index++]; y = points[index++]; newPath.lineTo(-y, x); break; case SWT.PATH_CUBIC_TO: x = points[index++]; y = points[index++]; cx1 = points[index++]; cy1 = points[index++]; cx2 = points[index++]; cy2 = points[index++]; newPath.cubicTo(-y, x, -cy1, cx1, -cy2, cx2); break; case SWT.PATH_QUAD_TO: x = points[index++]; y = points[index++]; cx1 = points[index++]; cy1 = points[index++]; newPath.quadTo(-y, x, -cy1, cx1); break; case SWT.PATH_CLOSE: newPath.close(); break; } } return newPath; } protected int[] rotate(int[] points) { int[] newPoints = new int[points.length]; for (int i = 0; i < points.length; i += 2) { newPoints[i] = -points[i + 1]; newPoints[i + 1] = points[i]; } return newPoints; } protected PointList rotate(PointList points) { int size = points.size(); PointList newPoints = new PointList(size); for (int i = 0; i < size; i++) { Point p = points.getPoint(i); newPoints.setPoint(rotate(p), i); } return newPoints; } private Pattern rotate(GradientPattern p) { GradientPattern p2 = new GradientPattern(p.getDevice(), // -p.y1, p.x1, // -p.y2, p.x2, // p.color1, p.alpha1, // p.color2, p.alpha2); return p2; } private Pattern rotate(ImagePattern p) { ImagePattern p2 = new ImagePattern(p.getDevice(), rotate(p.image)); return p2; } private Image rotate(Image image) { return image; } public void clipRect(Rectangle r) { graphics.clipRect(rotate(r)); } public void clipPath(Path path) { Path p2 = rotate((Path) path); graphics.clipPath(p2); p2.dispose(); } public void dispose() { if (lastBgPattern != null) { lastBgPattern.dispose(); lastBgPattern = null; } if (lastFgPattern != null) { lastFgPattern.dispose(); lastFgPattern = null; } } public void drawArc(int x, int y, int w, int h, int offset, int length) { graphics.drawArc(-y - h, x, h, w, offset, length); } public void drawFocus(int x, int y, int w, int h) { graphics.drawFocus(-y - h, x, h, w); } public void drawImage(Image srcImage, int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawImage(srcImage, x1, y1, w1, h1, x2, y2, w2, h2); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void drawImage(Image srcImage, int x, int y) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawImage(srcImage, x, y); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void drawLine(int x1, int y1, int x2, int y2) { graphics.drawLine(-y1, x1, -y2, x2); } public void drawOval(int x, int y, int w, int h) { graphics.drawOval(-y - h, x, h, w); } public void drawPath(Path path) { Path p2 = rotate((Path) path); graphics.drawPath(p2); p2.dispose(); } public void drawPoint(int x, int y) { graphics.drawPoint(-y, x); } public void drawPolygon(int[] points) { graphics.drawPolygon(rotate(points)); } public void drawPolygon(PointList points) { graphics.drawPolygon(rotate(points)); } public void drawPolyline(int[] points) { graphics.drawPolyline(rotate(points)); } public void drawPolyline(PointList points) { graphics.drawPolyline(rotate(points)); } public void drawRectangle(int x, int y, int width, int height) { graphics.drawRectangle(-y - height, x, height, width); } public void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { graphics.drawRoundRectangle(rotate(r), arcHeight, arcWidth); } public void drawString(String s, int x, int y) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawString(s, x, y); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void drawText(String s, int x, int y, int style) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawText(s, x, y, style); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void drawText(String s, int x, int y) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawText(s, x, y); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void drawTextLayout(TextLayout layout, int x, int y, int selectionStart, int selectionEnd, Color selectionForeground, Color selectionBackground) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.drawTextLayout(layout, x, y, selectionStart, selectionEnd, selectionForeground, selectionBackground); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void fillArc(int x, int y, int w, int h, int offset, int length) { graphics.fillArc(-y - h, x, h, w, offset, length); } public void fillGradient(int x, int y, int w, int h, boolean vertical) { graphics.fillGradient(-y - h, x, h, w, !vertical); } public void fillOval(int x, int y, int w, int h) { graphics.fillOval(-y - h, x, h, w); } public void fillPath(Path path) { Path p2 = rotate((Path) path); graphics.fillPath(p2); p2.dispose(); } public void fillPolygon(int[] points) { graphics.fillPolygon(rotate(points)); } public void fillPolygon(PointList points) { graphics.fillPolygon(rotate(points)); } public void fillRectangle(int x, int y, int width, int height) { graphics.fillRectangle(-y - height, x, height, width); } public void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight) { graphics.fillRoundRectangle(rotate(r), arcHeight, arcWidth); } public void fillString(String s, int x, int y) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.fillString(s, x, y); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public void fillText(String s, int x, int y) { boolean statePushed = false; try { graphics.pushState(); statePushed = true; } catch (Throwable t) { statePushed = false; } graphics.rotate(90); graphics.fillText(s, x, y); graphics.rotate(-90); if (statePushed) { try { graphics.restoreState(); graphics.popState(); } catch (Throwable t) { } } } public double getAbsoluteScale() { return graphics.getAbsoluteScale(); } public int getAlpha() { return graphics.getAlpha(); } public int getAntialias() { return graphics.getAntialias(); } public Color getBackgroundColor() { return graphics.getBackgroundColor(); } public Rectangle getClip(Rectangle rect) { rect = graphics.getClip(rect); int rx = rect.y; int ry = -rect.x - rect.width; int rw = rect.height; int rh = rect.width; rect.x = rx; rect.y = ry; rect.width = rw; rect.height = rh; return rect; } public int getFillRule() { return graphics.getFillRule(); } public Font getFont() { return graphics.getFont(); } public FontMetrics getFontMetrics() { return graphics.getFontMetrics(); } public Color getForegroundColor() { return graphics.getForegroundColor(); } public int getInterpolation() { return graphics.getInterpolation(); } public int getLineCap() { return graphics.getLineCap(); } public int getLineJoin() { return graphics.getLineJoin(); } public int getLineStyle() { return graphics.getLineStyle(); } public int getLineWidth() { return graphics.getLineWidth(); } public int getTextAntialias() { return graphics.getTextAntialias(); } public boolean getXORMode() { return graphics.getXORMode(); } public void popState() { graphics.popState(); } public void pushState() { graphics.pushState(); } public void restoreState() { graphics.restoreState(); } public void rotate(float degrees) { graphics.rotate(degrees); } public void scale(double amount) { graphics.scale(amount); } public void scale(float horizontal, float vertical) { graphics.scale(horizontal, vertical); } public void setAlpha(int alpha) { graphics.setAlpha(alpha); } public void setAntialias(int value) { graphics.setAntialias(value); } public void setBackgroundColor(Color rgb) { graphics.setBackgroundColor(rgb); } public void setBackgroundPattern(Pattern pattern) { if (lastBgPattern != null) { lastBgPattern.dispose(); lastBgPattern = null; } if (pattern instanceof GradientPattern) { Pattern p = rotate((GradientPattern) pattern); graphics.setBackgroundPattern(p); lastBgPattern = p; } else if (pattern instanceof ImagePattern) { Pattern p = rotate((ImagePattern) pattern); graphics.setBackgroundPattern(p); lastBgPattern = p; } else { graphics.setBackgroundPattern(pattern); } } public void setClip(Path path) { Path p2 = rotate((Path) path); graphics.setClip(p2); p2.dispose(); } public void setClip(Rectangle r) { graphics.setClip(rotate(r)); } public void setFillRule(int rule) { graphics.setFillRule(rule); } public void setFont(Font f) { graphics.setFont(f); } public void setForegroundColor(Color rgb) { graphics.setForegroundColor(rgb); } public void setForegroundPattern(Pattern pattern) { if (lastFgPattern != null) { lastFgPattern.dispose(); lastFgPattern = null; } if (pattern instanceof GradientPattern) { Pattern p = rotate((GradientPattern) pattern); graphics.setForegroundPattern(p); lastFgPattern = p; } else if (pattern instanceof ImagePattern) { Pattern p = rotate((ImagePattern) pattern); graphics.setForegroundPattern(p); lastFgPattern = p; } else { graphics.setForegroundPattern(pattern); } } public void setInterpolation(int interpolation) { graphics.setInterpolation(interpolation); } public void setLineCap(int cap) { graphics.setLineCap(cap); } public void setLineDash(int[] dash) { graphics.setLineDash(dash); } public void setLineJoin(int join) { graphics.setLineJoin(join); } public void setLineStyle(int style) { graphics.setLineStyle(style); } public void setLineWidth(int width) { graphics.setLineWidth(width); } public void setTextAntialias(int value) { graphics.setTextAntialias(value); } public void setXORMode(boolean b) { graphics.setXORMode(b); } public void shear(float horz, float vert) { graphics.shear(horz, vert); } public void translate(float dx, float dy) { graphics.translate(-dy, dx); } public void translate(int dx, int dy) { graphics.translate(-dy, dx); } // ========================================================== // Since 3.5 // ========================================================== public boolean getAdvanced() { return graphics.getAdvanced(); } public float getLineWidthFloat() { return graphics.getLineWidthFloat(); } public LineAttributes getLineAttributes() { return graphics.getLineAttributes(); } public float getLineMiterLimit() { return graphics.getLineMiterLimit(); } public void setAdvanced(boolean advanced) { graphics.setAdvanced(advanced); } public void setLineMiterLimit(float miterLimit) { graphics.setLineMiterLimit(miterLimit); } public void setLineWidthFloat(float width) { graphics.setLineWidthFloat(width); } public void setLineAttributes(LineAttributes attributes) { graphics.setLineAttributes(attributes); } public void setLineDash(float[] value) { graphics.setLineDash(value); } }