/******************************************************************************* * Copyright (c) 2012, 2015 itemis AG 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: * Alexander Nyßen (itemis AG) - initial API and implementation * *******************************************************************************/ package org.eclipse.gef.geometry.convert.swt; import org.eclipse.gef.geometry.convert.awt.Geometry2AWT; import org.eclipse.gef.geometry.internal.utils.PointListUtils; import org.eclipse.gef.geometry.planar.Line; import org.eclipse.gef.geometry.planar.Path; import org.eclipse.gef.geometry.planar.Point; import org.eclipse.gef.geometry.planar.Polygon; import org.eclipse.gef.geometry.planar.Polyline; import org.eclipse.gef.geometry.planar.Rectangle; import org.eclipse.gef.geometry.planar.Region; import org.eclipse.gef.geometry.planar.Ring; import org.eclipse.swt.graphics.PathData; /** * Utility class to support conversions between GEF's geometry API and SWT's * geometry classes. * * @author anyssen * */ public class Geometry2SWT { /** * Converts the given path into an SWT {@link PathData} representation. * * @param p * the {@link Path} to convert * * @return The {@link PathData} representing this path. */ public static final PathData toSWTPathData(Path p) { return AWT2SWT.toSWTPathData(Geometry2AWT.toAWTPath(p).getPathIterator(null)); } /** * Creates a new SWT {@link org.eclipse.swt.graphics.Point Point} from this * Point. * * @param p * the {@link Point} to convert * * @return A new SWT Point */ public static final org.eclipse.swt.graphics.Point toSWTPoint(Point p) { return new org.eclipse.swt.graphics.Point((int) p.x, (int) p.y); } /** * Returns an integer array of dimension 4, whose values represent the * integer-based coordinates of this {@link Line}'s start and end point. * * @param l * the {@link Line} to convert * * @return an array containing integer values, which are obtained by casting * x1, y1, x2, y2 */ public static final int[] toSWTPointArray(Line l) { return PointListUtils.toIntegerArray(PointListUtils.toCoordinatesArray(l.getPoints())); } /** * <p> * Returns an integer array, which represents the sequence of coordinates of * the {@link Point}s that make up this * {@link AbstractPointListBasedGeometry}. The x and y coordinate values are * transfered to integer values by either applying * {@link Math#floor(double)} or {@link Math#ceil(double)} to them, * dependent on their relative position to the centroid of this * {@link AbstractPointListBasedGeometry} (see {@link #getCentroid()}). * </p> * <p> * If the x coordinate of a {@link Point} is smaller than the x coordinate * of the centroid, then the x coordinate of that {@link Point} is rounded * down. Otherwise it is rounded up. Accordingly, if the y coordinate of a * {@link Point} is smaller than the y coordinate of the centroid, it is * rounded down. Otherwise, it is rounded up. * </p> * * @return an integer array of the x and y coordinates of this * {@link AbstractPointListBasedGeometry} */ private static final int[] toSWTPointArray(Point[] points, Point centroid) { int[] SWTPointArray = new int[points.length * 2]; for (int i = 0; i < points.length; i++) { SWTPointArray[2 * i] = (int) (points[i].x < centroid.x ? Math.floor(points[i].x) : Math.ceil(points[i].x)); SWTPointArray[2 * i + 1] = (int) (points[i].y < centroid.y ? Math.floor(points[i].y) : Math.ceil(points[i].y)); } return SWTPointArray; } /** * <p> * Returns an integer array, which represents the sequence of coordinates of * the {@link Point}s that make up this {@link Polygon}. The x and y * coordinate values are transfered to integer values by either applying * {@link Math#floor(double)} or {@link Math#ceil(double)} to them, * dependent on their relative position to the centroid of this * {@link Polygon} (see {@link Polygon#getCentroid()}). * </p> * <p> * If the x coordinate of a {@link Point} is smaller than the x coordinate * of the centroid, then the x coordinate of that {@link Point} is rounded * down. Otherwise it is rounded up. Accordingly, if the y coordinate of a * {@link Point} is smaller than the y coordinate of the centroid, it is * rounded down. Otherwise, it is rounded up. * </p> * * @param p * the {@link Polygon} to convert * * @return an integer array of the x and y coordinates of this * {@link Polygon} */ public static final int[] toSWTPointArray(Polygon p) { return toSWTPointArray(p.getPoints(), p.getCentroid()); } /** * <p> * Returns an integer array, which represents the sequence of coordinates of * the {@link Point}s that make up this {@link Polyline}. The x and y * coordinate values are transfered to integer values by either applying * {@link Math#floor(double)} or {@link Math#ceil(double)} to them, * dependent on their relative position to the centroid of this * {@link Polyline} (see {@link Polyline#getCentroid()}). * </p> * <p> * If the x coordinate of a {@link Point} is smaller than the x coordinate * of the centroid, then the x coordinate of that {@link Point} is rounded * down. Otherwise it is rounded up. Accordingly, if the y coordinate of a * {@link Point} is smaller than the y coordinate of the centroid, it is * rounded down. Otherwise, it is rounded up. * </p> * * @param p * the {@link Polyline} to convert * * @return an integer array of the x and y coordinates of this * {@link Polyline} */ public static final int[] toSWTPointArray(Polyline p) { return toSWTPointArray(p.getPoints(), p.getCentroid()); } /** * Converts a {@link Rectangle} into an * {@link org.eclipse.swt.graphics.Rectangle}. Note that as * {@link org.eclipse.swt.graphics.Rectangle} is integer-based, this implies * a loss of precision. The returned rectangle is the smallest * integer-precision representation that fully contains this * {@link Rectangle}. * * @param r * the {@link Rectangle} to convert * * @return An {@link org.eclipse.swt.graphics.Rectangle} representation of * this {@link Rectangle}. */ public static final org.eclipse.swt.graphics.Rectangle toSWTRectangle(Rectangle r) { return new org.eclipse.swt.graphics.Rectangle((int) Math.floor(r.getX()), (int) Math.floor(r.getY()), (int) Math.ceil(r.getWidth() + r.getX() - Math.floor(r.getX())), (int) Math.ceil(r.getHeight() + r.getY() - Math.floor(r.getY()))); } /** * <p> * Constructs a new {@link org.eclipse.swt.graphics.Region} that covers the * same area as this {@link Region}. This is to ease the use of a * {@link Region} for clipping: * </p> * * <p> * <code>gc.setClipping(region.toSWTRegion());</code> * </p> * * @param r * the {@link Region} to convert * * @return a new {@link org.eclipse.swt.graphics.Region} that covers the * same area as this {@link Region} */ public static final org.eclipse.swt.graphics.Region toSWTRegion(Region r) { org.eclipse.swt.graphics.Region swtRegion = new org.eclipse.swt.graphics.Region(); for (Rectangle rect : r.getShapes()) { swtRegion.add(toSWTRectangle(rect)); } return swtRegion; } /** * Constructs a new {@link org.eclipse.swt.graphics.Region} from this * {@link Ring}. The SWT {@link Region} can be used as a clipping area as * follows: <code>gc.setClipping(ring.toSWTRegion());</code> * * @param r * the {@link Region} to convert * * @return SWT {@link Region} representation of this {@link Ring} */ public static org.eclipse.swt.graphics.Region toSWTRegion(Ring r) { org.eclipse.swt.graphics.Region region = new org.eclipse.swt.graphics.Region(); // TODO: Add the individual outlines in xor mode to the SWT Region so // that voids are correctly converted, too. for (Polyline p : r.getOutlines()) { region.add(toSWTPointArray(p)); } return region; } private Geometry2SWT() { // this class should not be instantiated by clients } }