/******************************************************************************* * Copyright (c) 2008 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: * Stephane Lizeray slizeray@ilog.fr - initial API and implementation *******************************************************************************/ package org.eclipse.draw2d.examples.path; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.Polyline; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.PrecisionPoint; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Path; import org.eclipse.swt.widgets.Display; public class PathFigure extends Polyline { { setFill(true); } private boolean isClosed; private float degrees; private float cx, cy; protected void outlineShape(Graphics g) { drawShape(g, false); } protected void fillShape(Graphics g) { drawShape(g, true); } private void drawShape(Graphics g, boolean fill) { Path path = createPath(); g.pushState(); g.setAntialias(SWT.ON); if (fill) g.fillPath(path); else { g.drawPath(path); } g.popState(); path.dispose(); } public void setClosed(boolean isClosed) { this.isClosed = isClosed; } public boolean isClosed() { return isClosed; } public void setRotation(float cx, float cy, float degrees) { this.degrees = degrees; this.cx = cx; this.cy = cy; bounds = null; repaint(); } public float getRotationAngle() { return degrees; } public Point getRotationCenter() { return new PrecisionPoint(cx, cy); } private Path createPath() { PointList points = getPoints(); Path path = new Path(Display.getCurrent()); double angle = degreesToRadians(degrees); double cos = (double) Math.cos(angle), sin = (double) Math.sin(angle); PrecisionPoint p1 = getRotatedPoint(points.getFirstPoint().x(), points .getFirstPoint().y(), cos, sin); path.moveTo((float) p1.preciseX(), (float) p1.preciseY()); for (int i = 1; i < points.size(); i++) { PrecisionPoint p = getRotatedPoint(points.getPoint(i).x(), points .getPoint(i).y(), cos, sin); path.lineTo((float) p.preciseX(), (float) p.preciseY()); } if (isClosed()) path.close(); return path; } public PrecisionPoint getRotatedPoint(float x, float y, double cos, double sin) { PrecisionPoint p = new PrecisionPoint(x, y); if (degrees == 0) return p; p.setPreciseX(p.preciseX() - cx); p.setPreciseY(p.preciseY() - cy); float x1 = (float) (p.preciseX() * cos - p.preciseY() * sin); float y1 = (float) (p.preciseY() * cos + p.preciseX() * sin); p.setPreciseX(x1 + cx); p.setPreciseY(y1 + cy); return p; } public Rectangle getBounds() { if (bounds == null) { bounds = new Rectangle(); if (getPoints().size() > 0) { PointList points = getPoints(); double angle = degreesToRadians(degrees); double cos = (double) Math.cos(angle), sin = (double) Math .sin(angle); PrecisionPoint p1 = getRotatedPoint(points.getFirstPoint().x(), points.getFirstPoint().y(), cos, sin); bounds.setLocation(p1); for (int i = 1; i < points.size(); i++) { PrecisionPoint p = getRotatedPoint(points.getPoint(i).x(), points.getPoint(i).y(), cos, sin); bounds.union(p); } } } return bounds.getExpanded(lineWidth / 2, lineWidth / 2); } static private double degreesToRadians(double angle) { return angle * Math.PI / 180; } }