in packages/stunner-editors/lienzo-core/src/main/java/com/ait/lienzo/client/core/shape/OrthogonalPolyLine.java [450:630]
private static int drawTail(Point2DArray points, NFastDoubleArray buffer, Direction lastDirection, Direction tailDirection, double correction, final OrthogonalPolyLine pline, double p0x, double p0y, double p1x, double p1y, boolean write) {
double tailOffset = pline.getTailOffset();
double distance = 0;
Point2D p1 = points.get(points.size() - 1);
// correct for tailOffset
if (tailOffset > 0) {
if (!write) {
p1 = p1.copy();
}
correctEndWithOffset(tailOffset, tailDirection, p1);
p1x = p1.getX();
p1y = p1.getY();
}
// correct for correction
if (correction > 0) {
// must do this off a cloned Point2D, as we still need the p1, for the last part of the line at the end.
Point2D p1Copy = p1.copy();
correctEndWithOffset(correction, tailDirection, p1Copy);
p1x = p1Copy.getX();
p1y = p1Copy.getY();
}
final double dx = (p1x - p0x);
final double dy = (p1y - p0y);
int corners = 0;
boolean behind = false;
switch (tailDirection) {
case NORTH:
behind = dy < 0;
break;
case SOUTH:
behind = dy > 0;
break;
case WEST:
behind = dx < 0;
break;
case EAST:
behind = dx > 0;
break;
case NONE:
// do nothing as NONE is explicitey handled at the end
break;
default:
throw new IllegalStateException("Invalid Direction " + tailDirection);
}
double x = p0x;
double y = p0y;
if (behind) {
// means p0 is behind.
switch (tailDirection) {
case NORTH:
case SOUTH:
if ((lastDirection == NORTH && tailDirection == SOUTH) ||
(lastDirection == SOUTH && tailDirection == NORTH) ||
(dx > 0 && lastDirection == EAST) ||
(dx < 0 && lastDirection == WEST)) {
// A mid point is needed to ensure an attractive line is drawn.
x = p0x + (dx / 2);
addPoint(buffer, x, y, write);
if (lastDirection == NORTH || lastDirection == SOUTH) {
corners++;
}
}
y = p1y;
addPoint(buffer, x, y, write);
if (lastDirection != tailDirection) {
corners++;
}
x = p1x;
addPoint(buffer, x, y, write);
corners++;
y = p1.getY();
addPoint(buffer, x, y, write);
corners++;
break;
case WEST:
case EAST:
if ((lastDirection == WEST && tailDirection == EAST) ||
(lastDirection == EAST && tailDirection == WEST) ||
(dy > 0 && lastDirection == SOUTH) ||
(dy < 0 && lastDirection == NORTH)) {
// A mid point is needed to ensure an attrictive line is drawn.
y = p0y + (dy / 2);
addPoint(buffer, x, y, write);
if (lastDirection == EAST || lastDirection == WEST) {
corners++;
}
}
x = p1x;
addPoint(buffer, x, y, write);
if (lastDirection != tailDirection) {
corners++;
}
y = p1y;
addPoint(buffer, x, y, write);
corners++;
x = p1.getX();
addPoint(buffer, x, y, write);
corners++;
break;
default:
throw new IllegalStateException("Invalid Direction " + tailDirection);
}
} else {
// means p0 is in front
switch (tailDirection) {
case NORTH:
case SOUTH:
if ((lastDirection == NORTH && tailDirection == SOUTH) ||
(lastDirection == SOUTH && tailDirection == NORTH) ||
(dx > 0 && lastDirection == WEST) ||
(dx < 0 && lastDirection == EAST)) {
// A mid point is needed to ensure an attrictive line is drawn.
y = p0y + (dy / 2);
addPoint(buffer, x, y, write);
if (lastDirection == EAST || lastDirection == WEST) {
lastDirection = (dy < 0) ? NORTH : SOUTH;
corners++;
}
}
x = p1x;
addPoint(buffer, x, y, write);
if (lastDirection == NORTH || lastDirection == SOUTH) {
corners++;
}
y = p1.getY();
addPoint(buffer, x, y, write);
corners++;
break;
case WEST:
case EAST:
if ((lastDirection == WEST && tailDirection == EAST) ||
(lastDirection == EAST && tailDirection == WEST) ||
(dy > 0 && lastDirection == NORTH) ||
(dy < 0 && lastDirection == SOUTH)) {
// A mid point is needed to ensure an attrictive line is drawn.
x = p0x + (dx / 2);
addPoint(buffer, x, y, write);
if (lastDirection == NORTH || lastDirection == SOUTH) {
lastDirection = (dx < 0) ? WEST : EAST;
corners++;
}
}
y = p1y;
addPoint(buffer, x, y, write);
if (lastDirection == EAST || lastDirection == WEST) {
corners++;
}
x = p1.getX();
addPoint(buffer, x, y, write);
corners++;
break;
default:
throw new IllegalStateException("Invalid Direction " + tailDirection);
}
}
return corners;
}