1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00
This commit is contained in:
Arnaud Roques 2022-08-26 18:00:28 +02:00
parent 7c576ed4ac
commit 6809546c65
39 changed files with 751 additions and 191 deletions

View File

@ -87,9 +87,9 @@ public class Dimension2DDouble extends Dimension2D {
} }
public static Dimension2D delta(Dimension2D dim, double deltaWidth, double deltaHeight) { public static Dimension2D delta(Dimension2D dim, double deltaWidth, double deltaHeight) {
if (deltaHeight == 0 && deltaWidth == 0) { if (deltaHeight == 0 && deltaWidth == 0)
return dim; return dim;
}
return new Dimension2DDouble(dim.getWidth() + deltaWidth, dim.getHeight() + deltaHeight); 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) { public static Dimension2D atLeast(Dimension2D dim, double minWidth, double minHeight) {
double h = dim.getHeight(); double h = dim.getHeight();
double w = dim.getWidth(); double w = dim.getWidth();
if (w > minWidth && h > minHeight) { if (w > minWidth && h > minHeight)
return dim; return dim;
}
if (h < minHeight) { if (h < minHeight)
h = minHeight; h = minHeight;
}
if (w < minWidth) { if (w < minWidth)
w = minWidth; w = minWidth;
}
return new Dimension2DDouble(w, h); return new Dimension2DDouble(w, h);
} }

View File

@ -212,7 +212,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
} }
private TextBlock getEntityImageClass(ILeaf entity) { private TextBlock getEntityImageClass(ILeaf entity) {
return new EntityImageClass(null, entity, getSkinParam(), this); return new EntityImageClass(entity, getSkinParam(), this);
} }
@Override @Override

View File

