getAll() {
+ return all;
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/svek/Shape.java b/src/net/sourceforge/plantuml/svek/Shape.java
index fd05ee9e5..58ef5072f 100644
--- a/src/net/sourceforge/plantuml/svek/Shape.java
+++ b/src/net/sourceforge/plantuml/svek/Shape.java
@@ -36,12 +36,14 @@ package net.sourceforge.plantuml.svek;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.util.List;
+import java.util.Map;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.Hideable;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.graphic.StringBounderUtils;
import net.sourceforge.plantuml.posimo.Positionable;
import net.sourceforge.plantuml.svek.image.EntityImageDescription;
import net.sourceforge.plantuml.svek.image.EntityImageStateBorder;
@@ -96,7 +98,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable {
this.color = colorSequence.getValue();
this.uid = String.format("sh%04d", color);
this.shield = shield;
- if (shield > 0 && type != ShapeType.RECTANGLE) {
+ if (shield > 0 && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS) {
throw new IllegalArgumentException();
}
}
@@ -114,6 +116,10 @@ public class Shape implements Positionable, IShapePseudo, Hideable {
}
public void appendShape(StringBuilder sb) {
+ if (type == ShapeType.RECTANGLE_HTML_FOR_PORTS) {
+ appendLabelHtmlSpecialForLink(sb);
+ return;
+ }
if (type == ShapeType.RECTANGLE && shield > 0) {
appendHtml(sb);
return;
@@ -169,6 +175,47 @@ public class Shape implements Positionable, IShapePseudo, Hideable {
sb.append("");
}
+ private void appendLabelHtmlSpecialForLink(StringBuilder sb) {
+ final Ports ports = ((WithPorts) this.image).getPorts(StringBounderUtils.asStringBounder());
+
+ sb.append(uid);
+ sb.append(" [");
+ sb.append("shape=plaintext,");
+ // sb.append("color=\"" + StringUtils.getAsHtml(color) + "\",");
+ sb.append("label=<");
+ sb.append("");
+ double position = 0;
+ for (Map.Entry ent : ports.getAll().entrySet()) {
+ final String portName = ent.getKey();
+ final PortGeometry geom = ent.getValue();
+ final double missing = geom.getPosition() - position;
+ appendTr(sb, null, missing);
+ appendTr(sb, portName, geom.getHeight());
+ position = geom.getLastY();
+ }
+ appendTr(sb, null, getHeight() - position);
+ sb.append("
");
+ sb.append(">");
+ sb.append("];");
+ SvekUtils.println(sb);
+ }
+
+ private void appendTr(StringBuilder sb, final String portName, final double height) {
+ if (height <= 0) {
+ return;
+ }
+ sb.append("");
+ sb.append("");
+ sb.append(" | ");
+ sb.append("
");
+ }
+
private void appendTd(StringBuilder sb, int w, int h) {
sb.append(" maxX) {
@@ -124,6 +127,9 @@ public class SvgGraphics {
defs = simpleElement("defs");
gRoot = simpleElement("g");
strokeWidth = "" + scale;
+ final Random rnd = new Random();
+ this.filterUid = "b" + Integer.toString(Math.abs(rnd.nextInt()), 36);
+ this.shadowId = "f" + Integer.toString(Math.abs(rnd.nextInt()), 36);
} catch (ParserConfigurationException e) {
e.printStackTrace();
throw new IllegalStateException(e);
@@ -188,9 +194,7 @@ public class SvgGraphics {
elt.setAttribute("ry", format(yRadius));
elt.setAttribute("fill", fill);
elt.setAttribute("style", getStyle());
- if (deltaShadow > 0) {
- elt.setAttribute("filter", "url(#f1)");
- }
+ addFilterShadowId(elt, deltaShadow);
getG().appendChild(elt);
}
ensureVisible(x + xRadius + deltaShadow * 2, y + yRadius + deltaShadow * 2);
@@ -313,9 +317,7 @@ public class SvgGraphics {
manageShadow(deltaShadow);
if (hidden == false) {
final Element elt = createRectangleInternal(x, y, width, height);
- if (deltaShadow > 0) {
- elt.setAttribute("filter", "url(#f1)");
- }
+ addFilterShadowId(elt, deltaShadow);
if (rx > 0 && ry > 0) {
elt.setAttribute("rx", format(rx));
elt.setAttribute("ry", format(ry));
@@ -346,9 +348,7 @@ public class SvgGraphics {
elt.setAttribute("x2", format(x2));
elt.setAttribute("y2", format(y2));
elt.setAttribute("style", getStyle());
- if (deltaShadow > 0) {
- elt.setAttribute("filter", "url(#f1)");
- }
+ addFilterShadowId(elt, deltaShadow);
getG().appendChild(elt);
}
ensureVisible(x1 + 2 * deltaShadow, y1 + 2 * deltaShadow);
@@ -381,9 +381,7 @@ public class SvgGraphics {
elt.setAttribute("points", sb.toString());
elt.setAttribute("fill", fill);
elt.setAttribute("style", getStyle());
- if (deltaShadow > 0) {
- elt.setAttribute("filter", "url(#f1)");
- }
+ addFilterShadowId(elt, deltaShadow);
getG().appendChild(elt);
}
@@ -448,7 +446,7 @@ public class SvgGraphics {
private String getIdFilterBackColor(String color) {
String result = filterBackColor.get(color);
if (result == null) {
- result = "b" + filterBackColor.size();
+ result = filterUid + filterBackColor.size();
filterBackColor.put(color, result);
}
return result;
@@ -591,13 +589,17 @@ public class SvgGraphics {
elt.setAttribute("d", sb.toString());
elt.setAttribute("style", getStyle());
elt.setAttribute("fill", fill);
- if (deltaShadow > 0) {
- elt.setAttribute("filter", "url(#f1)");
- }
+ addFilterShadowId(elt, deltaShadow);
getG().appendChild(elt);
}
}
+ private void addFilterShadowId(final Element elt, double deltaShadow) {
+ if (deltaShadow > 0) {
+ elt.setAttribute("filter", "url(#" + shadowId + ")");
+ }
+ }
+
private StringBuilder currentPath = null;
public void newpath() {
@@ -701,7 +703,7 @@ public class SvgGraphics {
if (withShadow == false) {
//
final Element filter = (Element) document.createElement("filter");
- filter.setAttribute("id", "f1");
+ filter.setAttribute("id", shadowId);
filter.setAttribute("x", "-1");
filter.setAttribute("y", "-1");
filter.setAttribute("width", "300%");
diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverCenteredCharacterEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverCenteredCharacterEps.java
index c761d326c..fe26b72de 100644
--- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverCenteredCharacterEps.java
+++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverCenteredCharacterEps.java
@@ -56,7 +56,7 @@ public class DriverCenteredCharacterEps implements UDriver {
final TextLayout t = new TextLayout("" + c, font.getFont(), TextBlockUtils.getFontRenderContext());
eps.setStrokeColor(mapper.getMappedColor(param.getColor()));
- DriverTextEps.drawPathIterator(eps, xpos, ypos, t.getOutline(null).getPathIterator(null));
+ DriverTextEps.drawPathIterator(eps, xpos, ypos, t.getOutline(null));
}
diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java
index 38eeadd05..2b0e00c54 100644
--- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java
+++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java
@@ -32,9 +32,12 @@
package net.sourceforge.plantuml.ugraphic.eps;
import java.awt.Color;
+import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.PathIterator;
+import java.util.ArrayList;
+import java.util.List;
import net.sourceforge.plantuml.eps.EpsGraphics;
import net.sourceforge.plantuml.eps.EpsGraphicsMacroAndText;
@@ -85,7 +88,8 @@ public class DriverTextEps implements UDriver {
final FontConfiguration fontConfiguration = shape.getFontConfiguration();
final UFont font = fontConfiguration.getFont();
- final TextLayout t = new TextLayout(shape.getText(), font.getFont(), fontRenderContext);
+ final TextLayout textLayout = new TextLayout(shape.getText(), font.getFont(), fontRenderContext);
+ // System.err.println("text=" + shape.getText());
MinMax dim = null;
@@ -96,14 +100,14 @@ public class DriverTextEps implements UDriver {
eps.setFillColor(extended);
eps.setStrokeWidth("1", 0, 0);
if (dim == null) {
- dim = getMinMax(x, y, t.getOutline(null).getPathIterator(null));
+ dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null));
}
eps.epsRectangle(dim.getMinX() - 1, dim.getMinY() - 1, dim.getWidth() + 2, dim.getHeight() + 2, 0, 0);
}
}
eps.setStrokeColor(mapper.getMappedColor(fontConfiguration.getColor()));
- drawPathIterator(eps, x, y, t.getOutline(null).getPathIterator(null));
+ drawPathIterator(eps, x, y, getOutline(textLayout));
if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) {
final HtmlColor extended = fontConfiguration.getExtendedColor();
@@ -111,7 +115,7 @@ public class DriverTextEps implements UDriver {
eps.setStrokeColor(mapper.getMappedColor(extended));
}
if (dim == null) {
- dim = getMinMax(x, y, t.getOutline(null).getPathIterator(null));
+ dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null));
}
eps.setStrokeWidth("1.1", 0, 0);
eps.epsLine(x, y + 1.5, x + dim.getWidth(), y + 1.5);
@@ -119,7 +123,7 @@ public class DriverTextEps implements UDriver {
}
if (fontConfiguration.containsStyle(FontStyle.WAVE)) {
if (dim == null) {
- dim = getMinMax(x, y, t.getOutline(null).getPathIterator(null));
+ dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null));
}
final int ypos = (int) (y + 2.5) - 1;
final HtmlColor extended = fontConfiguration.getExtendedColor();
@@ -139,7 +143,7 @@ public class DriverTextEps implements UDriver {
eps.setStrokeColor(mapper.getMappedColor(extended));
}
if (dim == null) {
- dim = getMinMax(x, y, t.getOutline(null).getPathIterator(null));
+ dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null));
}
// final FontMetrics fm = font.getFontMetrics();
final double ypos = (dim.getMinY() + dim.getMaxY() * 2) / 3;
@@ -150,6 +154,10 @@ public class DriverTextEps implements UDriver {
}
+ private Shape getOutline(final TextLayout textLayout) {
+ return textLayout.getOutline(null);
+ }
+
private void drawAsText(UText shape, double x, double y, UParam param, EpsGraphics eps, ColorMapper mapper) {
final FontConfiguration fontConfiguration = shape.getFontConfiguration();
// final FontMetrics fm = g2dummy.getFontMetrics(fontConfiguration.getFont().getFont());
@@ -161,8 +169,26 @@ public class DriverTextEps implements UDriver {
}
- static void drawPathIterator(EpsGraphics eps, double x, double y, PathIterator path) {
+ static void drawPathIterator(EpsGraphics eps, double x, double y, Shape shape) {
+ final List breaks = analyze(shape);
+ if (breaks.size() == 0) {
+ final PathIterator path = shape.getPathIterator(null);
+ drawSingle(eps, x, y, path);
+ return;
+ }
+ // System.err.println("breaks=" + breaks);
+ final PathIterator path = new PathIteratorLimited(shape, 0, breaks.get(0));
+ drawSingle(eps, x, y, path);
+ for (int i = 0; i < breaks.size() - 1; i++) {
+ final PathIterator path2 = new PathIteratorLimited(shape, breaks.get(i) + 1, breaks.get(i + 1));
+ drawSingle(eps, x, y, path2);
+ }
+ final PathIterator path3 = new PathIteratorLimited(shape, breaks.get(breaks.size() - 1) + 1, Integer.MAX_VALUE);
+ drawSingle(eps, x, y, path3);
+ }
+
+ private static void drawSingle(EpsGraphics eps, double x, double y, final PathIterator path) {
eps.newpath();
final double coord[] = new double[6];
while (path.isDone() == false) {
@@ -185,7 +211,40 @@ public class DriverTextEps implements UDriver {
}
eps.fill(path.getWindingRule());
+ }
+ private static List analyze(Shape shape) {
+ int count = PathIteratorLimited.count(shape);
+ final List closings = getClosings(shape.getPathIterator(null));
+ final List result = new ArrayList();
+ for (Integer cl : closings) {
+ if (cl + 2 >= count) {
+ break;
+ }
+ final PathIterator path1 = new PathIteratorLimited(shape, 0, cl);
+ final PathIterator path2 = new PathIteratorLimited(shape, cl + 1, Integer.MAX_VALUE);
+ final double max1 = getMinMax(0, 0, path1).getMaxX();
+ final double min2 = getMinMax(0, 0, path2).getMinX();
+ if (min2 > max1) {
+ result.add(cl);
+ }
+ }
+ return result;
+ }
+
+ private static List getClosings(PathIterator path) {
+ final List result = new ArrayList();
+ int current = 0;
+ final double coord[] = new double[6];
+ while (path.isDone() == false) {
+ final int code = path.currentSegment(coord);
+ if (code == PathIterator.SEG_CLOSE) {
+ result.add(current);
+ }
+ current++;
+ path.next();
+ }
+ return result;
}
static private MinMax getMinMax(double x, double y, PathIterator path) {
@@ -216,4 +275,5 @@ public class DriverTextEps implements UDriver {
return result;
}
+
}
diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/PathIteratorLimited.java b/src/net/sourceforge/plantuml/ugraphic/eps/PathIteratorLimited.java
new file mode 100644
index 000000000..d86bfc59d
--- /dev/null
+++ b/src/net/sourceforge/plantuml/ugraphic/eps/PathIteratorLimited.java
@@ -0,0 +1,85 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
+ * in the United States and other countries.]
+ *
+ * Original Author: Arnaud Roques
+ *
+ */
+package net.sourceforge.plantuml.ugraphic.eps;
+
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+
+public class PathIteratorLimited implements PathIterator {
+
+ private final PathIterator path;
+ private final int limit;
+ private int current = 0;
+
+ public static int count(Shape source) {
+ int result = 0;
+ final PathIterator path = source.getPathIterator(null);
+ while (path.isDone() == false) {
+ result++;
+ path.next();
+ }
+ return result;
+ }
+
+ public PathIteratorLimited(Shape source, int start, int limit) {
+ this.path = source.getPathIterator(null);
+ this.limit = limit;
+ for (int i = 0; i < start; i++) {
+ this.next();
+ }
+ }
+
+ public int currentSegment(float[] arg0) {
+ return path.currentSegment(arg0);
+ }
+
+ public int currentSegment(double[] arg0) {
+ return path.currentSegment(arg0);
+ }
+
+ public int getWindingRule() {
+ return path.getWindingRule();
+ }
+
+ public boolean isDone() {
+ if (current >= limit) {
+ return true;
+ }
+ return path.isDone();
+ }
+
+ public void next() {
+ path.next();
+ current++;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/version/License.java b/src/net/sourceforge/plantuml/version/License.java
index bc729b9a3..f96143a8f 100644
--- a/src/net/sourceforge/plantuml/version/License.java
+++ b/src/net/sourceforge/plantuml/version/License.java
@@ -37,7 +37,7 @@ import java.util.List;
public enum License {
- GPL, LGPL, APACHE, EPL, MIT, BSD;
+ GPL, GPLV2, LGPL, APACHE, EPL, MIT, BSD;
public static License getCurrent() {
return GPL;
@@ -216,6 +216,36 @@ public enum License {
text.add("by the very same license.");
}
+ private void addGplV2(final List text) {
+ text.add("PlantUML is free software; you can redistribute it and/or modify it");
+ text.add("under the terms of the GNU General Public License as published by");
+ text.add("the Free Software Foundation, either version 2 of the License, or");
+ text.add("(at your option) any later version.");
+ text.add("");
+ text.add("PlantUML distributed in the hope that it will be useful, but");
+ text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
+ text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
+ text.add("License for more details.");
+ text.add("");
+ text.add("You should have received a copy of the GNU General Public");
+ text.add("License along with this library; if not, write to the Free Software");
+ text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
+ text.add("USA.");
+ text.add("");
+ text.add("Note that images (whatever their format : PNG, SVG...) generated by running PlantUML");
+ text.add("are owned by the author of their corresponding sources code (that is, their");
+ text.add("textual description in PlantUML language). Those images are not covered by");
+ text.add("the GPL license.");
+ text.add("");
+ text.add("The generated images can then be used without any reference to the GPL license.");
+ text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
+ text.add("also this will be appreciate by PlantUML team.");
+ text.add("");
+ text.add("There is an exception : if the textual description in PlantUML language is also covered");
+ text.add("by a license (like the GPL), then the generated images are logically covered");
+ text.add("by the very same license.");
+ }
+
private void addLgpl(final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU Lesser General Public License as published by");
@@ -287,6 +317,22 @@ public enum License {
h.add(" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
h.add(" * USA.");
h.add(" *");
+ } else if (this == License.GPLV2) {
+ h.add(" * PlantUML is free software; you can redistribute it and/or modify it");
+ h.add(" * under the terms of the GNU General Public License as published by");
+ h.add(" * the Free Software Foundation, either version 2 of the License, or");
+ h.add(" * (at your option) any later version.");
+ h.add(" *");
+ h.add(" * PlantUML distributed in the hope that it will be useful, but");
+ h.add(" * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
+ h.add(" * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
+ h.add(" * License for more details.");
+ h.add(" *");
+ h.add(" * You should have received a copy of the GNU General Public");
+ h.add(" * License along with this library; if not, write to the Free Software");
+ h.add(" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
+ h.add(" * USA.");
+ h.add(" *");
} else if (this == License.APACHE) {
h.add(" * Licensed under the Apache License, Version 2.0 (the \"License\");");
h.add(" * you may not use this file except in compliance with the License.");
@@ -376,6 +422,8 @@ public enum License {
final List text = getHeaderStart();
if (this == License.GPL) {
addGpl(text);
+ } else if (this == License.GPLV2) {
+ addGplV2(text);
} else if (this == License.MIT) {
addMit(text);
} else if (this == License.EPL) {
diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java
index fbcf29d94..dad85a040 100644
--- a/src/net/sourceforge/plantuml/version/PSystemVersion.java
+++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java
@@ -189,8 +189,8 @@ public class PSystemVersion extends AbstractPSystem {
int lim = 7;
if (lastversion == -1) {
- strings.add("Error");
- strings.add("Cannot connect to http://plantuml.com/");
+ strings.add("Error");
+ strings.add("Cannot connect to http://plantuml.com/");
strings.add("Maybe you should set your proxy ?");
strings.add("@startuml");
strings.add("checkversion(proxy=myproxy.com,port=8080)");
@@ -198,14 +198,14 @@ public class PSystemVersion extends AbstractPSystem {
lim = 9;
} else if (lastversion == 0) {
strings.add("Error");
- strings.add("Cannot retrieve last version from http://plantuml.com/");
+ strings.add("Cannot retrieve last version from http://plantuml.com/");
} else {
strings.add("Last available version for download : " + lastversion);
strings.add(" ");
if (Version.version() >= lastversion) {
- strings.add("Your version is up to date.");
+ strings.add("Your version is up to date.");
} else {
- strings.add("A newer version is available for download.");
+ strings.add("A newer version is available for download.");
}
}
diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java
index 6df7a02f0..e0b48e479 100644
--- a/src/net/sourceforge/plantuml/version/Version.java
+++ b/src/net/sourceforge/plantuml/version/Version.java
@@ -28,7 +28,7 @@
*
* Original Author: Arnaud Roques
*
- * Revision $Revision: 19980 $
+ * Revision $Revision: 20097 $
*
*/
package net.sourceforge.plantuml.version;
@@ -39,7 +39,7 @@ import java.util.Date;
public class Version {
public static int version() {
- return 8043;
+ return 8045;
}
public static String versionString() {
@@ -71,7 +71,7 @@ public class Version {
}
public static long compileTime() {
- return 1466340806152L;
+ return 1467650874144L;
}
public static String compileTimeString() {
diff --git a/src/net/sourceforge/plantuml/version/logo.png b/src/net/sourceforge/plantuml/version/logo.png
index 986cf4e75..faf91ddc6 100644
Binary files a/src/net/sourceforge/plantuml/version/logo.png and b/src/net/sourceforge/plantuml/version/logo.png differ
|