blob: 72ff48a2034e7bfc887d78f53e7f8561b326e6cb [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2013, 2013 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.fmc.blockdiagram.editor.algorithm.node;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.MultiText;
import org.eclipse.graphiti.mm.algorithms.Polygon;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Shape;
/**
* This abstract class collects all methods common to U-shaped polygons.
*
* 07 43 xx xx x6xx5x 1xxxx2
*
*
* @author Benjamin Schmeling
* @author Heiko Witteborg
*
*/
public abstract class AbstractUPolygonAlgorithm extends
AbstractLPolygonAlgorithm implements UPolygonAlgorithm {
// ----------------------------------------
// ----------- (U)Polygon Impl ------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#getInitialPoints
* (int, int, int, int)
*/
public List<Point> getInitialPoints(int x, int y, int width, int height) {
int outerCornerSize = hasRoundedCorners() ? L_PART_DEFAULT_SIZE / 2 : 0;
int innerCornerSize = hasRoundedCorners() ? outerCornerSize * 2 / 3 : 0;
List<Point> points = new ArrayList<Point>();
/* 0 */points.add(ga
.createPoint(x, y, outerCornerSize, outerCornerSize));
/* 1 */points.add(ga.createPoint(x, y + height, outerCornerSize,
outerCornerSize));
/* 2 */points.add(ga.createPoint(x + width, y + height,
outerCornerSize, outerCornerSize));
/* 3 */points.add(ga.createPoint(x + width, y, outerCornerSize,
outerCornerSize));
/* 4 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y,
outerCornerSize, outerCornerSize));
/* 5 */points.add(ga.createPoint(x + width - L_PART_DEFAULT_SIZE, y
+ height - L_PART_DEFAULT_SIZE, innerCornerSize,
innerCornerSize));
/* 6 */points.add(ga.createPoint(x + L_PART_DEFAULT_SIZE, y + height
- L_PART_DEFAULT_SIZE, innerCornerSize, innerCornerSize));
/* 7 */points.add(ga.createPoint(x + L_PART_DEFAULT_SIZE, y,
outerCornerSize, outerCornerSize));
return points;
}
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.polygon.UPolygonAlgorithm#resizeLeftPart(
* org.eclipse.graphiti.mm.algorithms.Polygon, int)
*/
public void resizeLeftPart(Polygon polygon, int size) {
int oldSize = getLeftPartSize(polygon);
int sizeDif = size - oldSize;
EList<Point> points = polygon.getPoints();
if (sizeDif != 0) {
switch (getAngle(polygon)) {
case 90:
points.get(6).setY(points.get(6).getY() + sizeDif);
points.get(7).setY(points.get(7).getY() + sizeDif);
break;
case 180:
points.get(6).setX(points.get(6).getX() - sizeDif);
points.get(7).setX(points.get(7).getX() - sizeDif);
break;
case 270:
points.get(6).setY(points.get(6).getY() - sizeDif);
points.get(7).setY(points.get(7).getY() - sizeDif);
break;
default:
points.get(6).setX(points.get(6).getX() + sizeDif);
points.get(7).setX(points.get(7).getX() + sizeDif);
}
}
// adapt corner roundings if polygon has rounded corners
if (hasRoundedCorners()) {
int leftTopCornerSize = getLeftPartTopCornerSize(polygon);
int leftBottomCornerSize = getLeftPartBottomCornerSize(polygon);
points.get(0).setBefore(leftTopCornerSize);
points.get(0).setAfter(leftTopCornerSize);
points.get(1).setBefore(leftBottomCornerSize);
points.get(6).setAfter(leftBottomCornerSize);
points.get(7).setBefore(leftTopCornerSize);
points.get(7).setAfter(leftTopCornerSize);
}
relocateText(polygon);
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon
.getGraphicsAlgorithmChildren();
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) {
// Resize left part of polygon children
if (graphicsAlgorithmChildren.get(i) instanceof Polygon)
this.resizeLeftPart((Polygon) graphicsAlgorithmChildren.get(i),
size);
// Update relative anchors when the ga modification is done
if (i == graphicsAlgorithmChildren.size() - 1)
createBoxAnchorSet(this.getContainerShape(polygon));
}
}
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.polygon.UPolygonAlgorithm#getLeftPartSize
* (org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getLeftPartSize(Polygon polygon) {
EList<Point> points = polygon.getPoints();
if (isFlattened(polygon))
return Math.abs(points.get(7).getY() - points.get(0).getY());
else
return Math.abs(points.get(7).getX() - points.get(0).getX());
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.graphicsalgorithms.LPolygonAlgorithm#
* resizeBottomPart(org.eclipse.graphiti.mm.algorithms.Polygon, int)
*/
public void resizeBottomPart(Polygon polygon, int size) {
int oldSize = getBottomPartSize(polygon);
int sizeDif = isFlipped(polygon) ? oldSize - size : size - oldSize;
EList<Point> points = polygon.getPoints();
if (sizeDif != 0) {
switch (getAngle(polygon)) {
case 90:
points.get(6).setX(points.get(6).getX() + sizeDif);
points.get(5).setX(points.get(5).getX() + sizeDif);
break;
case 180:
points.get(6).setY(points.get(6).getY() + sizeDif);
points.get(5).setY(points.get(5).getY() + sizeDif);
break;
case 270:
points.get(6).setX(points.get(6).getX() - sizeDif);
points.get(5).setX(points.get(5).getX() - sizeDif);
break;
default:
points.get(6).setY(points.get(6).getY() - sizeDif);
points.get(5).setY(points.get(5).getY() - sizeDif);
}
}
// adapt corner roundings if polygon has rounded corners
if (hasRoundedCorners()) {
int bottomLeftCornerSize = getBottomPartLeftCornerSize(polygon);
int bottomRightCornerSize = getBottomPartRightCornerSize(polygon);
points.get(1).setAfter(bottomLeftCornerSize);
points.get(2).setBefore(bottomRightCornerSize);
points.get(5).setAfter(bottomRightCornerSize);
points.get(6).setBefore(bottomLeftCornerSize);
}
relocateText(polygon);
EList<GraphicsAlgorithm> graphicsAlgorithmChildren = polygon
.getGraphicsAlgorithmChildren();
for (int i = 0; i < graphicsAlgorithmChildren.size(); i++) {
// Resize bottom part of polygon children
if (graphicsAlgorithmChildren.get(i) instanceof Polygon)
this.resizeBottomPart(
(Polygon) graphicsAlgorithmChildren.get(i), size);
// Update relative anchors when the ga modification is done
if (i == graphicsAlgorithmChildren.size() - 1)
createBoxAnchorSet(this.getContainerShape(polygon));
}
}
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.UPolygonAlgorithm#getLeftPartTopCornerSize
* (org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getLeftPartTopCornerSize(Polygon polygon) {
return getLeftPartSize(polygon) / 2;
}
@Override
/*
* (non-Javadoc)
*
* @see org.eclipse.fmc.blockdiagram.editor.node.UPolygonAlgorithm#
* getLeftPartBottomCornerSize(org.eclipse.graphiti.mm.algorithms.Polygon)
*/
public int getLeftPartBottomCornerSize(Polygon polygon) {
return getLeftPartTopCornerSize(polygon);
}
// ----------------------------------------
// ----------- Resizable Node -------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#resize(org
* .eclipse.graphiti.mm.algorithms.GraphicsAlgorithm, int, int, int, int)
*/
public void resize(GraphicsAlgorithm algorithm, int x, int y, int width,
int height) {
Polygon polygon = (Polygon) algorithm;
int angle = getAngle(polygon);
int[] resizeX = new int[4];
int[] resizeY = new int[4];
if (isFlipped(polygon)) {
switch (angle) {
case 90:
resizeX[0] = 1;
resizeX[1] = 2;
resizeX[2] = 5;
resizeX[3] = 6;
resizeY[0] = 2;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 5;
break;
case 180:
resizeX[0] = 0;
resizeX[1] = 1;
resizeX[2] = 6;
resizeX[3] = 7;
resizeY[0] = 1;
resizeY[1] = 2;
resizeY[2] = 5;
resizeY[3] = 6;
break;
case 270:
resizeX[0] = 0;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 7;
resizeY[0] = 0;
resizeY[1] = 1;
resizeY[2] = 6;
resizeY[3] = 7;
break;
default:
resizeX[0] = 2;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 5;
resizeY[0] = 0;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 7;
}
} else {
switch (angle) {
case 90:
resizeX[0] = 0;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 7;
resizeY[0] = 2;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 5;
break;
case 180:
resizeX[0] = 0;
resizeX[1] = 1;
resizeX[2] = 6;
resizeX[3] = 7;
resizeY[0] = 0;
resizeY[1] = 3;
resizeY[2] = 4;
resizeY[3] = 7;
break;
case 270:
resizeX[0] = 1;
resizeX[1] = 2;
resizeX[2] = 5;
resizeX[3] = 6;
resizeY[0] = 0;
resizeY[1] = 1;
resizeY[2] = 6;
resizeY[3] = 7;
break;
default:
resizeX[0] = 2;
resizeX[1] = 3;
resizeX[2] = 4;
resizeX[3] = 5;
resizeY[0] = 1;
resizeY[1] = 2;
resizeY[2] = 5;
resizeY[3] = 6;
}
}
int oldHeight = polygon.getHeight();
int oldWidth = polygon.getWidth();
int heightDif = height - oldHeight;
int widthDif = width - oldWidth;
EList<Point> points = polygon.getPoints();
for (int i = 0; i < resizeX.length; i++) {
points.get(resizeX[i]).setX(
points.get(resizeX[i]).getX() + widthDif);
}
for (int i = 0; i < resizeY.length; i++) {
points.get(resizeY[i]).setY(
points.get(resizeY[i]).getY() + heightDif);
}
// adapt corner roundings if polygon has rounded corners
if (hasRoundedCorners()) {
int leftTopCornerSize = getLeftPartTopCornerSize(polygon);
int leftBottomCornerSize = getLeftPartBottomCornerSize(polygon);
int rightTopCornerSize = getRightPartTopCornerSize(polygon);
int rightBottomCornerSize = getRightPartBottomCornerSize(polygon);
int bottomLeftCornerSize = getBottomPartLeftCornerSize(polygon);
int bottomRightCornerSize = getBottomPartRightCornerSize(polygon);
points.get(0).setBefore(leftTopCornerSize);
points.get(0).setAfter(leftTopCornerSize);
points.get(1).setBefore(leftBottomCornerSize);
points.get(1).setAfter(bottomLeftCornerSize);
points.get(2).setBefore(bottomRightCornerSize);
points.get(2).setAfter(rightBottomCornerSize);
points.get(3).setBefore(rightTopCornerSize);
points.get(3).setAfter(rightTopCornerSize);
points.get(4).setBefore(rightTopCornerSize);
points.get(4).setAfter(rightTopCornerSize);
points.get(5).setBefore(rightBottomCornerSize);
points.get(5).setAfter(bottomRightCornerSize);
points.get(6).setBefore(bottomLeftCornerSize);
points.get(6).setAfter(leftBottomCornerSize);
points.get(7).setBefore(leftTopCornerSize);
points.get(7).setAfter(leftTopCornerSize);
}
ga.setLocationAndSize(polygon, x, y, width, height);
relocateText(polygon);
// adapt first level container (relative anchors + invisible shape)
ContainerShape container = this.getContainerShape(polygon);
createBoxAnchorSet(container);
synchronizeFirstLevelShape(container);
}
// ----------------------------------------
// ----------- Named Node -----------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.NamedNode#relocateText(org.eclipse.graphiti
* .mm.algorithms.GraphicsAlgorithm)
*/
public void relocateText(GraphicsAlgorithm graphicsAlgorithm) {
Polygon polygon = (Polygon) graphicsAlgorithm;
MultiText text = this.getText(graphicsAlgorithm);
if (text != null) {
int multipleOffset = 0;
if (this.isMultipleInstances(this
.getContainerShape(graphicsAlgorithm))) {
multipleOffset = MULTI_INSTANCE_GAP;
}
int angle = getAngle(graphicsAlgorithm);
int textContainingPartSize;
boolean isOnTop = false;
switch (angle) {
case 90:
textContainingPartSize = getRightPartSize(polygon);
break;
case 270:
textContainingPartSize = getLeftPartSize(polygon);
break;
default:
textContainingPartSize = getBottomPartSize(polygon);
}
if ((isFlipped(graphicsAlgorithm) && angle == 0)
|| (!isFlipped(graphicsAlgorithm) && angle == 180)) {
isOnTop = true;
}
int x = super.textMargin;
int width = graphicsAlgorithm.getWidth() - 2 * super.textMargin
- multipleOffset;
int y = (isOnTop ? super.textMargin : graphicsAlgorithm.getHeight()
- textContainingPartSize + super.textMargin)
+ multipleOffset;
int height = textContainingPartSize - 2 * super.textMargin
- multipleOffset;
ga.setLocationAndSize(text, x, y, width, height);
}
}
// ----------------------------------------
// ----------- Anchored Node --------------
@Override
/*
* (non-Javadoc)
*
* @see
* org.eclipse.fmc.blockdiagram.editor.node.AbstractLPolygonAlgorithm#addBoxAnchorSet
* (org.eclipse.graphiti.mm.pictograms.ContainerShape)
*/
protected void addBoxAnchorSet(Shape shape) {
GraphicsAlgorithm firstLevelPolygon = shape.getGraphicsAlgorithm();
Polygon secondLevelPolygon = (Polygon) firstLevelPolygon
.getGraphicsAlgorithmChildren().get(0);
// Sides of the polygon:
// 7 3
// --- ---
// | | | |
// | | 6 4 | |
// 0 | | 5 | | 2
// | ------- |
// | |
// ---------------
// 1
int numSides = 8;
int lineWidth = getDefaultLineWidth();
Point[] point = new Point[numSides];
for (int i = 0; i < point.length; i++) {
point[i] = secondLevelPolygon.getPoints().get(i);
}
// Offset in case of a multi instance shape (adapt anchors when drawing
// background part)
double offsetMultiInstance = 0.0d;
if (firstLevelPolygon.getWidth() != secondLevelPolygon.getWidth()) {
// Remove anchors created when drawing the main part
FMCUtil.removeObsoleteAnchors(shape);
offsetMultiInstance = MULTI_INSTANCE_GAP;
}
// Length of the sides (not taking into account rounded corners)
int[] length = new int[numSides];
length[0] = Math.abs(isFlattened(secondLevelPolygon) ? point[2].getX()
- point[3].getX() : point[2].getY() - point[3].getY());
length[1] = Math.abs(isFlattened(secondLevelPolygon) ? point[1].getY()
- point[2].getY() : point[1].getX() - point[2].getX());
length[2] = length[0];
length[3] = getRightPartSize(secondLevelPolygon) + lineWidth;
length[4] = length[2] - getBottomPartSize(secondLevelPolygon);
length[6] = length[4];
length[7] = getLeftPartSize(secondLevelPolygon) + lineWidth;
length[5] = length[1] - length[7] - length[3];
// Length of the sides that should contain anchors
int[] anchoredLength = new int[numSides];
for (int i = 0; i < numSides; i++)
anchoredLength[i] = Math.max(length[i] - point[i].getAfter()
- point[(i + 1) % numSides].getBefore(),
DEFAULT_ANCHOR_DIAMETER);
// Number of anchors of the sides
int[] numAnchors = new int[numSides];
// Gaps between the anchor starting points of the sides (in x and y
// direction)
double[][] gaps = new double[numSides][2];
for (int i = 0; i < gaps.length; i++)
for (int j = 0; j < gaps[i].length; j++)
gaps[i][j] = 0.0d;
// Offsets of the starting points of the sides (in x and y direction)
double[][] offset = new double[numSides][2];
switch (getAngle(secondLevelPolygon)) {
case 90:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = offsetMultiInstance;
offset[1][1] = 0.0d;
offset[1][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][0] = 0.0d;
offset[3][1] = length[7] + length[5] + offsetMultiInstance;
offset[3][0] = 0.0d;
offset[4][1] = length[7] + length[5];
offset[4][0] = offsetMultiInstance;
offset[5][1] = length[7] + offsetMultiInstance;
offset[5][0] = length[4] - lineWidth;
offset[6][1] = length[7] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[6][0] = 0.0d;
offset[7][1] = offsetMultiInstance;
offset[7][0] = 0.0d;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[4].getAfter())
anchoredLength[4] = anchoredLength[4]
- (int) Math.abs((offsetMultiInstance - point[4]
.getAfter()));
} else {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = offsetMultiInstance;
offset[1][1] = offsetMultiInstance;
offset[1][0] = 0.0d;
offset[2][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][0] = 0.0d;
offset[3][1] = length[7] + length[5];
offset[3][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][1] = length[7] + length[5];
offset[4][0] = length[0] - length[4] + offsetMultiInstance;
offset[5][1] = length[7];
offset[5][0] = length[0] - length[4] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER + lineWidth;
offset[6][1] = length[7] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[6][0] = length[0] - length[4] + offsetMultiInstance; // overlapping
offset[7][1] = 0.0d;
offset[7][0] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[6].getAfter())
anchoredLength[6] = anchoredLength[6]
- (int) Math.abs((offsetMultiInstance - point[6]
.getAfter()));
}
break;
case 180:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][0] = 0.0d;
offset[2][1] = offsetMultiInstance;
offset[2][0] = 0.0d;
offset[3][1] = 0.0d;
offset[3][0] = offsetMultiInstance;
offset[4][1] = 0.0d;
offset[4][0] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][1] = length[4] - lineWidth;
offset[5][0] = length[3] + offsetMultiInstance;
offset[6][1] = offsetMultiInstance;
offset[6][0] = length[3] + length[5];
offset[7][1] = 0.0d;
offset[7][0] = length[3] + length[5] + offsetMultiInstance;
} else {
// specify relative starting points of polygon line segments
offset[0][1] = 0.0d;
offset[0][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][1] = 0.0d;
offset[1][0] = offsetMultiInstance;
offset[2][1] = offsetMultiInstance;
offset[2][0] = 0.0d;
offset[3][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][0] = 0.0d;
offset[4][1] = length[0] - length[4] + offsetMultiInstance;
offset[4][0] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[5][1] = length[0] - length[4] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER + lineWidth;
offset[5][0] = length[3] + offsetMultiInstance;
offset[6][1] = length[0] - length[4] + offsetMultiInstance;
offset[6][0] = length[3] + length[5];
offset[7][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[7][0] = length[3] + length[5];
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[4].getAfter())
anchoredLength[4] = anchoredLength[4]
- (int) Math.abs((offsetMultiInstance - point[4]
.getAfter()));
}
break;
case 270:
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[0][0] = 0.0d;
offset[1][1] = offsetMultiInstance;
offset[1][0] = 0.0d;
offset[2][1] = 0.0d;
offset[2][0] = offsetMultiInstance;
offset[3][1] = 0.0d;
offset[3][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][1] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][0] = length[0] - length[4] + offsetMultiInstance;
offset[5][1] = length[3] + offsetMultiInstance;
offset[5][0] = length[0] - length[4] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER + lineWidth;
offset[6][1] = length[3] + length[5];
offset[6][0] = length[0] - length[4] + offsetMultiInstance;
offset[7][1] = length[3] + length[5];
offset[7][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[4].getAfter())
anchoredLength[4] = anchoredLength[4]
- (int) Math.abs((offsetMultiInstance - point[4]
.getAfter()));
if (offsetMultiInstance > point[5].getAfter())
anchoredLength[5] = anchoredLength[5]
- (int) Math.abs((offsetMultiInstance - point[5]
.getAfter()));
} else {
// specify relative starting points of polygon line segments
offset[0][1] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[0][0] = 0.0d;
offset[1][1] = 0.0d;
offset[1][0] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[2][1] = 0.0d;
offset[2][0] = offsetMultiInstance;
offset[3][1] = offsetMultiInstance;
offset[3][0] = 0.0d;
offset[4][1] = length[3] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[4][0] = 0.0d;
offset[5][1] = length[3] + offsetMultiInstance;
offset[5][0] = length[4] - lineWidth;
offset[6][1] = length[3] + length[5];
offset[6][0] = offsetMultiInstance;
offset[7][1] = length[3] + length[5] + offsetMultiInstance;
offset[7][0] = 0.0d;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[6].getAfter())
anchoredLength[6] = anchoredLength[6]
- (int) Math.abs((offsetMultiInstance - point[6]
.getAfter()));
}
break;
default: // rotation = 0
if (isFlipped(secondLevelPolygon)) {
// specify relative starting points of polygon line segments
offset[0][1] = offsetMultiInstance;
offset[0][0] = 0.0d;
offset[1][1] = 0.0d;
offset[1][0] = offsetMultiInstance;
offset[2][1] = 0.0d;
offset[2][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][0] = length[7] + length[5];
offset[4][1] = length[0] - length[4] + offsetMultiInstance;
offset[4][0] = length[7] + length[5];
offset[5][1] = length[0] - length[4] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER + lineWidth;
offset[5][0] = length[7];
offset[6][1] = length[0] - length[4] + offsetMultiInstance;
offset[6][0] = length[7] - DEFAULT_ANCHOR_DIAMETER
+ offsetMultiInstance; // overlapping
offset[7][1] = length[0] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[7][0] = 0.0d;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[6].getAfter())
anchoredLength[6] = anchoredLength[6]
- (int) (offsetMultiInstance - point[6].getAfter());
} else {
// specify relative starting points of polygon line segments
offset[0][1] = offsetMultiInstance;
offset[0][0] = 0.0d;
offset[1][1] = length[2] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[1][0] = 0.0d;
offset[2][1] = 0.0d;
offset[2][0] = length[1] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[3][1] = 0.0d;
offset[3][0] = length[7] + length[5] + offsetMultiInstance;
offset[4][1] = offsetMultiInstance;
offset[4][0] = length[7] + length[5];
offset[5][1] = length[4] - lineWidth;
offset[5][0] = length[7] + offsetMultiInstance;
offset[6][1] = 0.0d;
offset[6][0] = length[7] + offsetMultiInstance
- DEFAULT_ANCHOR_DIAMETER;
offset[7][1] = 0.0d;
offset[7][0] = offsetMultiInstance;
// adjust length of segments due to overlapping of multi
// instances
if (offsetMultiInstance > point[5].getAfter())
anchoredLength[5] = anchoredLength[5]
- (int) (offsetMultiInstance - point[5].getAfter());
}
}
// adjust offsets according to rounded corners
for (int i = 0; i < numSides; i++) {
if (point[i].getX() == point[(i + 1) % numSides].getX()) { // vertical
// side
offset[i][1] = offset[i][1]
+ (point[i].getY() < point[(i + 1) % numSides].getY() ? (point[i]
.getAfter() > 0 ? point[i].getAfter()
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d)
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1)
% numSides].getBefore()
- ((double) DEFAULT_ANCHOR_DIAMETER)
/ 2
: 0.0d));
} else { // horizontal side
offset[i][0] = offset[i][0]
+ (point[i].getX() < point[(i + 1) % numSides].getX() ? (point[i]
.getAfter() > 0 ? point[i].getAfter()
- ((double) DEFAULT_ANCHOR_DIAMETER) / 2 : 0.0d)
: (point[(i + 1) % numSides].getBefore() > 0 ? point[(i + 1)
% numSides].getBefore()
- ((double) DEFAULT_ANCHOR_DIAMETER)
/ 2
: 0.0d));
}
}
// Calculate number of anchors per side
for (int i = 0; i < numSides; i++)
numAnchors[i] = anchoredLength[i] / DEFAULT_ANCHOR_GAP;
// Calculate gaps between the starting points of the anchors for each
// side
int direction = 0;
for (int i = 0; i < numSides; i++) {
direction = isFlattened(secondLevelPolygon) ? (i % 2)
: ((i + 1) % 2);
gaps[i][direction] = ((double) anchoredLength[i]) / numAnchors[i];
}
// Create relative box anchors
for (int i = 0; i < numSides; i++)
for (int j = 0; j < numAnchors[i]; j++)
createBoxAnchor(shape, (offset[i][0] + j * gaps[i][0])
/ firstLevelPolygon.getWidth(), (offset[i][1] + j
* gaps[i][1])
/ firstLevelPolygon.getHeight(),
AnchoredNode.DEFAULT_ANCHOR_GAP,
AnchoredNode.DEFAULT_ANCHOR_DIAMETER);
}
}