@ -81,6 +81,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap;
public class ClassDiagramFactory extends PSystemCommandFactory { public class ClassDiagramFactory extends PSystemCommandFactory {
@ -108,6 +109,7 @@ public class ClassDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandCreateEntityObjectMultilines()); cmds.add(new CommandCreateEntityObjectMultilines());
cmds.add(new CommandCreateMap()); cmds.add(new CommandCreateMap());
cmds.add(new CommandCreateJson()); cmds.add(new CommandCreateJson());
cmds.add(new CommandCreateJsonSingleLine());
cmds.add(new CommandCreateClass()); cmds.add(new CommandCreateClass());
cmds.add(new CommandCreateEntityObject()); cmds.add(new CommandCreateEntityObject());

View File

@ -80,7 +80,7 @@ public class CommandCreateClass extends SingleLineCommand2<ClassDiagram> {
private static IRegex getRegexConcat() { private static IRegex getRegexConcat() {
return RegexConcat.build(CommandCreateClass.class.getName(), RegexLeaf.start(), // return RegexConcat.build(CommandCreateClass.class.getName(), RegexLeaf.start(), //
new RegexLeaf("TYPE", // 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(), // RegexLeaf.spaceOneOrMore(), //
new RegexOr(// new RegexOr(//
new RegexConcat(// new RegexConcat(//

View File

@ -94,7 +94,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2<ClassDiagra
return RegexConcat.build(CommandCreateClassMultilines.class.getName(), RegexLeaf.start(), // return RegexConcat.build(CommandCreateClassMultilines.class.getName(), RegexLeaf.start(), //
new RegexLeaf("VISIBILITY", "(" + VisibilityModifier.regexForVisibilityCharacterInClassName() + ")?"), // new RegexLeaf("VISIBILITY", "(" + VisibilityModifier.regexForVisibilityCharacterInClassName() + ")?"), //
new RegexLeaf("TYPE", new RegexLeaf("TYPE",
"(interface|enum|annotation|abstract[%s]+class|abstract|class|entity|protocol|struct|exception)"), // "(interface|enum|annotation|abstract[%s]+class|static[%s]+class|abstract|class|entity|protocol|struct|exception)"), //
RegexLeaf.spaceOneOrMore(), // RegexLeaf.spaceOneOrMore(), //
new RegexOr(// new RegexOr(//
new RegexConcat(// new RegexConcat(//

View File

@ -233,11 +233,12 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
final Labels labels = new Labels(arg); final Labels labels = new Labels(arg);
final String kal1 = arg.get("QUALIFIER1", 0); final String kal1 = arg.get("QUALIFIER1", 0);
final String kal2 = arg.get("QUALIFIER2", 0);
final LinkArg linkArg = LinkArg final LinkArg linkArg = LinkArg
.build(labels.getDisplay(), queue, diagram.getSkinParam().classAttributeIconSize() > 0) .build(labels.getDisplay(), queue, diagram.getSkinParam().classAttributeIconSize() > 0)
.withQualifier(labels.getFirstLabel(), labels.getSecondLabel()) .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); Link link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, cl2, linkType, linkArg);
if (arg.get("URL", 0) != null) { if (arg.get("URL", 0) != null) {

View File

@ -35,7 +35,6 @@
*/ */
package net.sourceforge.plantuml.cucadiagram; package net.sourceforge.plantuml.cucadiagram;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -60,10 +59,6 @@ import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; 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.cucadiagram.entity.EntityFactory;
import net.sourceforge.plantuml.elk.CucaDiagramFileMakerElk; import net.sourceforge.plantuml.elk.CucaDiagramFileMakerElk;
import net.sourceforge.plantuml.graphic.USymbol; 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.CucaDiagramFileMaker;
import net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek; import net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.vizjs.GraphvizJs;
import net.sourceforge.plantuml.xmi.CucaDiagramXmiMaker; import net.sourceforge.plantuml.xmi.CucaDiagramXmiMaker;
import net.sourceforge.plantuml.xmlsc.StateDiagramScxmlMaker; import net.sourceforge.plantuml.xmlsc.StateDiagramScxmlMaker;
@ -879,24 +873,5 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
// Strange numbers here for backwards compatibility // Strange numbers here for backwards compatibility
return ClockwiseTopRightBottomLeft.topRightBottomLeft(0, 5, 5, 0); 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);
}
} }

View File

@ -65,12 +65,15 @@ public enum LeafType {
public static LeafType getLeafType(String type) { public static LeafType getLeafType(String type) {
type = StringUtils.goUpperCase(type); type = StringUtils.goUpperCase(type);
if (type.startsWith("ABSTRACT")) { if (type.startsWith("ABSTRACT"))
return LeafType.ABSTRACT_CLASS; return LeafType.ABSTRACT_CLASS;
}
if (type.startsWith("DIAMOND")) { if (type.startsWith("DIAMOND"))
return LeafType.STATE_CHOICE; return LeafType.STATE_CHOICE;
}
if (type.startsWith("STATIC"))
return LeafType.CLASS;
return LeafType.valueOf(type); return LeafType.valueOf(type);
} }

View File

@ -46,7 +46,6 @@ import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.awt.geom.Dimension2D; import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl;
import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder; 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.skin.VisibilityModifier;
import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Margins;
import net.sourceforge.plantuml.ugraphic.UComment; import net.sourceforge.plantuml.ugraphic.UComment;
import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.utils.UniqueSequence; import net.sourceforge.plantuml.utils.UniqueSequence;
@ -125,13 +123,6 @@ public class Link extends WithLinkType implements Hideable, Removeable {
this.type = type; this.type = type;
this.linkArg = linkArg; 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() { public Link getInv() {

View File

@ -54,11 +54,11 @@ public class LinkArg {
public static LinkArg build(final Display label, int length) { public static LinkArg build(final Display label, int length) {
return build(label, length, true); return build(label, length, true);
} }
public static LinkArg noDisplay(int length) { public static LinkArg noDisplay(int length) {
return build(Display.NULL, length, true); return build(Display.NULL, length, true);
} }
public static LinkArg build(final Display label, int length, boolean manageVisibilityModifier) { public static LinkArg build(final Display label, int length, boolean manageVisibilityModifier) {
VisibilityModifier visibilityModifier = null; VisibilityModifier visibilityModifier = null;
final Display newLabel; final Display newLabel;
@ -77,7 +77,7 @@ public class LinkArg {
kal2); kal2);
} }
public LinkArg withKal(String kal1) { public LinkArg withKal(String kal1, String kal2) {
return new LinkArg(label, length, qualifier1, qualifier2, labeldistance, labelangle, visibilityModifier, kal1, return new LinkArg(label, length, qualifier1, qualifier2, labeldistance, labelangle, visibilityModifier, kal1,
kal2); kal2);
} }

View File

@ -74,7 +74,6 @@ final public class DotData implements PortionShower {
private final ColorMapper colorMapper; private final ColorMapper colorMapper;
private final EntityFactory entityFactory; private final EntityFactory entityFactory;
private final GraphvizVersion graphvizVersion;
public EntityFactory getEntityFactory() { public EntityFactory getEntityFactory() {
return entityFactory; return entityFactory;
@ -83,7 +82,7 @@ final public class DotData implements PortionShower {
public DotData(IGroup topParent, List<Link> links, Collection<ILeaf> leafs, UmlDiagramType umlDiagramType, public DotData(IGroup topParent, List<Link> links, Collection<ILeaf> leafs, UmlDiagramType umlDiagramType,
ISkinParam skinParam, GroupHierarchy groupHierarchy, PortionShower portionShower, ColorMapper colorMapper, ISkinParam skinParam, GroupHierarchy groupHierarchy, PortionShower portionShower, ColorMapper colorMapper,
EntityFactory entityFactory, boolean isHideEmptyDescriptionForState, DotMode dotMode, EntityFactory entityFactory, boolean isHideEmptyDescriptionForState, DotMode dotMode,
String namespaceSeparator, Pragma pragma, GraphvizVersion graphvizVersion) { String namespaceSeparator, Pragma pragma) {
this.namespaceSeparator = namespaceSeparator; this.namespaceSeparator = namespaceSeparator;
this.pragma = pragma; this.pragma = pragma;
this.topParent = Objects.requireNonNull(topParent); this.topParent = Objects.requireNonNull(topParent);
@ -98,19 +97,16 @@ final public class DotData implements PortionShower {
this.groupHierarchy = groupHierarchy; this.groupHierarchy = groupHierarchy;
this.portionShower = portionShower; this.portionShower = portionShower;
this.entityFactory = entityFactory; this.entityFactory = entityFactory;
this.graphvizVersion = graphvizVersion;
} }
public DotData(IGroup topParent, List<Link> links, Collection<ILeaf> leafs, UmlDiagramType umlDiagramType, public DotData(IGroup topParent, List<Link> links, Collection<ILeaf> leafs, UmlDiagramType umlDiagramType,
ISkinParam skinParam, GroupHierarchy groupHierarchy, ColorMapper colorMapper, EntityFactory entityFactory, ISkinParam skinParam, GroupHierarchy groupHierarchy, ColorMapper colorMapper, EntityFactory entityFactory,
boolean isHideEmptyDescriptionForState, DotMode dotMode, String namespaceSeparator, Pragma pragma, boolean isHideEmptyDescriptionForState, DotMode dotMode, String namespaceSeparator, Pragma pragma) {
GraphvizVersion graphvizVersion) {
this(topParent, links, leafs, umlDiagramType, skinParam, groupHierarchy, new PortionShower() { this(topParent, links, leafs, umlDiagramType, skinParam, groupHierarchy, new PortionShower() {
public boolean showPortion(EntityPortion portion, IEntity entity) { public boolean showPortion(EntityPortion portion, IEntity entity) {
return true; return true;
} }
}, colorMapper, entityFactory, isHideEmptyDescriptionForState, dotMode, namespaceSeparator, pragma, }, colorMapper, entityFactory, isHideEmptyDescriptionForState, dotMode, namespaceSeparator, pragma);
graphvizVersion);
} }
public UmlDiagramType getUmlDiagramType() { public UmlDiagramType getUmlDiagramType() {
@ -236,8 +232,4 @@ final public class DotData implements PortionShower {
} }
public GraphvizVersion getGraphvizVersion() {
return graphvizVersion;
}
} }

View File

@ -36,7 +36,7 @@
package net.sourceforge.plantuml.cucadiagram.dot; package net.sourceforge.plantuml.cucadiagram.dot;
public interface GraphvizVersion { public interface GraphvizVersion {
public boolean useShield(); public boolean useShieldForQuantifier();
public boolean useProtectionWhenThereALinkFromOrToGroup(); public boolean useProtectionWhenThereALinkFromOrToGroup();

View File

@ -45,7 +45,7 @@ public class GraphvizVersionFinder {
final private File dotExe; final private File dotExe;
final public static GraphvizVersion DEFAULT = new GraphvizVersion() { final public static GraphvizVersion DEFAULT = new GraphvizVersion() {
public boolean useShield() { public boolean useShieldForQuantifier() {
return true; return true;
} }
@ -82,7 +82,7 @@ public class GraphvizVersionFinder {
final int minor = Integer.parseInt(m.group(2)); final int minor = Integer.parseInt(m.group(2));
final int v = 100 * major + minor; final int v = 100 * major + minor;
return new GraphvizVersion() { return new GraphvizVersion() {
public boolean useShield() { public boolean useShieldForQuantifier() {
return v <= 228; return v <= 228;
} }

View File

@ -39,6 +39,7 @@ package net.sourceforge.plantuml.cucadiagram.entity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -47,6 +48,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.ISkinParam; 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.graphic.color.Colors;
import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.skin.VisibilityModifier;
import net.sourceforge.plantuml.svek.IEntityImage; import net.sourceforge.plantuml.svek.IEntityImage;
import net.sourceforge.plantuml.svek.Kal;
import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.Margins;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svek.SingleStrategy; import net.sourceforge.plantuml.svek.SingleStrategy;
@ -282,7 +285,6 @@ final public class EntityImpl implements ILeaf, IGroup {
public final Margins getMargins() { public final Margins getMargins() {
checkNotGroup(); checkNotGroup();
System.err.println("GETTING MARGIN!");
return margins; return margins;
} }
@ -789,4 +791,23 @@ final public class EntityImpl implements ILeaf, IGroup {
return stereostyles; return stereostyles;
} }
private final Map<Direction, List<Kal>> kals = new EnumMap<>(Direction.class);
public void addKal(Kal kal) {
final Direction position = kal.getPosition();
List<Kal> list = kals.get(position);
if (list == null) {
list = new ArrayList<>();
kals.put(position, list);
}
list.add(kal);
}
public List<Kal> getKals(Direction position) {
final List<Kal> result = kals.get(position);
if (result == null)
return Collections.emptyList();
return Collections.unmodifiableList(result);
}
} }

View File

@ -64,6 +64,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement;
import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage;
import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap;
public class DescriptionDiagramFactory extends PSystemCommandFactory { public class DescriptionDiagramFactory extends PSystemCommandFactory {
@ -120,6 +121,7 @@ public class DescriptionDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandCreateMap()); cmds.add(new CommandCreateMap());
cmds.add(new CommandCreateJson()); cmds.add(new CommandCreateJson());
cmds.add(new CommandCreateJsonSingleLine());
// cmds.add(new CommandHideShowSpecificClass()); // cmds.add(new CommandHideShowSpecificClass());
cmds.add(new CommandArchimate()); cmds.add(new CommandArchimate());

View File

@ -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<AbstractClassOrObjectDiagram> {
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;
}
}

View File

@ -80,7 +80,6 @@ import net.sourceforge.plantuml.version.Version;
public class PicoWebServer implements Runnable { public class PicoWebServer implements Runnable {
private final Socket connect; private final Socket connect;
private static final AtomicBoolean stopRequested = new AtomicBoolean(false);
private static boolean enableStop; private static boolean enableStop;
public PicoWebServer(Socket c) { public PicoWebServer(Socket c) {
@ -91,7 +90,8 @@ public class PicoWebServer implements Runnable {
startServer(8080, null, false); 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; PicoWebServer.enableStop = argEnableStop;
final InetAddress bindAddress1 = bindAddress == null ? null : InetAddress.getByName(bindAddress); final InetAddress bindAddress1 = bindAddress == null ? null : InetAddress.getByName(bindAddress);
final ServerSocket serverConnect = new ServerSocket(port, 50, bindAddress1); 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 { public static void serverLoop(final ServerSocket serverConnect) throws IOException {
while (stopRequested.get() == false) { while (true) {
final PicoWebServer myServer = new PicoWebServer(serverConnect.accept()); final PicoWebServer myServer = new PicoWebServer(serverConnect.accept());
final Thread thread = new Thread(myServer); final Thread thread = new Thread(myServer);
thread.start(); thread.start();
@ -137,10 +137,10 @@ public class PicoWebServer implements Runnable {
return; return;
if (request.getPath().startsWith("/plantuml/serverinfo") && handleInfo(out)) if (request.getPath().startsWith("/plantuml/serverinfo") && handleInfo(out))
return; return;
if (enableStop && request.getPath().startsWith("/stopserver")) { if (enableStop && (request.getPath().startsWith("/stopserver")
stopRequested.set(true); || request.getPath().startsWith("/plantuml/stopserver")) && handleStop(out))
return; return;
}
} else if (request.getMethod().equals("POST") && request.getPath().equals("/render")) { } else if (request.getMethod().equals("POST") && request.getPath().equals("/render")) {
handleRenderRequest(request, out); handleRenderRequest(request, out);
return; 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, "<html>Stoping...</html>");
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 { private boolean handleInfo(BufferedOutputStream out) throws IOException {
write(out, "HTTP/1.1 " + "200"); write(out, "HTTP/1.1 " + "200");
write(out, "Cache-Control: no-cache"); write(out, "Cache-Control: no-cache");

View File

@ -240,6 +240,14 @@ public class DotPath implements UShape, Moveable {
beziers.get(0).ctrlx1 = x; beziers.get(0).ctrlx1 = x;
beziers.get(0).ctrly1 = y; 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() { public Point2D getEndPoint() {
return beziers.get(beziers.size() - 1).getP2(); return beziers.get(beziers.size() - 1).getP2();

View File

@ -162,7 +162,7 @@ public class SequenceDiagram extends UmlDiagram {
return participantsget(code) != null; return participantsget(code) != null;
} }
public String addMessage(AbstractMessage m) { public CommandExecutionResult addMessage(AbstractMessage m) {
if (m.isParallel()) if (m.isParallel())
m.setParallelBrother(getLastAbstractMessage()); m.setParallelBrother(getLastAbstractMessage());
@ -171,12 +171,13 @@ public class SequenceDiagram extends UmlDiagram {
events.add(m); events.add(m);
if (pendingCreate != null) { if (pendingCreate != null) {
if (m.compatibleForCreate(pendingCreate.getParticipant()) == false) 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); m.addLifeEvent(pendingCreate);
pendingCreate = null; pendingCreate = null;
} }
return null; return CommandExecutionResult.ok();
} }
private AbstractMessage getLastAbstractMessage() { private AbstractMessage getLastAbstractMessage() {

View File

@ -320,9 +320,9 @@ public class CommandArrow extends SingleLineCommand2<SequenceDiagram> {
msg.setPart1Anchor(arg.get("PART1ANCHOR", 1)); msg.setPart1Anchor(arg.get("PART1ANCHOR", 1));
msg.setPart2Anchor(arg.get("PART2ANCHOR", 1)); msg.setPart2Anchor(arg.get("PART2ANCHOR", 1));
final String error = diagram.addMessage(msg); final CommandExecutionResult status = diagram.addMessage(msg);
if (error != null) if (status.isOk() == false)
return CommandExecutionResult.error(error); return status;
final String s = arg.get("LIFECOLOR", 0); final String s = arg.get("LIFECOLOR", 0);

View File

@ -149,9 +149,9 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
msg.setPart1Anchor(arg.get("PART1ANCHOR", 1)); msg.setPart1Anchor(arg.get("PART1ANCHOR", 1));
msg.setPart2Anchor(arg.get("PART2ANCHOR", 1)); msg.setPart2Anchor(arg.get("PART2ANCHOR", 1));
final String error = diagram.addMessage(msg); final CommandExecutionResult status = diagram.addMessage(msg);
if (error != null) if (status.isOk() == false)
return CommandExecutionResult.error(error); return status;
final String s = arg.get("LIFECOLOR", 0); final String s = arg.get("LIFECOLOR", 0);

View File

@ -83,18 +83,17 @@ public class CommandReturn extends SingleLineCommand2<SequenceDiagram> {
boolean doDeactivation = true; boolean doDeactivation = true;
if (message1 == null) { if (message1 == null) {
final EventWithDeactivate last = diagram.getLastEventWithDeactivate(); final EventWithDeactivate last = diagram.getLastEventWithDeactivate();
if (last instanceof Message == false) { if (last instanceof Message == false)
return CommandExecutionResult.error("Nowhere to return to."); return CommandExecutionResult.error("Nowhere to return to.");
}
message1 = (Message) last; message1 = (Message) last;
doDeactivation = false; doDeactivation = false;
} }
ArrowConfiguration arrow = message1.getArrowConfiguration().withBody(ArrowBody.DOTTED); ArrowConfiguration arrow = message1.getArrowConfiguration().withBody(ArrowBody.DOTTED);
final String color = arg.get("COLOR", 0); final String color = arg.get("COLOR", 0);
if (color != null) { if (color != null)
arrow = arrow.withColor(HColorSet.instance().getColor(diagram.getSkinParam().getThemeStyle(), color)); arrow = arrow.withColor(HColorSet.instance().getColor(diagram.getSkinParam().getThemeStyle(), color));
}
final Display display = Display.getWithNewlines(arg.get("MESSAGE", 0)); final Display display = Display.getWithNewlines(arg.get("MESSAGE", 0));
final AbstractMessage message2; final AbstractMessage message2;
@ -106,17 +105,19 @@ public class CommandReturn extends SingleLineCommand2<SequenceDiagram> {
message2 = new Message(diagram.getSkinParam().getCurrentStyleBuilder(), message1.getParticipant2(), message2 = new Message(diagram.getSkinParam().getCurrentStyleBuilder(), message1.getParticipant2(),
message1.getParticipant1(), display, arrow, diagram.getNextMessageNumber()); message1.getParticipant1(), display, arrow, diagram.getNextMessageNumber());
final boolean parallel = arg.get("PARALLEL", 0) != null; final boolean parallel = arg.get("PARALLEL", 0) != null;
if (parallel) { if (parallel)
message2.goParallel(); message2.goParallel();
}
} }
diagram.addMessage(message2); final CommandExecutionResult status = diagram.addMessage(message2);
if (status.isOk() == false)
return status;
if (doDeactivation) { if (doDeactivation) {
final String error = diagram.activate(message1.getParticipant2(), LifeEventType.DEACTIVATE, null); final String error = diagram.activate(message1.getParticipant2(), LifeEventType.DEACTIVATE, null);
if (error != null) { if (error != null)
return CommandExecutionResult.error(error); return CommandExecutionResult.error(error);
}
} }
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();

View File

@ -245,7 +245,7 @@ public class GroupingTile extends AbstractTile {
tiles = removeEmptyCloseToParallel(tiles); tiles = removeEmptyCloseToParallel(tiles);
final List<Tile> result = new ArrayList<>(); final List<Tile> result = new ArrayList<>();
for (Tile tile : tiles) { for (Tile tile : tiles) {
if (isParallel(tile)) { if (result.size() > 0 && isParallel(tile)) {
if (pending == null) { if (pending == null) {
pending = new TileParallel(stringBounder); pending = new TileParallel(stringBounder);
final Tile tmp = result.get(result.size() - 1); final Tile tmp = result.get(result.size() - 1);

View File

@ -59,18 +59,18 @@ public class Bibliotekon {
private final List<SvekLine> lines1 = new ArrayList<>(); private final List<SvekLine> lines1 = new ArrayList<>();
private final List<SvekLine> allLines = new ArrayList<>(); private final List<SvekLine> 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); final SvekNode node = new SvekNode(ent, image, colorSequence, stringBounder);
nodeMap.put(ent, node); nodeMap.put(ent, node);
return node; return node;
} }
public Cluster getCluster(IGroup ent) { public Cluster getCluster(IGroup ent) {
for (Cluster cl : allCluster) { for (Cluster cl : allCluster)
if (cl.getGroups().contains(ent)) { if (cl.getGroups().contains(ent))
return cl; return cl;
}
}
return null; return null;
} }
@ -97,9 +97,9 @@ public class Bibliotekon {
private static boolean first(SvekLine line) { private static boolean first(SvekLine line) {
final int length = line.getLength(); final int length = line.getLength();
if (length == 1) { if (length == 1)
return true; return true;
}
return false; return false;
} }
@ -115,18 +115,16 @@ public class Bibliotekon {
final SvekNode result = getNode(ent); final SvekNode result = getNode(ent);
if (result != null) { if (result != null) {
String uid = result.getUid(); String uid = result.getUid();
if (result.isShielded()) { if (result.isShielded())
uid = uid + ":h"; uid = uid + ":h";
}
return uid; return uid;
} }
assert result == null; assert result == null;
if (ent.isGroup()) { if (ent.isGroup()) {
for (IEntity i : nodeMap.keySet()) { for (IEntity i : nodeMap.keySet())
if (ent.getCodeGetName().equals(i.getCodeGetName())) { if (ent.getCodeGetName().equals(i.getCodeGetName()))
return getNode(i).getUid(); return getNode(i).getUid();
}
}
return Cluster.getSpecialPointId(ent); return Cluster.getSpecialPointId(ent);
} }
throw new IllegalStateException(); throw new IllegalStateException();
@ -180,39 +178,36 @@ public class Bibliotekon {
public List<SvekLine> getAllLineConnectedTo(IEntity leaf) { public List<SvekLine> getAllLineConnectedTo(IEntity leaf) {
final List<SvekLine> result = new ArrayList<>(); final List<SvekLine> result = new ArrayList<>();
for (SvekLine line : allLines) { for (SvekLine line : allLines)
if (line.isLinkFromOrTo(leaf)) { if (line.isLinkFromOrTo(leaf))
result.add(line); result.add(line);
}
}
return Collections.unmodifiableList(result); return Collections.unmodifiableList(result);
} }
public SvekLine getLine(Link link) { public SvekLine getLine(Link link) {
for (SvekLine line : allLines) { for (SvekLine line : allLines)
if (line.isLink(link)) { if (line.isLink(link))
return line; return line;
}
}
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
public IEntity getOnlyOther(IEntity entity) { public IEntity getOnlyOther(IEntity entity) {
for (SvekLine line : allLines) { for (SvekLine line : allLines) {
final IEntity other = line.getOther(entity); final IEntity other = line.getOther(entity);
if (other != null) { if (other != null)
return other; return other;
}
} }
return null; return null;
} }
public ILeaf getLeaf(SvekNode node) { public ILeaf getLeaf(SvekNode node) {
for (Map.Entry<ILeaf, SvekNode> ent : nodeMap.entrySet()) { for (Map.Entry<ILeaf, SvekNode> ent : nodeMap.entrySet())
if (ent.getValue() == node) { if (ent.getValue() == node)
return ent.getKey(); return ent.getKey();
}
}
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }

View File

@ -76,7 +76,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker {
final DotData dotData = new DotData(diagram.getEntityFactory().getRootGroup(), getOrderedLinks(), final DotData dotData = new DotData(diagram.getEntityFactory().getRootGroup(), getOrderedLinks(),
diagram.getLeafsvalues(), diagram.getUmlDiagramType(), diagram.getSkinParam(), diagram, diagram, diagram.getLeafsvalues(), diagram.getUmlDiagramType(), diagram.getSkinParam(), diagram, diagram,
diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), dotMode, diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), dotMode,
diagram.getNamespaceSeparator(), diagram.getPragma(), diagram.getGraphvizVersion()); diagram.getNamespaceSeparator(), diagram.getPragma());
final boolean intricated = diagram.mergeIntricated(); final boolean intricated = diagram.mergeIntricated();
return new GeneralImageBuilder(intricated, dotData, diagram.getEntityFactory(), diagram.getSource(), return new GeneralImageBuilder(intricated, dotData, diagram.getEntityFactory(), diagram.getSource(),
diagram.getPragma(), stringBounder, diagram.getUmlDiagramType().getStyleName()); diagram.getPragma(), stringBounder, diagram.getUmlDiagramType().getStyleName());

View File

@ -60,6 +60,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.DotSplines;
import net.sourceforge.plantuml.cucadiagram.dot.Graphviz; import net.sourceforge.plantuml.cucadiagram.dot.Graphviz;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; 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.dot.ProcessState;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
@ -86,8 +87,6 @@ public class DotStringFactory implements Moveable {
private final StringBounder stringBounder; private final StringBounder stringBounder;
private GraphvizVersion graphvizVersion;
public DotStringFactory(StringBounder stringBounder, DotData dotData) { public DotStringFactory(StringBounder stringBounder, DotData dotData) {
this.skinParam = dotData.getSkinParam(); this.skinParam = dotData.getSkinParam();
this.umlDiagramType = dotData.getUmlDiagramType(); this.umlDiagramType = dotData.getUmlDiagramType();
@ -97,7 +96,6 @@ public class DotStringFactory implements Moveable {
this.stringBounder = stringBounder; this.stringBounder = stringBounder;
this.root = new Cluster(colorSequence, skinParam, dotData.getRootGroup()); this.root = new Cluster(colorSequence, skinParam, dotData.getRootGroup());
this.current = root; this.current = root;
this.graphvizVersion = dotData.getGraphvizVersion();
} }
public DotStringFactory(StringBounder stringBounder, CucaDiagram diagram) { public DotStringFactory(StringBounder stringBounder, CucaDiagram diagram) {
@ -109,7 +107,6 @@ public class DotStringFactory implements Moveable {
this.stringBounder = stringBounder; this.stringBounder = stringBounder;
this.root = new Cluster(colorSequence, skinParam, diagram.getEntityFactory().getRootGroup()); this.root = new Cluster(colorSequence, skinParam, diagram.getEntityFactory().getRootGroup());
this.current = root; this.current = root;
this.graphvizVersion = diagram.getGraphvizVersion();
} }
public void addNode(SvekNode node) { public void addNode(SvekNode node) {
@ -215,14 +212,14 @@ public class DotStringFactory implements Moveable {
root.printCluster1(sb, bibliotekon.allLines(), stringBounder); root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
for (SvekLine line : bibliotekon.lines0()) for (SvekLine line : bibliotekon.lines0())
line.appendLine(graphvizVersion, sb, dotMode, dotSplines); line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
root.fillRankMin(rankMin); root.fillRankMin(rankMin);
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, graphvizVersion, umlDiagramType); root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType);
printMinRanking(sb); printMinRanking(sb);
for (SvekLine line : bibliotekon.lines1()) for (SvekLine line : bibliotekon.lines1())
line.appendLine(graphvizVersion, sb, dotMode, dotSplines); line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
SvekUtils.println(sb); SvekUtils.println(sb);
sb.append("}"); sb.append("}");
@ -281,6 +278,24 @@ public class DotStringFactory implements Moveable {
return 35; 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 { public String getSvg(BaseFile basefile, String[] dotOptions) throws IOException {
String dotString = createDotString(dotOptions); String dotString = createDotString(dotOptions);
@ -299,7 +314,7 @@ public class DotStringFactory implements Moveable {
} }
} catch (GraphvizJsRuntimeException e) { } catch (GraphvizJsRuntimeException e) {
System.err.println("GraphvizJsRuntimeException"); System.err.println("GraphvizJsRuntimeException");
this.graphvizVersion = GraphvizJs.getGraphvizVersion(true); graphvizVersion = GraphvizJs.getGraphvizVersion(true);
dotString = createDotString(dotOptions); dotString = createDotString(dotOptions);
graphviz = GraphvizUtils.create(skinParam, dotString, "svg"); graphviz = GraphvizUtils.create(skinParam, dotString, "svg");
baos = new ByteArrayOutputStream(); baos = new ByteArrayOutputStream();

View File

@ -155,8 +155,7 @@ public final class GeneralImageBuilder {
throw new IllegalStateException(); throw new IllegalStateException();
if (leaf.getLeafType().isLikeClass()) { if (leaf.getLeafType().isLikeClass()) {
final EntityImageClass entityImageClass = new EntityImageClass(graphvizVersion, (ILeaf) leaf, skinParam, final EntityImageClass entityImageClass = new EntityImageClass((ILeaf) leaf, skinParam, portionShower);
portionShower);
final Neighborhood neighborhood = leaf.getNeighborhood(); final Neighborhood neighborhood = leaf.getNeighborhood();
if (neighborhood != null) if (neighborhood != null)
return new EntityImageProtected(entityImageClass, 20, neighborhood, bibliotekon); return new EntityImageProtected(entityImageClass, 20, neighborhood, bibliotekon);
@ -418,7 +417,7 @@ public final class GeneralImageBuilder {
final FontConfiguration labelFont = getFontForLink(link, skinParam); final FontConfiguration labelFont = getFontForLink(link, skinParam);
final SvekLine line = new SvekLine(link, dotStringFactory.getColorSequence(), skinParam, stringBounder, final SvekLine line = new SvekLine(link, dotStringFactory.getColorSequence(), skinParam, stringBounder,
labelFont, dotStringFactory.getBibliotekon(), pragma); labelFont, dotStringFactory.getBibliotekon(), pragma, dotStringFactory.getGraphvizVersion());
dotStringFactory.getBibliotekon().addLine(line); dotStringFactory.getBibliotekon().addLine(line);
@ -556,8 +555,8 @@ public final class GeneralImageBuilder {
} }
return createEntityImageBlock(ent, skinParam, dotData.isHideEmptyDescriptionForState(), dotData, return createEntityImageBlock(ent, skinParam, dotData.isHideEmptyDescriptionForState(), dotData,
dotStringFactory.getBibliotekon(), dotData.getGraphvizVersion(), dotData.getUmlDiagramType(), dotStringFactory.getBibliotekon(), dotStringFactory.getGraphvizVersion(),
dotData.getLinks()); dotData.getUmlDiagramType(), dotData.getLinks());
} }
return ent.getSvekImage(); return ent.getSvekImage();
} }
@ -568,8 +567,7 @@ public final class GeneralImageBuilder {
if (ent.getLeafType().isLikeClass() == false) if (ent.getLeafType().isLikeClass() == false)
continue; continue;
final IEntityImage im = new EntityImageClass(dotData.getGraphvizVersion(), ent, dotData.getSkinParam(), final IEntityImage im = new EntityImageClass(ent, dotData.getSkinParam(), dotData);
dotData);
final double w = im.calculateDimension(stringBounder).getWidth(); final double w = im.calculateDimension(stringBounder).getWidth();
if (w > result) if (w > result)
result = w; result = w;

View File

@ -128,7 +128,7 @@ public final class GroupPngMakerActivity {
final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(), final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(),
skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(), false, 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(), final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(),
diagram.getSource(), diagram.getPragma(), stringBounder, SName.activityDiagram); diagram.getSource(), diagram.getPragma(), stringBounder, SName.activityDiagram);

View File

@ -151,7 +151,7 @@ public final class GroupPngMakerState {
final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(), final DotData dotData = new DotData(group, links, group.getLeafsDirect(), diagram.getUmlDiagramType(),
skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(), skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(),
diagram.isHideEmptyDescriptionForState(), DotMode.NORMAL, diagram.getNamespaceSeparator(), diagram.isHideEmptyDescriptionForState(), DotMode.NORMAL, diagram.getNamespaceSeparator(),
diagram.getPragma(), diagram.getGraphvizVersion()); diagram.getPragma());
final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(), final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(),
diagram.getSource(), diagram.getPragma(), stringBounder, SName.stateDiagram); diagram.getSource(), diagram.getPragma(), stringBounder, SName.stateDiagram);

View File

@ -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);
}
}

View File

@ -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<Segment> {
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<Segment> 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;
}
}

View File

@ -73,6 +73,7 @@ import net.sourceforge.plantuml.cucadiagram.NoteLinkStrategy;
import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; 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.descdiagram.command.StringWithArrow;
import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment; 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, 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.link = Objects.requireNonNull(link);
this.skinParam = skinParam; this.skinParam = skinParam;
@ -308,15 +323,10 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
else else
this.labelShield = 7; 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) { private TextBlock addVisibilityModifier(TextBlock block, Link link, ISkinParam skinParam) {
final VisibilityModifier visibilityModifier = link.getVisibilityModifier(); final VisibilityModifier visibilityModifier = link.getVisibilityModifier();
@ -766,19 +776,20 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
link.getLinkConstraint().drawMe(ug, skinParam); 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(); 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<Point2D> getSquare(double x, double y) { private List<Point2D> getSquare(double x, double y) {
final List<Point2D> result = new ArrayList<>(); final List<Point2D> result = new ArrayList<>();
result.add(new Point2D.Double(x, y)); result.add(new Point2D.Double(x, y));
@ -1053,4 +1064,12 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
return link.getStereotype(); 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);
}
} }

View File

@ -38,7 +38,7 @@ package net.sourceforge.plantuml.svek;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.List; import java.util.List;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.Hideable; import net.sourceforge.plantuml.Hideable;
import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.awt.geom.Dimension2D; 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.EntityImageDescription;
import net.sourceforge.plantuml.svek.image.EntityImageLollipopInterface; import net.sourceforge.plantuml.svek.image.EntityImageLollipopInterface;
import net.sourceforge.plantuml.ugraphic.Shadowable; import net.sourceforge.plantuml.ugraphic.Shadowable;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.UPolygon;
public class SvekNode implements Positionable, IShapePseudo, Hideable { public class SvekNode implements Positionable, IShapePseudo, Hideable {
private final ShapeType type; private final ShapeType type;
private final double width; private Dimension2D dimImage;
private final double height;
private final String uid; private final String uid;
private final int color; private final int color;
private double minX; private double minX;
private double minY; private double minY;
private final Margins shield; private Margins shield;
private final EntityPosition entityPosition; private final EntityPosition entityPosition;
private final IEntityImage image; private final IEntityImage image;
private final StringBounder stringBounder;
public EntityPosition getEntityPosition() { public EntityPosition getEntityPosition() {
return entityPosition; return entityPosition;
@ -95,19 +96,14 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
private final IGroup group; private final IGroup group;
SvekNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { SvekNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) {
final Dimension2D dim = image.calculateDimension(stringBounder); this.stringBounder = stringBounder;
this.entityPosition = ent.getEntityPosition(); this.entityPosition = ent.getEntityPosition();
this.image = image; this.image = image;
this.top = ent.isTop(); this.top = ent.isTop();
this.type = image.getShapeType(); this.type = image.getShapeType();
this.width = dim.getWidth();
this.height = dim.getHeight();
this.color = colorSequence.getValue(); this.color = colorSequence.getValue();
this.uid = String.format("sh%04d", color); 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) { if (((EntityImpl) ent).getOriginalGroup() == null) {
this.group = 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() { public final ShapeType getType() {
return type; return type;
} }
public final double getWidth() { public final double getWidth() {
return width; return getDimImage().getWidth();
} }
public final double getHeight() { public final double getHeight() {
return height; return getDimImage().getHeight();
} }
public void appendShape(StringBuilder sb, StringBounder stringBounder) { public void appendShape(StringBuilder sb, StringBounder stringBounder) {
@ -139,7 +141,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
appendHtml(sb); appendHtml(sb);
return; return;
} }
if (type == ShapeType.RECTANGLE && shield.isZero() == false) { if (type == ShapeType.RECTANGLE && shield().isZero() == false) {
appendHtml(sb); appendHtml(sb);
return; return;
} }
@ -158,6 +160,17 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
SvekUtils.println(sb); 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) { private void appendHtml(StringBuilder sb) {
sb.append(uid); sb.append(uid);
sb.append(" ["); sb.append(" [");
@ -175,20 +188,20 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
sb.append("<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"); sb.append("<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">");
sb.append("<TR>"); sb.append("<TR>");
appendTd(sb); appendTd(sb);
appendTd(sb, 1, shield.getY1()); appendTd(sb, 1, shield().getY1());
appendTd(sb); appendTd(sb);
sb.append("</TR>"); sb.append("</TR>");
sb.append("<TR>"); sb.append("<TR>");
appendTd(sb, shield.getX1(), 1); appendTd(sb, shield().getX1(), 1);
sb.append("<TD BGCOLOR=\"" + StringUtils.sharp000000(color) + "\""); sb.append("<TD BGCOLOR=\"" + StringUtils.sharp000000(color) + "\"");
sb.append(" FIXEDSIZE=\"TRUE\" WIDTH=\"" + getWidth() + "\" HEIGHT=\"" + getHeight() + "\""); sb.append(" FIXEDSIZE=\"TRUE\" WIDTH=\"" + getWidth() + "\" HEIGHT=\"" + getHeight() + "\"");
sb.append(" PORT=\"h\">"); sb.append(" PORT=\"h\">");
sb.append("</TD>"); sb.append("</TD>");
appendTd(sb, shield.getX2(), 1); appendTd(sb, shield().getX2(), 1);
sb.append("</TR>"); sb.append("</TR>");
sb.append("<TR>"); sb.append("<TR>");
appendTd(sb); appendTd(sb);
appendTd(sb, 1, shield.getY2()); appendTd(sb, 1, shield().getY2());
appendTd(sb); appendTd(sb);
sb.append("</TR>"); sb.append("</TR>");
sb.append("</TABLE>"); sb.append("</TABLE>");
@ -247,7 +260,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
} }
private void appendShapeInternal(StringBuilder sb) { private void appendShapeInternal(StringBuilder sb) {
if (type == ShapeType.RECTANGLE && shield.isZero() == false) if (type == ShapeType.RECTANGLE && shield().isZero() == false)
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
else if (type == ShapeType.RECTANGLE || type == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE else if (type == ShapeType.RECTANGLE || type == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE
|| type == ShapeType.FOLDER) || type == ShapeType.FOLDER)
@ -301,15 +314,15 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
} }
public Dimension2D getSize() { public Dimension2D getSize() {
return new Dimension2DDouble(width, height); return getDimImage();
} }
public ClusterPosition getClusterPosition() { public ClusterPosition getClusterPosition() {
return new ClusterPosition(minX, minY, minX + width, minY + height); return new ClusterPosition(minX, minY, minX + getWidth(), minY + getHeight());
} }
public boolean isShielded() { public boolean isShielded() {
return shield.isZero() == false; return shield().isZero() == false;
} }
public void moveSvek(double deltaX, double deltaY) { public void moveSvek(double deltaX, double deltaY) {
@ -349,7 +362,7 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
if (getType() != ShapeType.FOLDER) if (getType() != ShapeType.FOLDER)
return pt; 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)) { if (clusterPosition.isPointJustUpper(pt)) {
final Dimension2D dimName = ((EntityImageDescription) image).getNameDimension(stringBounder); final Dimension2D dimName = ((EntityImageDescription) image).getNameDimension(stringBounder);
if (pt.getX() < minX + dimName.getWidth()) if (pt.getX() < minX + dimName.getWidth())
@ -367,4 +380,41 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
public void addImpact(double angle) { public void addImpact(double angle) {
((EntityImageLollipopInterface) image).addImpact(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<Kal> 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<Kal> list) {
for (Kal kal : list)
kal.drawU(ug);
}
} }

View File

@ -93,6 +93,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage
final Set<String> ids = new HashSet<>(); final Set<String> ids = new HashSet<>();
computeKal();
for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) { for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) {
final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; 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); 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) { private StyleSignature getDefaultStyleDefinition(Stereotype stereotype) {

View File

@ -40,6 +40,7 @@ import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineConfigurable; 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.ILeaf;
import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.PortionShower; 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.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; 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.Style;
import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Kal;
import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.Margins;
import net.sourceforge.plantuml.svek.Ports; import net.sourceforge.plantuml.svek.Ports;
import net.sourceforge.plantuml.svek.ShapeType; 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 { public class EntityImageClass extends AbstractEntityImage implements Stencil, WithPorts {
final private TextBlock body; final private TextBlock body;
// final private Margins shield;
final private GraphvizVersion version;
final private EntityImageClassHeader header; final private EntityImageClassHeader header;
final private Url url; final private Url url;
final private double roundCorner; final private double roundCorner;
@ -87,13 +88,12 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi
final private LineConfigurable lineConfig; 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)); super(entity, entity.getColors().mute(skinParam));
this.leafType = entity.getLeafType(); this.leafType = entity.getLeafType();
this.lineConfig = entity; this.lineConfig = entity;
this.roundCorner = getStyle().value(PName.RoundCorner).asDouble(); this.roundCorner = getStyle().value(PName.RoundCorner).asDouble();
this.version = version;
final boolean showMethods = portionShower.showPortion(EntityPortion.METHOD, entity); final boolean showMethods = portionShower.showPortion(EntityPortion.METHOD, entity);
final boolean showFields = portionShower.showPortion(EntityPortion.FIELD, entity); final boolean showFields = portionShower.showPortion(EntityPortion.FIELD, entity);
@ -112,7 +112,21 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi
width = getSkinParam().minClassWidth(); width = getSkinParam().minClassWidth();
final double height = dimBody.getHeight() + dimHeader.getHeight(); 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 @Override
@ -241,10 +255,7 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi
@Override @Override
public Margins getShield(StringBounder stringBounder) { public Margins getShield(StringBounder stringBounder) {
if (version != null && version.useShield()) return ((ILeaf) getEntity()).getMargins();
return ((ILeaf) getEntity()).getMargins();
return Margins.NONE;
} }
public double getStartingX(StringBounder stringBounder, double y) { public double getStartingX(StringBounder stringBounder, double y) {

View File

@ -186,7 +186,7 @@ public class TContext {
functionsSet.addFunction(new Dec2hex()); functionsSet.addFunction(new Dec2hex());
functionsSet.addFunction(new HslColor()); functionsSet.addFunction(new HslColor());
functionsSet.addFunction(new LoadJson()); functionsSet.addFunction(new LoadJson());
functionsSet.addFunction(new LoadJsonLegacy()); // functionsSet.addFunction(new LoadJsonLegacy());
functionsSet.addFunction(new Chr()); functionsSet.addFunction(new Chr());
functionsSet.addFunction(new Size()); functionsSet.addFunction(new Size());
functionsSet.addFunction(new GetJsonKey()); functionsSet.addFunction(new GetJsonKey());

View File

@ -81,7 +81,7 @@ public class Version {
} }
public static int beta() { public static int beta() {
final int beta = 1; final int beta = 2;
return beta; return beta;
} }

View File

@ -122,7 +122,7 @@ public class GraphvizJs implements Graphviz {
public static GraphvizVersion getGraphvizVersion(final boolean modeSafe) { public static GraphvizVersion getGraphvizVersion(final boolean modeSafe) {
return new GraphvizVersion() { return new GraphvizVersion() {
public boolean useShield() { public boolean useShieldForQuantifier() {
return true; return true;
} }