diff --git a/src/net/sourceforge/plantuml/Dimension2DDouble.java b/src/net/sourceforge/plantuml/Dimension2DDouble.java index bf091c48e..5affb5c29 100644 --- a/src/net/sourceforge/plantuml/Dimension2DDouble.java +++ b/src/net/sourceforge/plantuml/Dimension2DDouble.java @@ -87,9 +87,9 @@ public class Dimension2DDouble extends Dimension2D { } public static Dimension2D delta(Dimension2D dim, double deltaWidth, double deltaHeight) { - if (deltaHeight == 0 && deltaWidth == 0) { + if (deltaHeight == 0 && deltaWidth == 0) return dim; - } + return new Dimension2DDouble(dim.getWidth() + deltaWidth, dim.getHeight() + deltaHeight); } @@ -124,15 +124,15 @@ public class Dimension2DDouble extends Dimension2D { public static Dimension2D atLeast(Dimension2D dim, double minWidth, double minHeight) { double h = dim.getHeight(); double w = dim.getWidth(); - if (w > minWidth && h > minHeight) { + if (w > minWidth && h > minHeight) return dim; - } - if (h < minHeight) { + + if (h < minHeight) h = minHeight; - } - if (w < minWidth) { + + if (w < minWidth) w = minWidth; - } + return new Dimension2DDouble(w, h); } diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java index b286f9a90..c2cf8cea3 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -212,7 +212,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { } private TextBlock getEntityImageClass(ILeaf entity) { - return new EntityImageClass(null, entity, getSkinParam(), this); + return new EntityImageClass(entity, getSkinParam(), this); } @Override diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index c7006c98a..6c25d36ef 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -81,6 +81,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; +import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; public class ClassDiagramFactory extends PSystemCommandFactory { @@ -108,6 +109,7 @@ public class ClassDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandCreateEntityObjectMultilines()); cmds.add(new CommandCreateMap()); cmds.add(new CommandCreateJson()); + cmds.add(new CommandCreateJsonSingleLine()); cmds.add(new CommandCreateClass()); cmds.add(new CommandCreateEntityObject()); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java index f49233dad..a4c1a8b18 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java @@ -80,7 +80,7 @@ public class CommandCreateClass extends SingleLineCommand2 { private static IRegex getRegexConcat() { return RegexConcat.build(CommandCreateClass.class.getName(), RegexLeaf.start(), // new RegexLeaf("TYPE", // - "(interface|enum|annotation|abstract[%s]+class|abstract|class|entity|circle|diamond|protocol|struct|exception)"), // + "(interface|enum|annotation|abstract[%s]+class|static[%s]+class|abstract|class|entity|circle|diamond|protocol|struct|exception)"), // RegexLeaf.spaceOneOrMore(), // new RegexOr(// new RegexConcat(// diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index f5bcabed7..117faae7b 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -94,7 +94,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2 0) .withQualifier(labels.getFirstLabel(), labels.getSecondLabel()) - .withDistanceAngle(diagram.getLabeldistance(), diagram.getLabelangle()).withKal(kal1); + .withDistanceAngle(diagram.getLabeldistance(), diagram.getLabelangle()).withKal(kal1, kal2); Link link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, cl2, linkType, linkArg); if (arg.get("URL", 0) != null) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index e1c9185a0..60232f322 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.cucadiagram; -import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; @@ -60,10 +59,6 @@ import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; -import net.sourceforge.plantuml.cucadiagram.dot.Graphviz; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersions; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.elk.CucaDiagramFileMakerElk; import net.sourceforge.plantuml.graphic.USymbol; @@ -75,7 +70,6 @@ import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.svek.CucaDiagramFileMaker; import net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek; import net.sourceforge.plantuml.ugraphic.color.ColorMapper; -import net.sourceforge.plantuml.vizjs.GraphvizJs; import net.sourceforge.plantuml.xmi.CucaDiagramXmiMaker; import net.sourceforge.plantuml.xmlsc.StateDiagramScxmlMaker; @@ -879,24 +873,5 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, // Strange numbers here for backwards compatibility return ClockwiseTopRightBottomLeft.topRightBottomLeft(0, 5, 5, 0); } - - private GraphvizVersion graphvizVersion; - - public GraphvizVersion getGraphvizVersion() { - if (graphvizVersion == null) - graphvizVersion = getGraphvizVersionInternal(); - - return graphvizVersion; - } - - private GraphvizVersion getGraphvizVersionInternal() { - final Graphviz graphviz = GraphvizUtils.create(getSkinParam(), "foo;", "svg"); - if (graphviz instanceof GraphvizJs) - return GraphvizJs.getGraphvizVersion(false); - - final File f = graphviz.getDotExe(); - return GraphvizVersions.getInstance().getVersion(f); - } - } diff --git a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java index 148f86954..a7467e6a8 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java @@ -65,12 +65,15 @@ public enum LeafType { public static LeafType getLeafType(String type) { type = StringUtils.goUpperCase(type); - if (type.startsWith("ABSTRACT")) { + if (type.startsWith("ABSTRACT")) return LeafType.ABSTRACT_CLASS; - } - if (type.startsWith("DIAMOND")) { + + if (type.startsWith("DIAMOND")) return LeafType.STATE_CHOICE; - } + + if (type.startsWith("STATIC")) + return LeafType.CLASS; + return LeafType.valueOf(type); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index 85c653c00..01b2dd697 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -46,7 +46,6 @@ import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.awt.geom.Dimension2D; import net.sourceforge.plantuml.command.Position; -import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; @@ -56,7 +55,6 @@ import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.svek.Bibliotekon; -import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.ugraphic.UComment; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.utils.UniqueSequence; @@ -125,13 +123,6 @@ public class Link extends WithLinkType implements Hideable, Removeable { this.type = type; this.linkArg = linkArg; - - if (linkArg.getQualifier1() != null) - ((EntityImpl) cl1).ensureMargins(Margins.uniform(16)); - - if (linkArg.getQualifier2() != null) - ((EntityImpl) cl2).ensureMargins(Margins.uniform(16)); - } public Link getInv() { diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkArg.java b/src/net/sourceforge/plantuml/cucadiagram/LinkArg.java index 6d432d5e7..15cc3132f 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkArg.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkArg.java @@ -54,11 +54,11 @@ public class LinkArg { public static LinkArg build(final Display label, int length) { return build(label, length, true); } + public static LinkArg noDisplay(int length) { return build(Display.NULL, length, true); } - public static LinkArg build(final Display label, int length, boolean manageVisibilityModifier) { VisibilityModifier visibilityModifier = null; final Display newLabel; @@ -77,7 +77,7 @@ public class LinkArg { kal2); } - public LinkArg withKal(String kal1) { + public LinkArg withKal(String kal1, String kal2) { return new LinkArg(label, length, qualifier1, qualifier2, labeldistance, labelangle, visibilityModifier, kal1, kal2); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java index 91f8b7720..e387d6483 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java @@ -74,7 +74,6 @@ final public class DotData implements PortionShower { private final ColorMapper colorMapper; private final EntityFactory entityFactory; - private final GraphvizVersion graphvizVersion; public EntityFactory getEntityFactory() { return entityFactory; @@ -83,7 +82,7 @@ final public class DotData implements PortionShower { public DotData(IGroup topParent, List links, Collection leafs, UmlDiagramType umlDiagramType, ISkinParam skinParam, GroupHierarchy groupHierarchy, PortionShower portionShower, ColorMapper colorMapper, EntityFactory entityFactory, boolean isHideEmptyDescriptionForState, DotMode dotMode, - String namespaceSeparator, Pragma pragma, GraphvizVersion graphvizVersion) { + String namespaceSeparator, Pragma pragma) { this.namespaceSeparator = namespaceSeparator; this.pragma = pragma; this.topParent = Objects.requireNonNull(topParent); @@ -98,19 +97,16 @@ final public class DotData implements PortionShower { this.groupHierarchy = groupHierarchy; this.portionShower = portionShower; this.entityFactory = entityFactory; - this.graphvizVersion = graphvizVersion; } public DotData(IGroup topParent, List links, Collection leafs, UmlDiagramType umlDiagramType, ISkinParam skinParam, GroupHierarchy groupHierarchy, ColorMapper colorMapper, EntityFactory entityFactory, - boolean isHideEmptyDescriptionForState, DotMode dotMode, String namespaceSeparator, Pragma pragma, - GraphvizVersion graphvizVersion) { + boolean isHideEmptyDescriptionForState, DotMode dotMode, String namespaceSeparator, Pragma pragma) { this(topParent, links, leafs, umlDiagramType, skinParam, groupHierarchy, new PortionShower() { public boolean showPortion(EntityPortion portion, IEntity entity) { return true; } - }, colorMapper, entityFactory, isHideEmptyDescriptionForState, dotMode, namespaceSeparator, pragma, - graphvizVersion); + }, colorMapper, entityFactory, isHideEmptyDescriptionForState, dotMode, namespaceSeparator, pragma); } public UmlDiagramType getUmlDiagramType() { @@ -236,8 +232,4 @@ final public class DotData implements PortionShower { } - public GraphvizVersion getGraphvizVersion() { - return graphvizVersion; - } - } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersion.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersion.java index 7e8d60211..410573910 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersion.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersion.java @@ -36,7 +36,7 @@ package net.sourceforge.plantuml.cucadiagram.dot; public interface GraphvizVersion { - public boolean useShield(); + public boolean useShieldForQuantifier(); public boolean useProtectionWhenThereALinkFromOrToGroup(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java index 2fb92e2bb..f59316818 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java @@ -45,7 +45,7 @@ public class GraphvizVersionFinder { final private File dotExe; final public static GraphvizVersion DEFAULT = new GraphvizVersion() { - public boolean useShield() { + public boolean useShieldForQuantifier() { return true; } @@ -82,7 +82,7 @@ public class GraphvizVersionFinder { final int minor = Integer.parseInt(m.group(2)); final int v = 100 * major + minor; return new GraphvizVersion() { - public boolean useShield() { + public boolean useShieldForQuantifier() { return v <= 228; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index c08b7e48b..42280e562 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -39,6 +39,7 @@ package net.sourceforge.plantuml.cucadiagram.entity; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.EnumMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -47,6 +48,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; @@ -77,6 +79,7 @@ import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.svek.IEntityImage; +import net.sourceforge.plantuml.svek.Kal; import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.SingleStrategy; @@ -282,7 +285,6 @@ final public class EntityImpl implements ILeaf, IGroup { public final Margins getMargins() { checkNotGroup(); - System.err.println("GETTING MARGIN!"); return margins; } @@ -789,4 +791,23 @@ final public class EntityImpl implements ILeaf, IGroup { return stereostyles; } + private final Map> kals = new EnumMap<>(Direction.class); + + public void addKal(Kal kal) { + final Direction position = kal.getPosition(); + List list = kals.get(position); + if (list == null) { + list = new ArrayList<>(); + kals.put(position, list); + } + list.add(kal); + } + + public List getKals(Direction position) { + final List result = kals.get(position); + if (result == null) + return Collections.emptyList(); + return Collections.unmodifiableList(result); + } + } diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java index 95f89acaf..1467e1688 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java @@ -64,6 +64,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; +import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; public class DescriptionDiagramFactory extends PSystemCommandFactory { @@ -120,6 +121,7 @@ public class DescriptionDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandCreateMap()); cmds.add(new CommandCreateJson()); + cmds.add(new CommandCreateJsonSingleLine()); // cmds.add(new CommandHideShowSpecificClass()); cmds.add(new CommandArchimate()); diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java new file mode 100644 index 000000000..81a4682ab --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java @@ -0,0 +1,135 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * 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. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.objectdiagram.command; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.UrlBuilder; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.BodierJSon; +import net.sourceforge.plantuml.cucadiagram.Code; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; +import net.sourceforge.plantuml.cucadiagram.LeafType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.graphic.color.ColorParser; +import net.sourceforge.plantuml.graphic.color.ColorType; +import net.sourceforge.plantuml.json.Json.DefaultHandler; +import net.sourceforge.plantuml.json.JsonParser; +import net.sourceforge.plantuml.json.JsonValue; +import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; +import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; + +public class CommandCreateJsonSingleLine extends SingleLineCommand2 { + + public CommandCreateJsonSingleLine() { + super(getRegexConcat()); + } + + private static IRegex getRegexConcat() { + return RegexConcat.build(CommandCreateJsonSingleLine.class.getName(), RegexLeaf.start(), // + new RegexLeaf("TYPE", "json"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("NAME", "(?:[%g]([^%g]+)[%g][%s]+as[%s]+)?([%pLN_.]+)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), // + RegexLeaf.spaceZeroOrMore(), // + ColorParser.exp1(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("DATA", "(\\{.*\\})"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(AbstractClassOrObjectDiagram diagram, LineLocation location, + RegexResult arg) throws NoSuchColorException { + final String name = arg.get("NAME", 1); + final String data = arg.get("DATA", 0); + final IEntity entity1 = executeArg0(diagram, arg); + if (entity1 == null) + return CommandExecutionResult.error("No such entity"); + + final JsonValue json = getJsonValue(data); + + if (json == null) + return CommandExecutionResult.error("Bad data"); + ((BodierJSon) entity1.getBodier()).setJson(json); + + return CommandExecutionResult.ok(); + } + + private JsonValue getJsonValue(String data) { + try { + final DefaultHandler handler = new DefaultHandler(); + new JsonParser(handler).parse(data); + final JsonValue json = handler.getValue(); + return json; + } catch (Exception e) { + return null; + } + } + + private IEntity executeArg0(AbstractClassOrObjectDiagram diagram, RegexResult line0) throws NoSuchColorException { + final String name = line0.get("NAME", 1); + final Ident ident = diagram.buildLeafIdent(name); + final Code code = diagram.V1972() ? ident : diagram.buildCode(name); + final String display = line0.get("NAME", 0); + final String stereotype = line0.get("STEREO", 0); + final boolean leafExist = diagram.V1972() ? diagram.leafExistSmart(ident) : diagram.leafExist(code); + if (leafExist) + return diagram.getOrCreateLeaf(diagram.buildLeafIdent(name), code, LeafType.JSON, null); + + final IEntity entity = diagram.createLeaf(ident, code, Display.getWithNewlines(display), LeafType.JSON, null); + if (stereotype != null) + entity.setStereotype(Stereotype.build(stereotype, diagram.getSkinParam().getCircledCharacterRadius(), + diagram.getSkinParam().getFont(null, false, FontParam.CIRCLED_CHARACTER), + diagram.getSkinParam().getIHtmlColorSet())); + + final String s = line0.get("COLOR", 0); + entity.setSpecificColorTOBEREMOVED(ColorType.BACK, s == null ? null + : diagram.getSkinParam().getIHtmlColorSet().getColor(diagram.getSkinParam().getThemeStyle(), s)); + return entity; + } + +} diff --git a/src/net/sourceforge/plantuml/picoweb/PicoWebServer.java b/src/net/sourceforge/plantuml/picoweb/PicoWebServer.java index ad26691e3..cb61ea766 100644 --- a/src/net/sourceforge/plantuml/picoweb/PicoWebServer.java +++ b/src/net/sourceforge/plantuml/picoweb/PicoWebServer.java @@ -80,7 +80,6 @@ import net.sourceforge.plantuml.version.Version; public class PicoWebServer implements Runnable { private final Socket connect; - private static final AtomicBoolean stopRequested = new AtomicBoolean(false); private static boolean enableStop; public PicoWebServer(Socket c) { @@ -91,7 +90,8 @@ public class PicoWebServer implements Runnable { startServer(8080, null, false); } - public static void startServer(final int port, final String bindAddress, final boolean argEnableStop) throws IOException { + public static void startServer(final int port, final String bindAddress, final boolean argEnableStop) + throws IOException { PicoWebServer.enableStop = argEnableStop; final InetAddress bindAddress1 = bindAddress == null ? null : InetAddress.getByName(bindAddress); final ServerSocket serverConnect = new ServerSocket(port, 50, bindAddress1); @@ -100,7 +100,7 @@ public class PicoWebServer implements Runnable { } public static void serverLoop(final ServerSocket serverConnect) throws IOException { - while (stopRequested.get() == false) { + while (true) { final PicoWebServer myServer = new PicoWebServer(serverConnect.accept()); final Thread thread = new Thread(myServer); thread.start(); @@ -137,10 +137,10 @@ public class PicoWebServer implements Runnable { return; if (request.getPath().startsWith("/plantuml/serverinfo") && handleInfo(out)) return; - if (enableStop && request.getPath().startsWith("/stopserver")) { - stopRequested.set(true); + if (enableStop && (request.getPath().startsWith("/stopserver") + || request.getPath().startsWith("/plantuml/stopserver")) && handleStop(out)) return; - } + } else if (request.getMethod().equals("POST") && request.getPath().equals("/render")) { handleRenderRequest(request, out); return; @@ -167,6 +167,32 @@ public class PicoWebServer implements Runnable { } } + private boolean handleStop(BufferedOutputStream out) throws IOException { + write(out, "HTTP/1.1 " + "200"); + write(out, "Cache-Control: no-cache"); + write(out, "Server: PlantUML PicoWebServer " + Version.versionString()); + write(out, "Date: " + new Date()); + write(out, ""); + + write(out, "Stoping..."); + + out.flush(); + + final Thread stop = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(3000L); + } catch (InterruptedException e) { + } + System.exit(0); + } + }); + stop.start(); + + return true; + } + private boolean handleInfo(BufferedOutputStream out) throws IOException { write(out, "HTTP/1.1 " + "200"); write(out, "Cache-Control: no-cache"); diff --git a/src/net/sourceforge/plantuml/posimo/DotPath.java b/src/net/sourceforge/plantuml/posimo/DotPath.java index 450f8c19f..8a89b862a 100644 --- a/src/net/sourceforge/plantuml/posimo/DotPath.java +++ b/src/net/sourceforge/plantuml/posimo/DotPath.java @@ -240,6 +240,14 @@ public class DotPath implements UShape, Moveable { beziers.get(0).ctrlx1 = x; beziers.get(0).ctrly1 = y; } + + public void moveStartPoint(double dx, double dy) { + beziers.get(0).x1 += dx; + beziers.get(0).y1 += dy; + beziers.get(0).ctrlx1 += dx; + beziers.get(0).ctrly1 += dy; + } + public Point2D getEndPoint() { return beziers.get(beziers.size() - 1).getP2(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index 94783291f..de0e7ec5a 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -162,7 +162,7 @@ public class SequenceDiagram extends UmlDiagram { return participantsget(code) != null; } - public String addMessage(AbstractMessage m) { + public CommandExecutionResult addMessage(AbstractMessage m) { if (m.isParallel()) m.setParallelBrother(getLastAbstractMessage()); @@ -171,12 +171,13 @@ public class SequenceDiagram extends UmlDiagram { events.add(m); if (pendingCreate != null) { if (m.compatibleForCreate(pendingCreate.getParticipant()) == false) - return "After create command, you have to send a message to \"" + pendingCreate.getParticipant() + "\""; + return CommandExecutionResult.error("After create command, you have to send a message to \"" + + pendingCreate.getParticipant() + "\""); m.addLifeEvent(pendingCreate); pendingCreate = null; } - return null; + return CommandExecutionResult.ok(); } private AbstractMessage getLastAbstractMessage() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java index 8e8ccb680..6ba4b34e5 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -320,9 +320,9 @@ public class CommandArrow extends SingleLineCommand2 { msg.setPart1Anchor(arg.get("PART1ANCHOR", 1)); msg.setPart2Anchor(arg.get("PART2ANCHOR", 1)); - final String error = diagram.addMessage(msg); - if (error != null) - return CommandExecutionResult.error(error); + final CommandExecutionResult status = diagram.addMessage(msg); + if (status.isOk() == false) + return status; final String s = arg.get("LIFECOLOR", 0); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java index c1213b105..d31b73d57 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -149,9 +149,9 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { msg.setPart1Anchor(arg.get("PART1ANCHOR", 1)); msg.setPart2Anchor(arg.get("PART2ANCHOR", 1)); - final String error = diagram.addMessage(msg); - if (error != null) - return CommandExecutionResult.error(error); + final CommandExecutionResult status = diagram.addMessage(msg); + if (status.isOk() == false) + return status; final String s = arg.get("LIFECOLOR", 0); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java index 49438cd45..d57860938 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java @@ -83,18 +83,17 @@ public class CommandReturn extends SingleLineCommand2 { boolean doDeactivation = true; if (message1 == null) { final EventWithDeactivate last = diagram.getLastEventWithDeactivate(); - if (last instanceof Message == false) { + if (last instanceof Message == false) return CommandExecutionResult.error("Nowhere to return to."); - } + message1 = (Message) last; doDeactivation = false; } ArrowConfiguration arrow = message1.getArrowConfiguration().withBody(ArrowBody.DOTTED); final String color = arg.get("COLOR", 0); - if (color != null) { + if (color != null) arrow = arrow.withColor(HColorSet.instance().getColor(diagram.getSkinParam().getThemeStyle(), color)); - } final Display display = Display.getWithNewlines(arg.get("MESSAGE", 0)); final AbstractMessage message2; @@ -106,17 +105,19 @@ public class CommandReturn extends SingleLineCommand2 { message2 = new Message(diagram.getSkinParam().getCurrentStyleBuilder(), message1.getParticipant2(), message1.getParticipant1(), display, arrow, diagram.getNextMessageNumber()); final boolean parallel = arg.get("PARALLEL", 0) != null; - if (parallel) { + if (parallel) message2.goParallel(); - } + } - diagram.addMessage(message2); + final CommandExecutionResult status = diagram.addMessage(message2); + if (status.isOk() == false) + return status; if (doDeactivation) { final String error = diagram.activate(message1.getParticipant2(), LifeEventType.DEACTIVATE, null); - if (error != null) { + if (error != null) return CommandExecutionResult.error(error); - } + } return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java index 787ba637a..a46d9d723 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java @@ -245,7 +245,7 @@ public class GroupingTile extends AbstractTile { tiles = removeEmptyCloseToParallel(tiles); final List result = new ArrayList<>(); for (Tile tile : tiles) { - if (isParallel(tile)) { + if (result.size() > 0 && isParallel(tile)) { if (pending == null) { pending = new TileParallel(stringBounder); final Tile tmp = result.get(result.size() - 1); diff --git a/src/net/sourceforge/plantuml/svek/Bibliotekon.java b/src/net/sourceforge/plantuml/svek/Bibliotekon.java index 4d2f4a03f..92e2804bd 100644 --- a/src/net/sourceforge/plantuml/svek/Bibliotekon.java +++ b/src/net/sourceforge/plantuml/svek/Bibliotekon.java @@ -59,18 +59,18 @@ public class Bibliotekon { private final List lines1 = new ArrayList<>(); private final List allLines = new ArrayList<>(); - public SvekNode createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { + public SvekNode createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, + StringBounder stringBounder) { final SvekNode node = new SvekNode(ent, image, colorSequence, stringBounder); nodeMap.put(ent, node); return node; } public Cluster getCluster(IGroup ent) { - for (Cluster cl : allCluster) { - if (cl.getGroups().contains(ent)) { + for (Cluster cl : allCluster) + if (cl.getGroups().contains(ent)) return cl; - } - } + return null; } @@ -97,9 +97,9 @@ public class Bibliotekon { private static boolean first(SvekLine line) { final int length = line.getLength(); - if (length == 1) { + if (length == 1) return true; - } + return false; } @@ -115,18 +115,16 @@ public class Bibliotekon { final SvekNode result = getNode(ent); if (result != null) { String uid = result.getUid(); - if (result.isShielded()) { + if (result.isShielded()) uid = uid + ":h"; - } + return uid; } assert result == null; if (ent.isGroup()) { - for (IEntity i : nodeMap.keySet()) { - if (ent.getCodeGetName().equals(i.getCodeGetName())) { + for (IEntity i : nodeMap.keySet()) + if (ent.getCodeGetName().equals(i.getCodeGetName())) return getNode(i).getUid(); - } - } return Cluster.getSpecialPointId(ent); } throw new IllegalStateException(); @@ -180,39 +178,36 @@ public class Bibliotekon { public List getAllLineConnectedTo(IEntity leaf) { final List result = new ArrayList<>(); - for (SvekLine line : allLines) { - if (line.isLinkFromOrTo(leaf)) { + for (SvekLine line : allLines) + if (line.isLinkFromOrTo(leaf)) result.add(line); - } - } + return Collections.unmodifiableList(result); } public SvekLine getLine(Link link) { - for (SvekLine line : allLines) { - if (line.isLink(link)) { + for (SvekLine line : allLines) + if (line.isLink(link)) return line; - } - } + throw new IllegalArgumentException(); } public IEntity getOnlyOther(IEntity entity) { for (SvekLine line : allLines) { final IEntity other = line.getOther(entity); - if (other != null) { + if (other != null) return other; - } + } return null; } public ILeaf getLeaf(SvekNode node) { - for (Map.Entry ent : nodeMap.entrySet()) { - if (ent.getValue() == node) { + for (Map.Entry ent : nodeMap.entrySet()) + if (ent.getValue() == node) return ent.getKey(); - } - } + throw new IllegalArgumentException(); } } diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java index 3f7a677f9..b1d5dc516 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java @@ -76,7 +76,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { final DotData dotData = new DotData(diagram.getEntityFactory().getRootGroup(), getOrderedLinks(), diagram.getLeafsvalues(), diagram.getUmlDiagramType(), diagram.getSkinParam(), diagram, diagram, diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), dotMode, - diagram.getNamespaceSeparator(), diagram.getPragma(), diagram.getGraphvizVersion()); + diagram.getNamespaceSeparator(), diagram.getPragma()); final boolean intricated = diagram.mergeIntricated(); return new GeneralImageBuilder(intricated, dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder, diagram.getUmlDiagramType().getStyleName()); diff --git a/src/net/sourceforge/plantuml/svek/DotStringFactory.java b/src/net/sourceforge/plantuml/svek/DotStringFactory.java index 9822e860d..bf2d7cd5a 100644 --- a/src/net/sourceforge/plantuml/svek/DotStringFactory.java +++ b/src/net/sourceforge/plantuml/svek/DotStringFactory.java @@ -60,6 +60,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; import net.sourceforge.plantuml.cucadiagram.dot.Graphviz; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; +import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersions; import net.sourceforge.plantuml.cucadiagram.dot.ProcessState; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.graphic.StringBounder; @@ -86,8 +87,6 @@ public class DotStringFactory implements Moveable { private final StringBounder stringBounder; - private GraphvizVersion graphvizVersion; - public DotStringFactory(StringBounder stringBounder, DotData dotData) { this.skinParam = dotData.getSkinParam(); this.umlDiagramType = dotData.getUmlDiagramType(); @@ -97,7 +96,6 @@ public class DotStringFactory implements Moveable { this.stringBounder = stringBounder; this.root = new Cluster(colorSequence, skinParam, dotData.getRootGroup()); this.current = root; - this.graphvizVersion = dotData.getGraphvizVersion(); } public DotStringFactory(StringBounder stringBounder, CucaDiagram diagram) { @@ -109,7 +107,6 @@ public class DotStringFactory implements Moveable { this.stringBounder = stringBounder; this.root = new Cluster(colorSequence, skinParam, diagram.getEntityFactory().getRootGroup()); this.current = root; - this.graphvizVersion = diagram.getGraphvizVersion(); } public void addNode(SvekNode node) { @@ -215,14 +212,14 @@ public class DotStringFactory implements Moveable { root.printCluster1(sb, bibliotekon.allLines(), stringBounder); for (SvekLine line : bibliotekon.lines0()) - line.appendLine(graphvizVersion, sb, dotMode, dotSplines); + line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines); root.fillRankMin(rankMin); - root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, graphvizVersion, umlDiagramType); + root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType); printMinRanking(sb); for (SvekLine line : bibliotekon.lines1()) - line.appendLine(graphvizVersion, sb, dotMode, dotSplines); + line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines); SvekUtils.println(sb); sb.append("}"); @@ -281,6 +278,24 @@ public class DotStringFactory implements Moveable { return 35; } + private GraphvizVersion graphvizVersion; + + public GraphvizVersion getGraphvizVersion() { + if (graphvizVersion == null) + graphvizVersion = getGraphvizVersionInternal(); + + return graphvizVersion; + } + + private GraphvizVersion getGraphvizVersionInternal() { + final Graphviz graphviz = GraphvizUtils.create(skinParam, "foo;", "svg"); + if (graphviz instanceof GraphvizJs) + return GraphvizJs.getGraphvizVersion(false); + + final File f = graphviz.getDotExe(); + return GraphvizVersions.getInstance().getVersion(f); + } + public String getSvg(BaseFile basefile, String[] dotOptions) throws IOException { String dotString = createDotString(dotOptions); @@ -299,7 +314,7 @@ public class DotStringFactory implements Moveable { } } catch (GraphvizJsRuntimeException e) { System.err.println("GraphvizJsRuntimeException"); - this.graphvizVersion = GraphvizJs.getGraphvizVersion(true); + graphvizVersion = GraphvizJs.getGraphvizVersion(true); dotString = createDotString(dotOptions); graphviz = GraphvizUtils.create(skinParam, dotString, "svg"); baos = new ByteArrayOutputStream(); diff --git a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java index f9bd1c583..a34f5fb3e 100644 --- a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java +++ b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java @@ -155,8 +155,7 @@ public final class GeneralImageBuilder { throw new IllegalStateException(); if (leaf.getLeafType().isLikeClass()) { - final EntityImageClass entityImageClass = new EntityImageClass(graphvizVersion, (ILeaf) leaf, skinParam, - portionShower); + final EntityImageClass entityImageClass = new EntityImageClass((ILeaf) leaf, skinParam, portionShower); final Neighborhood neighborhood = leaf.getNeighborhood(); if (neighborhood != null) return new EntityImageProtected(entityImageClass, 20, neighborhood, bibliotekon); @@ -418,7 +417,7 @@ public final class GeneralImageBuilder { final FontConfiguration labelFont = getFontForLink(link, skinParam); final SvekLine line = new SvekLine(link, dotStringFactory.getColorSequence(), skinParam, stringBounder, - labelFont, dotStringFactory.getBibliotekon(), pragma); + labelFont, dotStringFactory.getBibliotekon(), pragma, dotStringFactory.getGraphvizVersion()); dotStringFactory.getBibliotekon().addLine(line); @@ -556,8 +555,8 @@ public final class GeneralImageBuilder { } return createEntityImageBlock(ent, skinParam, dotData.isHideEmptyDescriptionForState(), dotData, - dotStringFactory.getBibliotekon(), dotData.getGraphvizVersion(), dotData.getUmlDiagramType(), - dotData.getLinks()); + dotStringFactory.getBibliotekon(), dotStringFactory.getGraphvizVersion(), + dotData.getUmlDiagramType(), dotData.getLinks()); } return ent.getSvekImage(); } @@ -568,8 +567,7 @@ public final class GeneralImageBuilder { if (ent.getLeafType().isLikeClass() == false) continue; - final IEntityImage im = new EntityImageClass(dotData.getGraphvizVersion(), ent, dotData.getSkinParam(), - dotData); + final IEntityImage im = new EntityImageClass(ent, dotData.getSkinParam(), dotData); final double w = im.calculateDimension(stringBounder).getWidth(); if (w > result) result = w; diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java index a1d2b0ae8..6bba214b7 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java @@ -128,7 +128,7 @@ public final class GroupPngMakerActivity { final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(), skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(), false, - DotMode.NORMAL, diagram.getNamespaceSeparator(), diagram.getPragma(), diagram.getGraphvizVersion()); + DotMode.NORMAL, diagram.getNamespaceSeparator(), diagram.getPragma()); final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder, SName.activityDiagram); diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java index 7d97ab0aa..0ed1ab132 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java @@ -151,7 +151,7 @@ public final class GroupPngMakerState { final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(), skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), DotMode.NORMAL, diagram.getNamespaceSeparator(), - diagram.getPragma(), diagram.getGraphvizVersion()); + diagram.getPragma()); final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder, SName.stateDiagram); diff --git a/src/net/sourceforge/plantuml/svek/Kal.java b/src/net/sourceforge/plantuml/svek/Kal.java new file mode 100644 index 000000000..f6788c922 --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/Kal.java @@ -0,0 +1,174 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * 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. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.svek; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.awt.geom.Dimension2D; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.ugraphic.color.HColors; + +public class Kal implements UDrawable { + + private final TextBlock textBlock; + private final Direction position; + private Dimension2D dim; + private UTranslate translate; + private final SvekLine svekLine; + private final EntityImpl entity; + private final Link link; + + public Kal(SvekLine svekLine, String text, FontConfiguration font, ISkinParam skinParam, EntityImpl entity, + Link link, StringBounder stringBounder) { + this.svekLine = svekLine; + this.entity = entity; + this.link = link; + this.textBlock = Display.getWithNewlines(text).create7(font, HorizontalAlignment.LEFT, skinParam, + CreoleMode.SIMPLE_LINE); + this.dim = Dimension2DDouble.delta(this.textBlock.calculateDimension(stringBounder), 4, 2); + + if (link.getLength() == 1 && link.getEntity1() == entity) { + this.position = Direction.RIGHT; + entity.ensureMargins(new Margins(0, dim.getWidth(), 0, 0)); + + } else if (link.getLength() == 1 && link.getEntity2() == entity) { + this.position = Direction.LEFT; + entity.ensureMargins(new Margins(dim.getWidth(), 0, 0, 0)); + + } else if (link.getEntity1() == entity) { + this.position = Direction.DOWN; + entity.ensureMargins(new Margins(0, 0, dim.getHeight(), 0)); + + } else if (link.getEntity2() == entity) { + this.position = Direction.UP; + entity.ensureMargins(new Margins(0, 0, 0, dim.getHeight())); + + } else { + throw new IllegalStateException(); + } + + entity.addKal(this); + + } + + public Dimension2D getDimension() { + return dim; + } + + @Override + public void drawU(UGraphic ug) { + final URectangle rect = new URectangle(dim); + ug = ug.apply(getTranslate()); + ug.apply(HColors.WHITE.bg()).apply(HColors.BLACK).apply(new UStroke(0.5)).draw(rect); + textBlock.drawU(ug.apply(new UTranslate(2, 1))); + } + + private UTranslate getTranslate() { + return getTextDelta().compose(translate); + + } + + public double getX1() { + return getTranslate().getDx() - 5; + } + + public double getX2() { + return getX1() + dim.getWidth() + 10; + } + + private UTranslate getTextDelta() { + switch (position) { + case RIGHT: + return UTranslate.dy(-dim.getHeight() / 2); + case LEFT: + return new UTranslate(-dim.getWidth() + 0.5, -dim.getHeight() / 2); + case DOWN: + return UTranslate.dx(-dim.getWidth() / 2); + case UP: + return new UTranslate(-dim.getWidth() / 2, -dim.getHeight() + 0.5); + default: + throw new IllegalStateException(); + } + + } + + public final Direction getPosition() { + return position; + } + + public void setTranslate(UTranslate translate) { + this.translate = translate; + } + + public double overlapx(Kal other) { + if (this.position != other.position) + throw new IllegalArgumentException(); + if (other.getX1() >= this.getX1() && other.getX1() <= this.getX2()) + return this.getX2() - other.getX1(); + if (other.getX2() >= this.getX1() && other.getX2() <= this.getX2()) + return this.getX1() - other.getX2(); + + if (this.getX1() >= other.getX1() && this.getX1() <= other.getX2()) + return other.getX2() - this.getX1(); + if (this.getX2() >= other.getX1() && this.getX2() <= other.getX2()) + return other.getX1() - this.getX2(); + + return 0; + } + + public void moveX(double dx) { + if (dx == 0) + return; + this.translate = this.translate.compose(UTranslate.dx(dx)); + if (link.getEntity1() == entity) + svekLine.moveStartPoint(dx, 0); + + } + +} diff --git a/src/net/sourceforge/plantuml/svek/LineOfSegments.java b/src/net/sourceforge/plantuml/svek/LineOfSegments.java new file mode 100644 index 000000000..3dae11817 --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/LineOfSegments.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * 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. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.svek; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class LineOfSegments { + + static private class Segment implements Comparable { + private final int idx; + private double middle; + private final double halfSize; + + private Segment(int idx, double x1, double x2) { + this.idx = idx; + this.middle = (x1 + x2) / 2; + this.halfSize = (x2 - x1) / 2; + } + + @Override + public int compareTo(Segment other) { + return Double.compare(this.middle, other.middle); + } + + private double overlap(Segment other) { + final double distance = other.middle - this.middle; + if (distance < 0) + throw new IllegalArgumentException(); + final double diff = distance - this.halfSize - other.halfSize; + if (diff > 0) + return 0; + return -diff; + } + + private void push(double delta) { + middle += delta; + } + } + + private final List all = new ArrayList<>(); + + public void addSegment(double x1, double x2) { + all.add(new Segment(all.size(), x1, x2)); + } + + public double getMean() { + double sum = 0; + for (Segment seg : all) + sum += seg.middle; + + return sum / all.size(); + } + + void solveOverlapsInternal() { + if (all.size() < 2) + return; + Collections.sort(all); + for (int i = 0; i < all.size(); i++) + if (oneLoop() == false) + return; + } + + private boolean oneLoop() { + for (int i = all.size() - 2; i >= 0; i--) { + final Segment seg1 = all.get(i); + final Segment seg2 = all.get(i + 1); + final double overlap = seg1.overlap(seg2); + if (overlap > 0) { + for (int k = i + 1; k < all.size(); k++) + all.get(k).push(overlap); + return true; + } + } + return false; + + } + + public double[] solveOverlaps() { + final double mean1 = getMean(); + solveOverlapsInternal(); + final double mean2 = getMean(); + final double diff = mean1 - mean2; + if (diff != 0) + for (Segment seg : all) + seg.push(diff); + final double[] result = new double[all.size()]; + for (Segment seg : all) + result[seg.idx] = seg.middle - seg.halfSize; + return result; + + } + +} diff --git a/src/net/sourceforge/plantuml/svek/SvekLine.java b/src/net/sourceforge/plantuml/svek/SvekLine.java index 8b17b0265..27fa06880 100644 --- a/src/net/sourceforge/plantuml/svek/SvekLine.java +++ b/src/net/sourceforge/plantuml/svek/SvekLine.java @@ -73,6 +73,7 @@ import net.sourceforge.plantuml.cucadiagram.NoteLinkStrategy; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; +import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; import net.sourceforge.plantuml.descdiagram.command.StringWithArrow; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -211,7 +212,21 @@ public class SvekLine implements Moveable, Hideable, GuideLine { } public SvekLine(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder, - FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma) { + FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma, GraphvizVersion graphvizVersion) { + + if (graphvizVersion.useShieldForQuantifier() && link.getLinkArg().getQualifier1() != null) + ((EntityImpl) link.getEntity1()).ensureMargins(Margins.uniform(16)); + + if (graphvizVersion.useShieldForQuantifier() && link.getLinkArg().getQualifier2() != null) + ((EntityImpl) link.getEntity2()).ensureMargins(Margins.uniform(16)); + + if (link.getLinkArg().getKal1() != null) + this.kal1 = new Kal(this, link.getLinkArg().getKal1(), font, skinParam, (EntityImpl) link.getEntity1(), + link, stringBounder); + + if (link.getLinkArg().getKal2() != null) + this.kal2 = new Kal(this, link.getLinkArg().getKal2(), font, skinParam, (EntityImpl) link.getEntity2(), + link, stringBounder); this.link = Objects.requireNonNull(link); this.skinParam = skinParam; @@ -308,15 +323,10 @@ public class SvekLine implements Moveable, Hideable, GuideLine { else this.labelShield = 7; - if (link.getLinkArg().getKal1() != null) { - this.kal1 = Display.getWithNewlines(link.getLinkArg().getKal1()).create7(font, HorizontalAlignment.LEFT, - skinParam, CreoleMode.SIMPLE_LINE); - - } - } - private TextBlock kal1; + private Kal kal1; + private Kal kal2; private TextBlock addVisibilityModifier(TextBlock block, Link link, ISkinParam skinParam) { final VisibilityModifier visibilityModifier = link.getVisibilityModifier(); @@ -766,19 +776,20 @@ public class SvekLine implements Moveable, Hideable, GuideLine { link.getLinkConstraint().drawMe(ug, skinParam); } - if (kal1 != null) { - final Dimension2D dim1 = kal1.calculateDimension(stringBounder); - final URectangle rect = new URectangle(dim1); - final UTranslate tr = new UTranslate(dotPath.getStartPoint()).compose(new UTranslate(dx, dy)) - .compose(UTranslate.dx(-dim1.getWidth() / 2)); - final UGraphic ug1 = ug.apply(tr); - ug1.apply(HColors.WHITE.bg()).draw(rect); - kal1.drawU(ug1); - } - ug.closeGroup(); } + public void computeKal() { + if (kal1 != null) { + final UTranslate tr = new UTranslate(dotPath.getStartPoint()).compose(new UTranslate(dx, dy)); + kal1.setTranslate(tr); + } + if (kal2 != null) { + final UTranslate tr = new UTranslate(dotPath.getEndPoint()).compose(new UTranslate(dx, dy)); + kal2.setTranslate(tr); + } + } + private List getSquare(double x, double y) { final List result = new ArrayList<>(); result.add(new Point2D.Double(x, y)); @@ -1053,4 +1064,12 @@ public class SvekLine implements Moveable, Hideable, GuideLine { return link.getStereotype(); } + public void moveStartPoint(double dx, double dy) { + dotPath.moveStartPoint(dx, dy); + } + + public void moveEndPoint(double dx, double dy) { + dotPath.moveEndPoint(dx, dy); + } + } diff --git a/src/net/sourceforge/plantuml/svek/SvekNode.java b/src/net/sourceforge/plantuml/svek/SvekNode.java index 31e932768..c49827f5e 100644 --- a/src/net/sourceforge/plantuml/svek/SvekNode.java +++ b/src/net/sourceforge/plantuml/svek/SvekNode.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.svek; import java.awt.geom.Point2D; import java.util.List; -import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.Hideable; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.awt.geom.Dimension2D; @@ -52,23 +52,24 @@ import net.sourceforge.plantuml.svek.image.AbstractEntityImageBorder; import net.sourceforge.plantuml.svek.image.EntityImageDescription; import net.sourceforge.plantuml.svek.image.EntityImageLollipopInterface; import net.sourceforge.plantuml.ugraphic.Shadowable; +import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UPolygon; public class SvekNode implements Positionable, IShapePseudo, Hideable { private final ShapeType type; - private final double width; - private final double height; + private Dimension2D dimImage; private final String uid; private final int color; private double minX; private double minY; - private final Margins shield; + private Margins shield; private final EntityPosition entityPosition; private final IEntityImage image; + private final StringBounder stringBounder; public EntityPosition getEntityPosition() { return entityPosition; @@ -95,19 +96,14 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { private final IGroup group; SvekNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { - final Dimension2D dim = image.calculateDimension(stringBounder); + this.stringBounder = stringBounder; this.entityPosition = ent.getEntityPosition(); this.image = image; this.top = ent.isTop(); this.type = image.getShapeType(); - this.width = dim.getWidth(); - this.height = dim.getHeight(); + this.color = colorSequence.getValue(); this.uid = String.format("sh%04d", color); - this.shield = image.getShield(stringBounder); - if (shield.isZero() == false && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS - && type != ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE) - throw new IllegalArgumentException(); if (((EntityImpl) ent).getOriginalGroup() == null) { this.group = null; @@ -118,16 +114,22 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { } } + private Dimension2D getDimImage() { + if (dimImage == null) + this.dimImage = image.calculateDimension(stringBounder); + return dimImage; + } + public final ShapeType getType() { return type; } public final double getWidth() { - return width; + return getDimImage().getWidth(); } public final double getHeight() { - return height; + return getDimImage().getHeight(); } public void appendShape(StringBuilder sb, StringBounder stringBounder) { @@ -139,7 +141,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { appendHtml(sb); return; } - if (type == ShapeType.RECTANGLE && shield.isZero() == false) { + if (type == ShapeType.RECTANGLE && shield().isZero() == false) { appendHtml(sb); return; } @@ -158,6 +160,17 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { SvekUtils.println(sb); } + private Margins shield() { + if (shield == null) { + this.shield = image.getShield(stringBounder); + if (shield.isZero() == false && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS + && type != ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE) + throw new IllegalStateException(); + } + + return shield; + } + private void appendHtml(StringBuilder sb) { sb.append(uid); sb.append(" ["); @@ -175,20 +188,20 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { sb.append(""); sb.append(""); appendTd(sb); - appendTd(sb, 1, shield.getY1()); + appendTd(sb, 1, shield().getY1()); appendTd(sb); sb.append(""); sb.append(""); - appendTd(sb, shield.getX1(), 1); + appendTd(sb, shield().getX1(), 1); sb.append(""); - appendTd(sb, shield.getX2(), 1); + appendTd(sb, shield().getX2(), 1); sb.append(""); sb.append(""); appendTd(sb); - appendTd(sb, 1, shield.getY2()); + appendTd(sb, 1, shield().getY2()); appendTd(sb); sb.append(""); sb.append("
"); sb.append("
"); @@ -247,7 +260,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { } private void appendShapeInternal(StringBuilder sb) { - if (type == ShapeType.RECTANGLE && shield.isZero() == false) + if (type == ShapeType.RECTANGLE && shield().isZero() == false) throw new UnsupportedOperationException(); else if (type == ShapeType.RECTANGLE || type == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE || type == ShapeType.FOLDER) @@ -301,15 +314,15 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { } public Dimension2D getSize() { - return new Dimension2DDouble(width, height); + return getDimImage(); } public ClusterPosition getClusterPosition() { - return new ClusterPosition(minX, minY, minX + width, minY + height); + return new ClusterPosition(minX, minY, minX + getWidth(), minY + getHeight()); } public boolean isShielded() { - return shield.isZero() == false; + return shield().isZero() == false; } public void moveSvek(double deltaX, double deltaY) { @@ -349,7 +362,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { if (getType() != ShapeType.FOLDER) return pt; - final ClusterPosition clusterPosition = new ClusterPosition(minX, minY, minX + width, minY + height); + final ClusterPosition clusterPosition = new ClusterPosition(minX, minY, minX + getWidth(), minY + getHeight()); if (clusterPosition.isPointJustUpper(pt)) { final Dimension2D dimName = ((EntityImageDescription) image).getNameDimension(stringBounder); if (pt.getX() < minX + dimName.getWidth()) @@ -367,4 +380,41 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable { public void addImpact(double angle) { ((EntityImageLollipopInterface) image).addImpact(angle); } + + public void drawKals(UGraphic ug) { + if (leaf instanceof EntityImpl == false) + return; + + drawList(ug, ((EntityImpl) leaf).getKals(Direction.DOWN)); + drawList(ug, ((EntityImpl) leaf).getKals(Direction.UP)); + drawList(ug, ((EntityImpl) leaf).getKals(Direction.LEFT)); + drawList(ug, ((EntityImpl) leaf).getKals(Direction.RIGHT)); + + } + + public void fixOverlap() { + if (leaf instanceof EntityImpl == false) + return; + + fixHoverlap(((EntityImpl) leaf).getKals(Direction.DOWN)); + fixHoverlap(((EntityImpl) leaf).getKals(Direction.UP)); + } + + private void fixHoverlap(final List list) { + final LineOfSegments los = new LineOfSegments(); + for (Kal kal : list) + los.addSegment(kal.getX1(), kal.getX2()); + + final double[] res = los.solveOverlaps(); + for (int i = 0; i < list.size(); i++) { + final Kal kal = list.get(i); + final double diff = res[i] - kal.getX1(); + kal.moveX(diff); + } + } + + private void drawList(UGraphic ug, final List list) { + for (Kal kal : list) + kal.drawU(ug); + } } diff --git a/src/net/sourceforge/plantuml/svek/SvekResult.java b/src/net/sourceforge/plantuml/svek/SvekResult.java index 8d1d27171..dd79c0f05 100644 --- a/src/net/sourceforge/plantuml/svek/SvekResult.java +++ b/src/net/sourceforge/plantuml/svek/SvekResult.java @@ -93,6 +93,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage final Set ids = new HashSet<>(); + computeKal(); + for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) { final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; @@ -105,6 +107,16 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage line.drawU(ug2, styleLine.getStroke(), color, ids); } + for (SvekNode node : dotStringFactory.getBibliotekon().allNodes()) + node.drawKals(ug); + + } + + private void computeKal() { + for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) + line.computeKal(); + for (SvekNode node : dotStringFactory.getBibliotekon().allNodes()) + node.fixOverlap(); } private StyleSignature getDefaultStyleDefinition(Stereotype stereotype) { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java index 787c1107d..246e4d886 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java @@ -40,6 +40,7 @@ import java.util.EnumMap; import java.util.Map; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineConfigurable; @@ -50,7 +51,7 @@ import net.sourceforge.plantuml.cucadiagram.EntityPortion; import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.PortionShower; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; +import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; @@ -60,6 +61,7 @@ import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.Kal; import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.Ports; import net.sourceforge.plantuml.svek.ShapeType; @@ -78,8 +80,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColors; public class EntityImageClass extends AbstractEntityImage implements Stencil, WithPorts { final private TextBlock body; - // final private Margins shield; - final private GraphvizVersion version; + final private EntityImageClassHeader header; final private Url url; final private double roundCorner; @@ -87,13 +88,12 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi final private LineConfigurable lineConfig; - public EntityImageClass(GraphvizVersion version, ILeaf entity, ISkinParam skinParam, PortionShower portionShower) { + public EntityImageClass(ILeaf entity, ISkinParam skinParam, PortionShower portionShower) { super(entity, entity.getColors().mute(skinParam)); this.leafType = entity.getLeafType(); this.lineConfig = entity; this.roundCorner = getStyle().value(PName.RoundCorner).asDouble(); - this.version = version; final boolean showMethods = portionShower.showPortion(EntityPortion.METHOD, entity); final boolean showFields = portionShower.showPortion(EntityPortion.FIELD, entity); @@ -112,7 +112,21 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi width = getSkinParam().minClassWidth(); final double height = dimBody.getHeight() + dimHeader.getHeight(); - return new Dimension2DDouble(width, height); + return new Dimension2DDouble(Math.max(width, getKalWidth() * 1.3), height); + // return new Dimension2DDouble(width + getKalWidth(), height); + } + + private double getKalWidth() { + double widthUp = 0; + double widthDown = 0; + for (Kal kal : ((EntityImpl) getEntity()).getKals(Direction.UP)) + widthUp += kal.getDimension().getWidth(); + + for (Kal kal : ((EntityImpl) getEntity()).getKals(Direction.DOWN)) + widthDown += kal.getDimension().getWidth(); + + return Math.max(widthUp, widthDown); + } @Override @@ -241,10 +255,7 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi @Override public Margins getShield(StringBounder stringBounder) { - if (version != null && version.useShield()) - return ((ILeaf) getEntity()).getMargins(); - - return Margins.NONE; + return ((ILeaf) getEntity()).getMargins(); } public double getStartingX(StringBounder stringBounder, double y) { diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index ee6084f7f..54248da1d 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -186,7 +186,7 @@ public class TContext { functionsSet.addFunction(new Dec2hex()); functionsSet.addFunction(new HslColor()); functionsSet.addFunction(new LoadJson()); - functionsSet.addFunction(new LoadJsonLegacy()); + // functionsSet.addFunction(new LoadJsonLegacy()); functionsSet.addFunction(new Chr()); functionsSet.addFunction(new Size()); functionsSet.addFunction(new GetJsonKey()); diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 7aa49affb..21ed7c2e5 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -81,7 +81,7 @@ public class Version { } public static int beta() { - final int beta = 1; + final int beta = 2; return beta; } diff --git a/src/net/sourceforge/plantuml/vizjs/GraphvizJs.java b/src/net/sourceforge/plantuml/vizjs/GraphvizJs.java index 2f5fd69f5..90961383d 100644 --- a/src/net/sourceforge/plantuml/vizjs/GraphvizJs.java +++ b/src/net/sourceforge/plantuml/vizjs/GraphvizJs.java @@ -122,7 +122,7 @@ public class GraphvizJs implements Graphviz { public static GraphvizVersion getGraphvizVersion(final boolean modeSafe) { return new GraphvizVersion() { - public boolean useShield() { + public boolean useShieldForQuantifier() { return true; } diff --git a/src/net/sourceforge/plantuml/picoweb/PicoWebServerTest.java b/test/net/sourceforge/plantuml/picoweb/PicoWebServerTest.java similarity index 100% rename from src/net/sourceforge/plantuml/picoweb/PicoWebServerTest.java rename to test/net/sourceforge/plantuml/picoweb/PicoWebServerTest.java