Import version 1.2021.0

This commit is contained in:
Arnaud Roques 2021-01-10 21:52:19 +01:00
parent 3a7e935cec
commit 5ec1037202
93 changed files with 1854 additions and 436 deletions

View File

@ -83,6 +83,7 @@
<mkdir dir="dist" />
<jar jarfile="plantuml.jar" basedir="build">
<manifest>
<attribute name="Automatic-Module-Name" value="net.sourceforge.plantuml" />
<attribute name="Main-Class" value="net.sourceforge.plantuml.Run" />
<attribute name="Class-Path" value="avalon-framework-4.2.0.jar batik-all-1.7.jar commons-io-1.3.1.jar commons-logging-1.0.4.jar fop.jar xml-apis-ext-1.3.04.jar xmlgraphics-commons-1.4.jar jlatexmath-minimal-1.0.3.jar jlm_cyrillic.jar jlm_greek.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar ditaa0_9.jar" />
</manifest>

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2020.27-SNAPSHOT</version>
<version>1.2021.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>

View File

@ -46,7 +46,9 @@ import java.io.IOException;
import net.sourceforge.plantuml.braille.BrailleCharFactory;
import net.sourceforge.plantuml.braille.UGraphicBraille;
import net.sourceforge.plantuml.graphic.FontStyle;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.StyledString;
import net.sourceforge.plantuml.png.MetadataTag;
import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.svg.SvgGraphics;
@ -142,10 +144,20 @@ public enum FileFormat {
}
static private Dimension2DDouble getJavaDimension(UFont font, String text) {
final Font javaFont = font.getFont();
final FontMetrics fm = gg.getFontMetrics(javaFont);
final Rectangle2D rect = fm.getStringBounds(text, gg);
return new Dimension2DDouble(rect.getWidth(), rect.getHeight());
double width = 0;
double height = 0;
for (StyledString styledString : StyledString.build(text)) {
final Font javaFont;
if (styledString.getStyle() == FontStyle.BOLD)
javaFont = font.bold().getFont();
else
javaFont = font.getFont();
final FontMetrics fm = gg.getFontMetrics(javaFont);
final Rectangle2D rect = fm.getStringBounds(styledString.getText(), gg);
width += rect.getWidth();
height = Math.max(height, rect.getHeight());
}
return new Dimension2DDouble(width, height);
}
private StringBounder getBrailleStringBounder() {

View File

@ -51,6 +51,7 @@ import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.color.HColor;
@ -189,5 +190,8 @@ public interface ISkinParam extends ISkinSimple {
public ActorStyle actorStyle();
public void setSvgSize(String origin, String sizeToUse);
public LengthAdjust getlengthAdjust();
}

View File

@ -97,6 +97,7 @@ import net.sourceforge.plantuml.version.PSystemLicenseFactory;
import net.sourceforge.plantuml.version.PSystemVersionFactory;
import net.sourceforge.plantuml.wbs.WBSDiagramFactory;
import net.sourceforge.plantuml.wire.WireDiagramFactory;
import net.sourceforge.plantuml.yaml.YamlDiagramFactory;
public class PSystemBuilder {
@ -217,6 +218,7 @@ public class PSystemBuilder {
factories.add(new JsonDiagramFactory());
factories.add(new GitDiagramFactory());
factories.add(new BoardDiagramFactory());
factories.add(new YamlDiagramFactory());
return factories;
}

View File

@ -73,6 +73,7 @@ import net.sourceforge.plantuml.style.StyleLoader;
import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
@ -113,6 +114,9 @@ public class SkinParam implements ISkinParam {
if (type == UmlDiagramType.BOARD) {
UseStyle.setBetaStyle(true);
}
if (type == UmlDiagramType.YAML) {
UseStyle.setBetaStyle(true);
}
if (type == UmlDiagramType.SEQUENCE) {
// skin = "debug.skin";
// USE_STYLE2.set(true);
@ -1258,4 +1262,18 @@ public class SkinParam implements ISkinParam {
return s;
}
public LengthAdjust getlengthAdjust() {
final String value = getValue("lengthAdjust");
if ("spacingAndGlyphs".equalsIgnoreCase(value)) {
return LengthAdjust.SPACING_AND_GLYPHS;
}
if ("spacing".equalsIgnoreCase(value)) {
return LengthAdjust.SPACING;
}
if ("none".equalsIgnoreCase(value)) {
return LengthAdjust.NONE;
}
return LengthAdjust.defaultValue();
}
}

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
@ -372,4 +373,8 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.transformStringForSizeHack(s);
}
public LengthAdjust getlengthAdjust() {
return skinParam.getlengthAdjust();
}
}

View File

@ -68,6 +68,9 @@ public class StringUtils {
public static final char PACKAGE_PRIVATE_METHOD = '\uEEF5';
public static final char PUBLIC_METHOD = '\uEEF4';
public static final char IE_MANDATORY = '\uEEF3';
public static final char BOLD_START = '\uEEF2';
public static final char BOLD_END = '\uEEF1';
// Used in BackSlash
public static final char PRIVATE_BLOCK = '\uE000';

View File

@ -58,6 +58,7 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
private final DisplaySection header = DisplaySection.none();
private final DisplaySection footer = DisplaySection.none();
private Display mainFrame;
private final UmlDiagramType type;
private final SkinParam skinParam;
@ -67,22 +68,25 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
return pragma;
}
public TitledDiagram() {
this.skinParam = SkinParam.create(getUmlDiagramType());
public TitledDiagram(UmlDiagramType type) {
this.type = type;
this.skinParam = SkinParam.create(type);
}
public final StyleBuilder getCurrentStyleBuilder() {
return skinParam.getCurrentStyleBuilder();
}
public TitledDiagram(ISkinSimple orig) {
this();
public TitledDiagram(UmlDiagramType type, ISkinSimple orig) {
this(type);
if (orig != null) {
this.skinParam.copyAllFrom(orig);
}
}
abstract public UmlDiagramType getUmlDiagramType();
final public UmlDiagramType getUmlDiagramType() {
return type;
}
public final ISkinParam getSkinParam() {
return skinParam;

View File

@ -98,12 +98,12 @@ public abstract class UmlDiagram extends TitledDiagram implements Diagram, Annot
private Animation animation;
public UmlDiagram() {
super();
public UmlDiagram(UmlDiagramType type) {
super(type);
}
public UmlDiagram(ISkinSimple orig) {
super(orig);
public UmlDiagram(UmlDiagramType type, ISkinSimple orig) {
super(type, orig);
}
final public int getMinwidth() {

View File

@ -39,7 +39,7 @@ import net.sourceforge.plantuml.style.SName;
public enum UmlDiagramType {
SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, WIRE,
HELP, GANTT, SALT, JSON, GIT, BOARD;
HELP, GANTT, SALT, JSON, GIT, BOARD, YAML;
public SName getStyleName() {
if (this == SEQUENCE) {

View File

@ -61,7 +61,7 @@ public class ActivityDiagram extends CucaDiagram {
private ConditionalContext currentContext;
public ActivityDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.ACTIVITY, skinParam);
setNamespaceSeparator(null);
}
@ -163,11 +163,6 @@ public class ActivityDiagram extends CucaDiagram {
return lastEntityBrancheConsulted;
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.ACTIVITY;
}
public final ConditionalContext getCurrentContext() {
return currentContext;
}

View File

@ -82,7 +82,7 @@ public class ActivityDiagram3 extends UmlDiagram {
private final Swimlanes swinlanes = new Swimlanes(getSkinParam(), getPragma());
public ActivityDiagram3(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.ACTIVITY, skinParam);
}
private void manageSwimlaneStrategy() {
@ -199,11 +199,6 @@ public class ActivityDiagram3 extends UmlDiagram {
return new DiagramDescription("activity3");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.ACTIVITY;
}
@Override
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {

View File

@ -47,6 +47,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class UGraphicInterceptorUDrawable2 extends UGraphicDelegator {
@ -85,10 +86,11 @@ public class UGraphicInterceptorUDrawable2 extends UGraphicDelegator {
}
private void drawGoto(FtileGoto ftile) {
final HColor gotoColor = HColorUtils.MY_RED;
final FtileGeometry geom = ftile.calculateDimension(getStringBounder());
final Point2D pt = geom.getPointIn();
UGraphic ugGoto = getUg().apply(HColorUtils.GREEN).apply(
HColorUtils.GREEN.bg());
UGraphic ugGoto = getUg().apply(gotoColor).apply(gotoColor.bg());
ugGoto = ugGoto.apply(new UTranslate(pt));
final UTranslate posNow = getPosition();
final UTranslate dest = positions.get(ftile.getName());

View File

@ -80,9 +80,8 @@ public class BoardDiagram extends UmlDiagram {
return new DiagramDescription("Board");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.BOARD;
public BoardDiagram() {
super(UmlDiagramType.BOARD);
}
@Override

View File

@ -78,9 +78,8 @@ public class BpmDiagram extends UmlDiagram {
return new DiagramDescription("(Bpm Diagram)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.BPM;
public BpmDiagram() {
super(UmlDiagramType.BPM);
}
@Override

View File

@ -41,13 +41,14 @@ import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
public abstract class AbstractEntityDiagram extends CucaDiagram {
public AbstractEntityDiagram(ISkinSimple orig) {
super(orig);
public AbstractEntityDiagram(UmlDiagramType type, ISkinSimple orig) {
super(type, orig);
}
final protected List<String> getDotStrings() {

View File

@ -67,7 +67,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
public class ClassDiagram extends AbstractClassOrObjectDiagram {
public ClassDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.CLASS, skinParam);
}
private Code getShortName1972(Code code) {
@ -170,11 +170,6 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
return super.leafExist(getFullyQualifiedCode1972(code));
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.CLASS;
}
private boolean allowMixing;
public void setAllowMixing(boolean allowMixing) {

View File

@ -40,6 +40,7 @@ import net.sourceforge.plantuml.TitledDiagram;
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.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
@ -57,13 +58,16 @@ public class CommandCaption extends SingleLineCommand2<TitledDiagram> {
RegexLeaf.start(), //
new RegexLeaf("caption"), //
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
new RegexLeaf("DISPLAY", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
new RegexOr(//
new RegexLeaf("DISPLAY1", "[%g](.*)[%g]"), //
new RegexLeaf("DISPLAY2", "(.*[\\p{L}0-9_.].*)")), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
diagram.setCaption(DisplayPositionned.single(Display.getWithNewlines(arg.get("DISPLAY", 0)),
HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
final Display s = Display.getWithNewlines(arg.getLazzy("DISPLAY", 0));
diagram.setCaption(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
return CommandExecutionResult.ok();
}

View File

@ -63,7 +63,10 @@ public class CommandFooter extends SingleLineCommand2<TitledDiagram> {
new RegexOr( //
new RegexConcat(RegexLeaf.spaceZeroOrMore(), new RegexLeaf(":"), RegexLeaf.spaceZeroOrMore()), //
RegexLeaf.spaceOneOrMore()), //
new RegexLeaf("LABEL", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
new RegexOr(//
new RegexLeaf("LABEL1", "[%g](.*)[%g]"), //
new RegexLeaf("LABEL2", "(.*[\\p{L}0-9_.].*)")), //
RegexLeaf.end()); //
}
@Override
@ -74,7 +77,8 @@ public class CommandFooter extends SingleLineCommand2<TitledDiagram> {
ha = FontParam.FOOTER.getStyleDefinition(null).getMergedStyle(diagram.getCurrentStyleBuilder())
.getHorizontalAlignment();
}
diagram.getFooter().putDisplay(Display.getWithNewlines(arg.get("LABEL", 0)), ha);
final Display s = Display.getWithNewlines(arg.getLazzy("LABEL", 0));
diagram.getFooter().putDisplay(s, ha);
return CommandExecutionResult.ok();
}

View File

@ -65,7 +65,10 @@ public class CommandHeader extends SingleLineCommand2<TitledDiagram> {
new RegexLeaf(":"), //
RegexLeaf.spaceZeroOrMore()), //
RegexLeaf.spaceOneOrMore()), //
new RegexLeaf("LABEL", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
new RegexOr(//
new RegexLeaf("LABEL1", "[%g](.*)[%g]"), //
new RegexLeaf("LABEL2", "(.*[\\p{L}0-9_.].*)")), //
RegexLeaf.end()); //
}
@Override
@ -76,7 +79,8 @@ public class CommandHeader extends SingleLineCommand2<TitledDiagram> {
ha = FontParam.HEADER.getStyleDefinition(null).getMergedStyle(diagram.getCurrentStyleBuilder())
.getHorizontalAlignment();
}
diagram.getHeader().putDisplay(Display.getWithNewlines(arg.get("LABEL", 0)), ha);
final Display s = Display.getWithNewlines(arg.getLazzy("LABEL", 0));
diagram.getHeader().putDisplay(s, ha);
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,73 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.TitledDiagram;
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.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.VerticalAlignment;
public class CommandLegend extends SingleLineCommand2<TitledDiagram> {
public CommandLegend() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandLegend.class.getName(), //
RegexLeaf.start(), //
new RegexLeaf("legend"), //
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
new RegexOr(//
new RegexLeaf("LEGEND1", "[%g](.*)[%g]"), //
new RegexLeaf("LEGEND2", "(.*[\\p{L}0-9_.].*)")), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
final Display s = Display.getWithNewlines(arg.getLazzy("LEGEND", 0));
diagram.setLegend(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
return CommandExecutionResult.ok();
}
}

View File

@ -40,6 +40,7 @@ import net.sourceforge.plantuml.TitledDiagram;
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.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
@ -57,13 +58,16 @@ public class CommandTitle extends SingleLineCommand2<TitledDiagram> {
RegexLeaf.start(), //
new RegexLeaf("title"), //
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
new RegexLeaf("TITLE", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
new RegexOr(//
new RegexLeaf("TITLE1", "[%g](.*)[%g]"), //
new RegexLeaf("TITLE2", "(.*[\\p{L}0-9_.].*)")), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
diagram.setTitle(DisplayPositionned.single(Display.getWithNewlines(arg.get("TITLE", 0)),
HorizontalAlignment.CENTER, VerticalAlignment.TOP));
final Display s = Display.getWithNewlines(arg.getLazzy("TITLE", 0));
diagram.setTitle(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.TOP));
return CommandExecutionResult.ok();
}
}

View File

@ -262,6 +262,7 @@ public abstract class PSystemCommandFactory extends PSystemAbstractFactory {
cmds.add(new CommandMultilinesCaption());
cmds.add(new CommandMultilinesTitle());
cmds.add(new CommandMultilinesLegend());
cmds.add(new CommandLegend());
cmds.add(new CommandFooter());
cmds.add(new CommandMultilinesFooter());

View File

@ -47,7 +47,7 @@ import net.sourceforge.plantuml.graphic.USymbol;
public class CompositeDiagram extends AbstractEntityDiagram {
public CompositeDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.COMPOSITE, skinParam);
}
@Override
@ -63,9 +63,4 @@ public class CompositeDiagram extends AbstractEntityDiagram {
return getOrCreateLeafDefault(ident, code, type, symbol);
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.COMPOSITE;
}
}

View File

@ -39,7 +39,7 @@ import net.sourceforge.plantuml.utils.StartUtils;
public enum DiagramType {
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX,
DEFINITION, GANTT, NW, MINDMAP, WBS, WIRE, JSON, GIT, BOARD,
DEFINITION, GANTT, NW, MINDMAP, WBS, WIRE, JSON, GIT, BOARD, YAML,
UNKNOWN;
static public DiagramType getTypeFromArobaseStart(String s) {
@ -113,6 +113,9 @@ public enum DiagramType {
if (StartUtils.startsWithSymbolAnd("startboard", s)) {
return BOARD;
}
if (StartUtils.startsWithSymbolAnd("startyaml", s)) {
return YAML;
}
return UNKNOWN;
}
}

View File

@ -50,7 +50,7 @@ public class CommandCreoleStyle implements Command {
private final FontStyle style;
private final boolean tryExtendedColor;
public static CommandCreoleStyle createCreole(FontStyle style) {
public static Command createCreole(FontStyle style) {
return new CommandCreoleStyle("^(" + style.getCreoleSyntax() + "(.+?)" + style.getCreoleSyntax() + ")", style,
false);
}

View File

@ -0,0 +1,89 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.creole.command;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.creole.legacy.StripeSimple;
import net.sourceforge.plantuml.graphic.FontStyle;
public class CommandCreoleStyle2 implements Command {
private final Pattern2 p;
private final FontStyle style;
public static Command createCreole(FontStyle style) {
return new CommandCreoleStyle2("^(" + style.getCreoleSyntax() + "(.+?)" + style.getCreoleSyntax() + ")", style);
}
public static Command createLegacy(FontStyle style) {
return new CommandCreoleStyle2(
"^((" + style.getActivationPattern() + ")(.+?)" + style.getDeactivationPattern() + ")", style);
}
public static Command createLegacyEol(FontStyle style) {
return new CommandCreoleStyle2("^((" + style.getActivationPattern() + ")(.+))$", style);
}
private CommandCreoleStyle2(String p, FontStyle style) {
this.p = MyPattern.cmpile(p);
this.style = style;
}
public String executeAndGetRemaining(final String line, StripeSimple stripe) {
final Matcher2 m = p.matcher(line);
if (m.find() == false) {
throw new IllegalStateException();
}
final int groupCount = m.groupCount();
final String part1 = m.group(groupCount);
final String part2 = line.substring(m.group(1).length());
return StringUtils.BOLD_START + part1 + StringUtils.BOLD_END + part2;
}
public int matchingSize(String line) {
final Matcher2 m = p.matcher(line);
if (m.find() == false) {
return 0;
}
return m.group(1).length();
}
}

View File

@ -69,6 +69,7 @@ import net.sourceforge.plantuml.creole.command.CommandCreoleSizeChange;
import net.sourceforge.plantuml.creole.command.CommandCreoleSpace;
import net.sourceforge.plantuml.creole.command.CommandCreoleSprite;
import net.sourceforge.plantuml.creole.command.CommandCreoleStyle;
import net.sourceforge.plantuml.creole.command.CommandCreoleStyle2;
import net.sourceforge.plantuml.creole.command.CommandCreoleSvgAttributeChange;
import net.sourceforge.plantuml.creole.command.CommandCreoleUrl;
import net.sourceforge.plantuml.graphic.FontConfiguration;
@ -113,6 +114,8 @@ public class StripeSimple implements Stripe {
return header;
}
public final static boolean TSPAN = false;
public StripeSimple(FontConfiguration fontConfiguration, StripeStyle style, CreoleContext context,
ISkinSimple skinParam, CreoleMode modeSimpleLine) {
this.fontConfiguration = fontConfiguration;
@ -120,9 +123,16 @@ public class StripeSimple implements Stripe {
this.skinParam = skinParam;
// class Splitter
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.BOLD));
if (TSPAN) {
this.commands.add(CommandCreoleStyle2.createCreole(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle2.createLegacy(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle2.createLegacyEol(FontStyle.BOLD));
} else {
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.BOLD));
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.BOLD));
}
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.ITALIC));
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.ITALIC));
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.ITALIC));

View File

@ -118,8 +118,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return ident;
}
public CucaDiagram(ISkinSimple orig) {
super(orig);
public CucaDiagram(UmlDiagramType type, ISkinSimple orig) {
super(type, orig);
this.stacks2.add(Ident.empty());
}

View File

@ -77,10 +77,14 @@ abstract class AbstractGraphviz implements Graphviz {
this.dotString = dotString;
this.type = type;
}
protected boolean findExecutableOnPath() {
return true;
}
protected File searchDotExe() {
final protected File searchDotExe() {
String getenv = GraphvizUtils.getenvGraphvizDot();
if (getenv == null) {
if (findExecutableOnPath() && getenv == null) {
getenv = findExecutableOnPath(getExeName());
}
if (getenv == null) {

View File

@ -46,8 +46,8 @@ class GraphvizWindowsLite extends AbstractGraphviz {
static private File specificDotExe;
@Override
protected File searchDotExe() {
return specificDotExe();
protected boolean findExecutableOnPath() {
return false;
}
@Override

View File

@ -48,7 +48,7 @@ import net.sourceforge.plantuml.graphic.USymbol;
public class DescriptionDiagram extends AbstractEntityDiagram {
public DescriptionDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.DESCRIPTION, skinParam);
}
@Override
@ -74,7 +74,7 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
if (type == null) {
String codeString = code.getName();
if (codeString.startsWith("[") && codeString.endsWith("]")) {
final USymbol sym = getSkinParam().componentStyle().toUSymbol() ;
final USymbol sym = getSkinParam().componentStyle().toUSymbol();
final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, sym);
}
@ -127,9 +127,4 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
return super.checkFinalError();
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.DESCRIPTION;
}
}

View File

@ -87,9 +87,8 @@ public class FlowDiagram extends UmlDiagram implements TextBlock {
return new DiagramDescription("Flow Diagram");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.FLOW;
public FlowDiagram() {
super(UmlDiagramType.FLOW);
}
public void lineSimple(TileGeometry orientation, String idDest, String label) {

View File

@ -67,6 +67,7 @@ public class GitDiagram extends UmlDiagram {
private final Collection<GNode> gnodes;
public GitDiagram(GitTextArea textArea) {
super(UmlDiagramType.GIT);
this.gnodes = new GNodeBuilder(textArea.getAllCommits()).getAllNodes();
new GNodeBuilder(textArea.getAllCommits());
}
@ -75,10 +76,6 @@ public class GitDiagram extends UmlDiagram {
return new DiagramDescription("(Git)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.GIT;
}
@Override
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)

View File

@ -0,0 +1,92 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.graphic;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.StringUtils;
public class StyledString {
private final String text;
private final FontStyle style;
private StyledString(String text, FontStyle style) {
this.text = text;
this.style = style;
}
@Override
public String toString() {
return style + "[" + text + "]";
}
public final String getText() {
return text;
}
public final FontStyle getStyle() {
return style;
}
public static List<StyledString> build(String s) {
final List<StyledString> result = new ArrayList<StyledString>();
while (s.length() > 0) {
final int i1 = s.indexOf(StringUtils.BOLD_START);
if (i1 == -1) {
result.add(new StyledString(s, FontStyle.PLAIN));
s = "";
break;
}
final int i2 = s.indexOf(StringUtils.BOLD_END);
if (i1 > 0)
result.add(new StyledString(s.substring(0, i1), FontStyle.PLAIN));
if (i2 == -1) {
result.add(new StyledString(s.substring(i1 + 1), FontStyle.BOLD));
s = "";
} else {
result.add(new StyledString(s.substring(i1 + 1, i2), FontStyle.BOLD));
s = s.substring(i2 + 1);
}
}
return Collections.unmodifiableList(result);
}
}

View File

@ -66,9 +66,8 @@ public class Help extends UmlDiagram {
return new DiagramDescription("(Help)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.HELP;
public Help() {
super(UmlDiagramType.HELP);
}
@Override

View File

@ -74,7 +74,8 @@ public class JsonDiagram extends UmlDiagram {
private final JsonValue root;
private final List<String> highlighted;
public JsonDiagram(JsonValue json, List<String> highlighted) {
public JsonDiagram(UmlDiagramType type, JsonValue json, List<String> highlighted) {
super(UmlDiagramType.JSON);
if (json != null && (json.isString() || json.isBoolean() || json.isNumber())) {
this.root = new JsonArray();
((JsonArray) this.root).add(json);
@ -85,14 +86,12 @@ public class JsonDiagram extends UmlDiagram {
}
public DiagramDescription getDescription() {
if (getUmlDiagramType() == UmlDiagramType.YAML) {
return new DiagramDescription("(Yaml)");
}
return new DiagramDescription("(Json)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.JSON;
}
@Override
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
@ -124,7 +123,8 @@ public class JsonDiagram extends UmlDiagram {
private void drawInternal(UGraphic ug) {
if (root == null) {
final Display display = Display.getWithNewlines("Your data does not sound like JSON data");
final Display display = Display
.getWithNewlines("Your data does not sound like " + getUmlDiagramType() + " data");
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.courier(14));
TextBlock result = display.create(fontConfiguration, HorizontalAlignment.LEFT, getSkinParam());
result = TextBlockUtils.withMargin(result, 5, 2);

View File

@ -41,6 +41,7 @@ import java.util.List;
import net.sourceforge.plantuml.BackSlash;
import net.sourceforge.plantuml.StringLocated;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.command.PSystemAbstractFactory;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.DiagramType;
@ -81,7 +82,9 @@ public class JsonDiagramFactory extends PSystemAbstractFactory {
} catch (ParseException e) {
json = null;
}
return new JsonDiagram(json, highlighted);
final JsonDiagram result = new JsonDiagram(UmlDiagramType.JSON, json, highlighted);
result.setSource(source);
return result;
}
}

View File

@ -80,16 +80,16 @@ public class SmetanaForJson {
private ST_Agraph_s g;
private StringBounder stringBounder;
private final List<Node> nodes = new ArrayList<Node>();
private final List<InternalNode> nodes = new ArrayList<InternalNode>();
private final List<ST_Agedge_s> edges = new ArrayList<ST_Agedge_s>();
private Mirror xMirror;
static class Node {
static class InternalNode {
private final TextBlockJson block;
private final ST_Agnode_s node;
public Node(TextBlockJson block, ST_Agnode_s node) {
public InternalNode(TextBlockJson block, ST_Agnode_s node) {
this.block = block;
this.node = node;
}
@ -118,7 +118,7 @@ public class SmetanaForJson {
final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted);
final ST_Agnode_s node1 = createNode(block.calculateDimension(stringBounder), block.size(), current.isArray(),
(int) block.getWidthColA(stringBounder), (int) block.getWidthColB(stringBounder));
nodes.add(new Node(block, node1));
nodes.add(new InternalNode(block, node1));
final List<JsonValue> children = block.children();
final List<String> keys = block.keys();
for (int i = 0; i < children.size(); i++) {
@ -151,12 +151,12 @@ public class SmetanaForJson {
public void drawMe(JsonValue root, List<String> highlighted) {
initGraph(root, highlighted);
double max = 0;
for (Node node : nodes) {
for (InternalNode node : nodes) {
max = Math.max(max, node.getMaxX());
}
xMirror = new Mirror(max);
for (Node node : nodes) {
for (InternalNode node : nodes) {
node.block.drawU(ug.apply(getPosition(node.node)));
}
final HColor color = getStyle().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());

View File

@ -42,8 +42,10 @@ 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.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
@ -54,6 +56,7 @@ public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandMindMapPlus.class.getName(), RegexLeaf.start(), //
new RegexLeaf("TYPE", "([+-]+)"), //
new RegexOptional(new RegexLeaf("BACKCOLOR", "\\[(#\\w+)\\]")), //
new RegexLeaf("SHAPE", "(_)?"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("LABEL", "([^%s].*)"), RegexLeaf.end());
@ -63,8 +66,13 @@ public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) {
final String type = arg.get("TYPE", 0);
final String label = arg.get("LABEL", 0);
final String stringColor = arg.get("BACKCOLOR", 0);
HColor backColor = null;
if (stringColor != null) {
backColor = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(stringColor);
}
final Direction direction = type.contains("-") ? Direction.LEFT : Direction.RIGHT;
return diagram.addIdea(null, type.length() - 1, Display.getWithNewlines(label),
return diagram.addIdea(backColor, type.length() - 1, Display.getWithNewlines(label),
IdeaShape.fromDesc(arg.get("SHAPE", 0)), direction);
}

View File

@ -87,9 +87,8 @@ public class MindMapDiagram extends UmlDiagram {
return new DiagramDescription("MindMap");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.MINDMAP;
public MindMapDiagram() {
super(UmlDiagramType.MINDMAP);
}
@Override

View File

@ -92,9 +92,8 @@ public class NwDiagram extends UmlDiagram {
return new DiagramDescription("(Nwdiag)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.NWDIAG;
public NwDiagram() {
super(UmlDiagramType.NWDIAG);
}
public void init() {

View File

@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.cucadiagram.Code;
@ -57,10 +58,10 @@ import net.sourceforge.plantuml.utils.UniqueSequence;
public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram {
public AbstractClassOrObjectDiagram(ISkinSimple orig) {
super(orig);
public AbstractClassOrObjectDiagram(UmlDiagramType type, ISkinSimple orig) {
super(type, orig);
}
@Override
public Ident cleanIdent(Ident ident) {
String codeString = ident.getName();
@ -70,18 +71,16 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
return ident;
}
final public boolean insertBetween(IEntity entity1, IEntity entity2, IEntity node) {
final Link link = foundLink(entity1, entity2);
if (link == null) {
return false;
}
final Link l1 = new Link(entity1, node, link.getType(), link.getLabel(), link.getLength(),
link.getQualifier1(), null, link.getLabeldistance(), link.getLabelangle(), getSkinParam()
.getCurrentStyleBuilder());
final Link l1 = new Link(entity1, node, link.getType(), link.getLabel(), link.getLength(), link.getQualifier1(),
null, link.getLabeldistance(), link.getLabelangle(), getSkinParam().getCurrentStyleBuilder());
final Link l2 = new Link(node, entity2, link.getType(), link.getLabel(), link.getLength(), null,
link.getQualifier2(), link.getLabeldistance(), link.getLabelangle(), getSkinParam()
.getCurrentStyleBuilder());
link.getQualifier2(), link.getLabeldistance(), link.getLabelangle(),
getSkinParam().getCurrentStyleBuilder());
addLink(l1);
addLink(l2);
removeLink(link);
@ -146,8 +145,8 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
insertPointBetween(entity2A, entity2B, point2);
final int length = 1;
final Link point1ToPoint2 = new Link(point1, point2, linkType, label, length, getSkinParam()
.getCurrentStyleBuilder());
final Link point1ToPoint2 = new Link(point1, point2, linkType, label, length,
getSkinParam().getCurrentStyleBuilder());
addLink(point1ToPoint2);
return CommandExecutionResult.ok();
@ -164,15 +163,15 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
removeLink(existingLink1);
}
final IEntity entity1real = existingLink1.isInverted() ? existingLink1.getEntity2() : existingLink1
.getEntity1();
final IEntity entity2real = existingLink1.isInverted() ? existingLink1.getEntity1() : existingLink1
.getEntity2();
final IEntity entity1real = existingLink1.isInverted() ? existingLink1.getEntity2()
: existingLink1.getEntity1();
final IEntity entity2real = existingLink1.isInverted() ? existingLink1.getEntity1()
: existingLink1.getEntity2();
final Link entity1ToPoint = new Link(entity1real, point1, existingLink1.getType().getPart2(),
existingLink1.getLabel(), existingLink1.getLength(), existingLink1.getQualifier1(), null,
existingLink1.getLabeldistance(), existingLink1.getLabelangle(), getSkinParam()
.getCurrentStyleBuilder());
existingLink1.getLabeldistance(), existingLink1.getLabelangle(),
getSkinParam().getCurrentStyleBuilder());
entity1ToPoint.setLinkArrow(existingLink1.getLinkArrow());
final Link pointToEntity2 = new Link(point1, entity2real, existingLink1.getType().getPart1(), Display.NULL,
existingLink1.getLength(), null, existingLink1.getQualifier2(), existingLink1.getLabeldistance(),
@ -267,16 +266,16 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
void createNew(int mode, LinkType linkType, Display label) {
existingLink = foundLink(entity1, entity2);
if (existingLink == null) {
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL,
2, getSkinParam().getCurrentStyleBuilder());
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL, 2,
getSkinParam().getCurrentStyleBuilder());
} else {
removeLink(existingLink);
}
final IEntity entity1real = existingLink.isInverted() ? existingLink.getEntity2() : existingLink
.getEntity1();
final IEntity entity2real = existingLink.isInverted() ? existingLink.getEntity1() : existingLink
.getEntity2();
final IEntity entity1real = existingLink.isInverted() ? existingLink.getEntity2()
: existingLink.getEntity1();
final IEntity entity2real = existingLink.isInverted() ? existingLink.getEntity1()
: existingLink.getEntity2();
entity1ToPoint = new Link(entity1real, point, existingLink.getType().getPart2(), existingLink.getLabel(),
existingLink.getLength(), existingLink.getQualifier1(), null, existingLink.getLabeldistance(),
@ -303,11 +302,11 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
addLink(pointToEntity2);
if (mode == 1) {
pointToAssocied = new Link(point, associed, linkType, label, length, getSkinParam()
.getCurrentStyleBuilder());
pointToAssocied = new Link(point, associed, linkType, label, length,
getSkinParam().getCurrentStyleBuilder());
} else {
pointToAssocied = new Link(associed, point, linkType, label, length, getSkinParam()
.getCurrentStyleBuilder());
pointToAssocied = new Link(associed, point, linkType, label, length,
getSkinParam().getCurrentStyleBuilder());
}
addLink(pointToAssocied);
}
@ -315,8 +314,8 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
void createInSecond(LinkType linkType, Display label) {
existingLink = foundLink(entity1, entity2);
if (existingLink == null) {
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL,
2, getSkinParam().getCurrentStyleBuilder());
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL, 2,
getSkinParam().getCurrentStyleBuilder());
} else {
removeLink(existingLink);
}

View File

@ -65,9 +65,8 @@ public class PostItDiagram extends UmlDiagram {
private final Map<String, PostIt> postIts = new HashMap<String, PostIt>();
@Override
public UmlDiagramType getUmlDiagramType() {
return null;
public PostItDiagram() {
super(UmlDiagramType.TIMING);
}
@Override

View File

@ -130,15 +130,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private Day printStart;
private Day printEnd;
private HColor linksColor = HColorUtils.RED_DARK;
private HColor linksColor = null;
public DiagramDescription getDescription() {
return new DiagramDescription("(Project)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.GANTT;
public GanttDiagram() {
super(UmlDiagramType.GANTT);
}
private int horizontalPages = 1;
@ -261,12 +260,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (openClose.getCalendar() == null) {
return new TimeHeaderSimple(min, max);
} else if (printScale == PrintScale.WEEKLY) {
return new TimeHeaderWeekly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays);
return new TimeHeaderWeekly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
nameDays);
} else if (printScale == PrintScale.MONTHLY) {
return new TimeHeaderMonthly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays);
return new TimeHeaderMonthly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
nameDays);
} else {
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays,
printStart, printEnd);
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
nameDays, printStart, printEnd);
}
}
@ -293,19 +294,17 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (printStart != null && constraint.isHidden(min, max)) {
continue;
}
// If the linksColor is the default color, we should try to get the arrow color (default is RED_DARK)
if (linksColor == HColorUtils.RED_DARK) {
constraint.getUDrawable(timeScale, getLinkColor(), this).drawU(ug);
} else {
constraint.getUDrawable(timeScale, linksColor, this).drawU(ug);
}
constraint.getUDrawable(timeScale, getLinkColor(), this).drawU(ug);
}
}
private HColor getLinkColor() {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(getCurrentStyleBuilder());
return styleArrow.value(PName.LineColor).asColor(colorSet);
if (linksColor == null) {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(getCurrentStyleBuilder());
return styleArrow.value(PName.LineColor).asColor(colorSet);
}
return linksColor;
}
public StyleSignature getDefaultStyleDefinitionArrow() {
@ -596,7 +595,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
return openClose.getLoadAt(day) > 0;
}
public void affectResource(Task result, String description) {
public boolean affectResource(Task result, String description) {
final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?");
final Matcher m = p.matcher(description);
if (m.find() == false) {
@ -607,7 +606,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (m.group(3) != null) {
percentage = Integer.parseInt(m.group(3));
}
if (percentage == 0) {
return false;
}
result.addResource(resource, percentage);
return true;
}
public Resource getResource(String resourceName) {
@ -677,7 +680,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
public void colorDay(DayOfWeek day, HColor color) {
colorDaysOfWeek.put(day, color);
}
public void nameDay(Day day, String name) {
nameDays.put(day, name);
}
@ -734,4 +737,4 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
}
}
}

View File

@ -103,7 +103,7 @@ public class TimeHeaderDaily extends TimeHeader {
final double x2 = getTimeScale().getEndingPosition(wink);
HColor back = colorDays.get(wink);
// Day of week should be stronger than period of time (back color).
HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
if (backDoW != null) {
back = backDoW;
}

View File

@ -102,7 +102,7 @@ public class TimeHeaderWeekly extends TimeHeader {
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
HColor back = colorDays.get(wink);
// Day of week should be stronger than period of time (back color).
HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
if (backDoW != null) {
back = backDoW;
}

View File

@ -63,7 +63,10 @@ public class SubjectTask implements Subject {
for (final StringTokenizer st = new StringTokenizer(resource, "{}"); st.hasMoreTokens();) {
final String part = st.nextToken().trim();
if (part.length() > 0) {
project.affectResource(result, part);
final boolean ok = project.affectResource(result, part);
if (ok == false) {
return Failable.error("Bad argument for resource");
}
}
}

View File

@ -52,9 +52,14 @@ public class SolverImpl extends AbstractSolver implements Solver {
protected Day computeEnd() {
Day current = (Day) values.get(TaskAttribute.START);
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
int cpt = 0;
while (fullLoad > 0) {
fullLoad -= loadPlanable.getLoadAt(current);
current = current.increment();
cpt++;
if (cpt > 100000) {
throw new IllegalStateException();
}
}
return current.decrement();
}
@ -63,12 +68,17 @@ public class SolverImpl extends AbstractSolver implements Solver {
protected Day computeStart() {
Day current = (Day) values.get(TaskAttribute.END);
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
int cpt = 0;
while (fullLoad > 0) {
fullLoad -= loadPlanable.getLoadAt(current);
current = current.decrement();
if (current.getMillis() <= 0) {
return current;
}
cpt++;
if (cpt > 100000) {
throw new IllegalStateException();
}
}
return current.increment();
}

View File

@ -104,6 +104,7 @@ public class PSystemSalt extends TitledDiagram implements WithSprite {
@Deprecated
public PSystemSalt(List<String> data) {
super(UmlDiagramType.SALT);
this.data = data;
}
@ -280,11 +281,6 @@ public class PSystemSalt extends TitledDiagram implements WithSprite {
this.iamSalt = true;
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.SALT;
}
public final boolean isIamSalt() {
return iamSalt;
}

View File

@ -81,7 +81,7 @@ public class SequenceDiagram extends UmlDiagram {
private final Rose skin2 = new Rose();
public SequenceDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.SEQUENCE, skinParam);
}
@Deprecated
@ -388,11 +388,6 @@ public class SequenceDiagram extends UmlDiagram {
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.SEQUENCE;
}
private ParticipantEnglober participantEnglober;
public void boxStart(Display comment, HColor color, Stereotype stereotype) {

View File

@ -112,7 +112,9 @@ public class CommandArrow extends SingleLineCommand2<SequenceDiagram> {
new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
RegexLeaf.spaceZeroOrMore(), new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), RegexLeaf.end());
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
RegexLeaf.end());
}
private Participant getOrCreateParticipant(SequenceDiagram system, RegexResult arg2, String n) {

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.skin;
public enum ArrowDirection {
LEFT_TO_RIGHT_NORMAL, RIGHT_TO_LEFT_REVERSE, SELF, BOTH_DIRECTION;

View File

@ -68,18 +68,13 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class ListSpriteDiagram extends UmlDiagram {
public ListSpriteDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.HELP, skinParam);
}
public DiagramDescription getDescription() {
return new DiagramDescription("(Sprites)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.HELP;
}
@Override
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {

View File

@ -77,18 +77,13 @@ public class StdlibDiagram extends UmlDiagram {
private String name;
public StdlibDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.HELP, skinParam);
}
public DiagramDescription getDescription() {
return new DiagramDescription("(Sprites)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.HELP;
}
@Override
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {

View File

@ -57,7 +57,7 @@ public class StateDiagram extends AbstractEntityDiagram {
private static final String CONCURRENT_PREFIX = "CONC";
public StateDiagram(ISkinSimple skinParam) {
super(skinParam);
super(UmlDiagramType.STATE, skinParam);
// setNamespaceSeparator(null);
}
@ -260,11 +260,6 @@ public class StateDiagram extends AbstractEntityDiagram {
super.endGroup();
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.STATE;
}
private boolean hideEmptyDescription = false;
@Override

View File

@ -57,6 +57,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.png.PngIO;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
@ -88,7 +89,7 @@ public class GraphicsSudoku {
public ImageData writeImageSvg(OutputStream os) throws IOException {
final UGraphicSvg ug = new UGraphicSvg(true, new Dimension2DDouble(0, 0), new ColorMapperIdentity(),
(String) null, false, 1.0, null, null, 0, "none", SvgCharSizeHack.NO_HACK);
(String) null, false, 1.0, null, null, 0, "none", SvgCharSizeHack.NO_HACK, LengthAdjust.defaultValue());
drawInternal(ug);
ug.createXml(os, null);
return ImageDataSimple.ok();

View File

@ -110,8 +110,9 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
public static void checkOldVersionWarning(List<String> strings) {
final long days = (System.currentTimeMillis() - Version.compileTime()) / 1000L / 3600 / 24;
if (days >= 90) {
strings.add("This version of PlantUML is " + days + " days old, so you should");
strings.add(" consider upgrading from https://plantuml.com/download");
strings.add(" ");
strings.add("<b>This version of PlantUML is " + days + " days old, so you should");
strings.add("<b>consider upgrading from https://plantuml.com/download");
}
}

View File

@ -0,0 +1,44 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.svg;
public enum LengthAdjust {
NONE, SPACING, SPACING_AND_GLYPHS;
public static LengthAdjust defaultValue() {
return SPACING;
}
}

View File

@ -118,6 +118,7 @@ public class SvgGraphics {
private final String shadowId;
private final String gradientId;
private final boolean svgDimensionStyle;
private final LengthAdjust lengthAdjust;
final protected void ensureVisible(double x, double y) {
if (x > maxX) {
@ -129,13 +130,14 @@ public class SvgGraphics {
}
public SvgGraphics(boolean svgDimensionStyle, Dimension2D minDim, double scale, String hover, long seed,
String preserveAspectRatio) {
this(svgDimensionStyle, minDim, null, scale, hover, seed, preserveAspectRatio);
String preserveAspectRatio, LengthAdjust lengthAdjust) {
this(svgDimensionStyle, minDim, null, scale, hover, seed, preserveAspectRatio, lengthAdjust);
}
public SvgGraphics(boolean svgDimensionStyle, Dimension2D minDim, String backcolor, double scale, String hover,
long seed, String preserveAspectRatio) {
long seed, String preserveAspectRatio, LengthAdjust lengthAdjust) {
try {
this.lengthAdjust = lengthAdjust;
this.svgDimensionStyle = svgDimensionStyle;
this.scale = scale;
this.document = getDocument();
@ -436,8 +438,15 @@ public class SvgGraphics {
fillMe(elt);
elt.setAttribute("font-size", format(fontSize));
// elt.setAttribute("text-anchor", "middle");
elt.setAttribute("lengthAdjust", "spacingAndGlyphs");
elt.setAttribute("textLength", format(textLength));
if (lengthAdjust == LengthAdjust.SPACING) {
elt.setAttribute("lengthAdjust", "spacing");
elt.setAttribute("textLength", format(textLength));
} else if (lengthAdjust == LengthAdjust.SPACING_AND_GLYPHS) {
elt.setAttribute("lengthAdjust", "spacingAndGlyphs");
elt.setAttribute("textLength", format(textLength));
}
if (fontWeight != null) {
elt.setAttribute("font-weight", fontWeight);
}

View File

@ -218,6 +218,12 @@ public abstract class Eater {
return s.charAt(i);
}
final public boolean matchAffectation() {
final String tmp = s.substring(i);
final boolean result = tmp.matches("^\\$?[_\\p{L}][_\\p{L}0-9]*\\s*=.*");
return result;
}
final public char peekCharN2() {
if (i + 1 >= s.length()) {
return 0;

View File

@ -74,20 +74,34 @@ public class EaterFunctionCall extends Eater {
final TValue result = TValue.fromString(value);
values.add(result);
} else if (unquoted) {
final String read = eatAndGetOptionalQuotedString();
if (TokenStack.isSpecialAffectationWhenFunctionCall(read)) {
updateNamedArguments(read, context, memory);
if (matchAffectation()) {
final String varname = eatAndGetVarname();
skipSpaces();
checkAndEatChar('=');
skipSpaces();
final String read = eatAndGetOptionalQuotedString();
final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read);
final TValue result = TValue.fromString(value);
namedArguments.put(varname, result);
} else {
final String read = eatAndGetOptionalQuotedString();
final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read);
final TValue result = TValue.fromString(value);
values.add(result);
}
// }
} else {
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
if (tokens.isSpecialAffectationWhenFunctionCall()) {
final String special = tokens.tokenIterator().nextToken().getSurface();
updateNamedArguments(special, context, memory);
if (matchAffectation()) {
final String varname = eatAndGetVarname();
skipSpaces();
checkAndEatChar('=');
skipSpaces();
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
tokens.guessFunctions();
final TValue result = tokens.getResult(getLineLocation(), context, memory);
namedArguments.put(varname, result);
} else {
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
tokens.guessFunctions();
final TValue result = tokens.getResult(getLineLocation(), context, memory);
values.add(result);
@ -108,16 +122,6 @@ public class EaterFunctionCall extends Eater {
}
}
private void updateNamedArguments(String special, TContext context, TMemory memory)
throws EaterException, EaterExceptionLocated {
assert special.contains("=");
final StringEater stringEater = new StringEater(special);
final String varname = stringEater.eatAndGetVarname();
stringEater.checkAndEatChar('=');
final TValue expr = stringEater.eatExpression(context, memory);
namedArguments.put(varname, expr);
}
public final List<TValue> getValues() {
return Collections.unmodifiableList(values);
}

View File

@ -47,39 +47,38 @@ import net.sourceforge.plantuml.tim.Eater;
import net.sourceforge.plantuml.tim.EaterException;
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
import net.sourceforge.plantuml.tim.TContext;
import net.sourceforge.plantuml.tim.TLineType;
import net.sourceforge.plantuml.tim.TMemory;
public class TokenStack {
final private List<Token> tokens;
public boolean isSpecialAffectationWhenFunctionCall() {
if (tokens.size() != 1) {
return false;
}
final Token single = tokens.get(0);
if (single.getTokenType() != TokenType.PLAIN_TEXT) {
return false;
}
return isSpecialAffectationWhenFunctionCall(single.getSurface());
}
public static boolean isSpecialAffectationWhenFunctionCall(String surface) {
final int idx = surface.indexOf('=');
if (idx <= 0) {
return false;
}
if (TLineType.isLetterOrUnderscoreOrDollar(surface.charAt(0)) == false) {
return false;
}
for (int i = 1; i < idx; i++) {
if (TLineType.isLetterOrUnderscoreOrDigit(surface.charAt(i)) == false) {
return false;
}
}
return true;
}
// public boolean isSpecialAffectationWhenFunctionCall() {
// if (tokens.size() != 1) {
// return false;
// }
// final Token single = tokens.get(0);
// if (single.getTokenType() != TokenType.PLAIN_TEXT) {
// return false;
// }
// return isSpecialAffectationWhenFunctionCall(single.getSurface());
// }
//
// public static boolean isSpecialAffectationWhenFunctionCall(String surface) {
// final int idx = surface.indexOf('=');
// if (idx <= 0) {
// return false;
// }
// if (TLineType.isLetterOrUnderscoreOrDollar(surface.charAt(0)) == false) {
// return false;
// }
// for (int i = 1; i < idx; i++) {
// if (TLineType.isLetterOrUnderscoreOrDigit(surface.charAt(i)) == false) {
// return false;
// }
// }
// return true;
// }
public TokenStack() {
this(new ArrayList<Token>());

View File

@ -95,9 +95,8 @@ public class TimingDiagram extends UmlDiagram implements Clocks {
return new DiagramDescription("(Timing Diagram)");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.TIMING;
public TimingDiagram() {
super(UmlDiagramType.TIMING);
}
@Override

View File

@ -60,6 +60,7 @@ import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.security.ImageIO;
import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.svg.SvgGraphics;
import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
@ -159,7 +160,8 @@ public class FontChecker {
}
private String getSvgImage(char c) throws IOException, TransformerException {
final SvgGraphics svg = new SvgGraphics(true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none");
final SvgGraphics svg = new SvgGraphics(true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none",
LengthAdjust.defaultValue());
svg.setStrokeColor("black");
svg.svgImage(getBufferedImage(c), 0, 0);
final ByteArrayOutputStream os = new ByteArrayOutputStream();

View File

@ -71,6 +71,7 @@ import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.mjpeg.MJPEGGenerator;
import net.sourceforge.plantuml.security.ImageIO;
import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorBackground;
@ -283,7 +284,8 @@ public class ImageBuilder {
option.getWatermark());
case SVG:
return createUGraphicSVG(colorMapper, param.getDpiFactor(), dim, param.getBackcolor(),
option.getSvgLinkTarget(), option.getHoverColor(), seed, option.getPreserveAspectRatio());
option.getSvgLinkTarget(), option.getHoverColor(), seed, option.getPreserveAspectRatio(),
param.getlengthAdjust());
case EPS:
return new UGraphicEps(colorMapper, EpsStrategy.getDefault2());
case EPS_TEXT:
@ -307,7 +309,7 @@ public class ImageBuilder {
}
private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, final HColor suggested,
String svgLinkTarget, String hover, long seed, String preserveAspectRatio) {
String svgLinkTarget, String hover, long seed, String preserveAspectRatio, LengthAdjust lengthAdjust) {
HColor backColor = HColorUtils.WHITE;
if (suggested instanceof HColorSimple) {
backColor = suggested;
@ -316,14 +318,15 @@ public class ImageBuilder {
final UGraphicSvg ug;
if (suggested instanceof HColorGradient) {
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, (HColorGradient) suggested, false, scale,
svgLinkTarget, hover, seed, preserveAspectRatio, param.getSvgCharSizeHack());
svgLinkTarget, hover, seed, preserveAspectRatio, param.getSvgCharSizeHack(),
param.getlengthAdjust());
} else if (backColor == null || colorMapper.toColor(backColor).equals(Color.WHITE)) {
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, false, scale, svgLinkTarget, hover, seed,
preserveAspectRatio, param.getSvgCharSizeHack());
preserveAspectRatio, param.getSvgCharSizeHack(), param.getlengthAdjust());
} else {
final String tmp = colorMapper.toSvg(backColor);
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, tmp, false, scale, svgLinkTarget, hover, seed,
preserveAspectRatio, param.getSvgCharSizeHack());
preserveAspectRatio, param.getSvgCharSizeHack(), param.getlengthAdjust());
}
return ug;

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.SvgCharSizeHack;
import net.sourceforge.plantuml.anim.Animation;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
@ -58,6 +59,7 @@ public class ImageParameter {
private final HColor backcolor;
private final boolean svgDimensionStyle;
private final SvgCharSizeHack svgCharSizeHack;
private final LengthAdjust lengthAdjust;
private final UStroke borderStroke;
private final HColor borderColor;
@ -79,6 +81,7 @@ public class ImageParameter {
this.borderCorner = 0;
this.borderStroke = null;
this.svgCharSizeHack = SvgCharSizeHack.NO_HACK;
this.lengthAdjust = LengthAdjust.defaultValue();
}
public ImageParameter(ISkinParam skinParam, Animation animation, double dpiFactor, String metadata,
@ -104,6 +107,7 @@ public class ImageParameter {
}
this.svgCharSizeHack = skinParam;
this.lengthAdjust = skinParam.getlengthAdjust();
}
@ -159,4 +163,8 @@ public class ImageParameter {
return svgCharSizeHack;
}
public final LengthAdjust getlengthAdjust() {
return lengthAdjust;
}
}

View File

@ -48,6 +48,7 @@ import net.sourceforge.plantuml.SvgCharSizeHack;
import net.sourceforge.plantuml.eps.EpsStrategy;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.png.PngIO;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps;
@ -66,7 +67,8 @@ public abstract class UGraphicUtils {
final Dimension2D size = computeSize(colorMapper, background, image);
final UGraphicSvg svg = new UGraphicSvg(true, size, colorMapper, colorMapper.toRGB(background), false, 1.0,
fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor(), seed,
fileFormatOption.getPreserveAspectRatio(), SvgCharSizeHack.NO_HACK);
fileFormatOption.getPreserveAspectRatio(), SvgCharSizeHack.NO_HACK,
LengthAdjust.defaultValue());
image.drawU(svg);
svg.createXml(os, fileFormatOption.isWithMetadata() ? metadata : null);
} else if (fileFormat == FileFormat.EPS) {

View File

@ -44,16 +44,26 @@ public class UText implements UShape {
private final String text;
private final FontConfiguration font;
private final int orientation;
@Override
public String toString() {
return "UText[" + text + "]";
}
public UText(String text, FontConfiguration font) {
private UText(String text, FontConfiguration font, int orientation) {
assert text.indexOf('\t') == -1;
this.text = text;
this.font = font;
this.orientation = orientation;
}
public UText(String text, FontConfiguration font) {
this(text, font, 0);
}
public UText withOrientation(int orientation) {
return new UText(text, font, orientation);
}
public String getText() {
@ -70,4 +80,8 @@ public class UText implements UShape {
return descent;
}
public final int getOrientation() {
return orientation;
}
}

View File

@ -40,19 +40,20 @@ import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.util.List;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.EnsureVisible;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.TikzFontDistortion;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.FontStyle;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.StyledString;
import net.sourceforge.plantuml.ugraphic.UDriver;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UParam;
@ -70,83 +71,108 @@ public class DriverTextG2d implements UDriver<Graphics2D> {
this.visible = visible;
}
private static void printFont() {
final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
final String fontNames[] = ge.getAvailableFontFamilyNames();
final int j = fontNames.length;
for (int i = 0; i < j; i++) {
Log.info("Available fonts: " + fontNames[i]);
}
}
public void draw(UShape ushape, double x, double y, ColorMapper mapper, UParam param, Graphics2D g2d) {
final UText shape = (UText) ushape;
final FontConfiguration fontConfiguration = shape.getFontConfiguration();
final String text = shape.getText();
final List<StyledString> strings = StyledString.build(text);
final UFont font = fontConfiguration.getFont().scaled(param.getScale());
final Dimension2D dimBack = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
for (StyledString styledString : strings) {
final FontConfiguration fc = styledString.getStyle() == FontStyle.BOLD ? fontConfiguration.bold()
: fontConfiguration;
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), fc.getFont(),
styledString.getText());
printSingleText(g2d, fc, styledString.getText(), x, y, mapper, param);
x += dim.getWidth();
}
}
private void printSingleText(Graphics2D g2d, final FontConfiguration fontConfiguration, final String text, double x,
double y, ColorMapper mapper, UParam param) {
final UFont font = fontConfiguration.getFont().scaled(param.getScale());
final HColor extended = fontConfiguration.getExtendedColor();
if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) {
final Rectangle2D.Double area = new Rectangle2D.Double(x, y - dimBack.getHeight() + 1.5, dimBack.getWidth(),
dimBack.getHeight());
if (extended instanceof HColorGradient) {
final GradientPaint paint = DriverRectangleG2d.getPaintGradient(x, y, mapper, dimBack.getWidth(),
dimBack.getHeight(), extended);
g2d.setPaint(paint);
g2d.fill(area);
} else {
final Color backColor = mapper.toColor(extended);
if (backColor != null) {
g2d.setColor(backColor);
g2d.setBackground(backColor);
final int orientation = 0;
if (orientation == 90) {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(font.getFont());
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
final AffineTransform orig = g2d.getTransform();
g2d.translate(x, y);
g2d.rotate(Math.PI / 2);
g2d.drawString(text, 0, 0);
g2d.setTransform(orig);
} else if (orientation == 0) {
final Dimension2D dimBack = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) {
final Rectangle2D.Double area = new Rectangle2D.Double(x, y - dimBack.getHeight() + 1.5,
dimBack.getWidth(), dimBack.getHeight());
if (extended instanceof HColorGradient) {
final GradientPaint paint = DriverRectangleG2d.getPaintGradient(x, y, mapper, dimBack.getWidth(),
dimBack.getHeight(), extended);
g2d.setPaint(paint);
g2d.fill(area);
} else {
final Color backColor = mapper.toColor(extended);
if (backColor != null) {
g2d.setColor(backColor);
g2d.setBackground(backColor);
g2d.fill(area);
}
}
}
}
visible.ensureVisible(x, y - dimBack.getHeight() + 1.5);
visible.ensureVisible(x + dimBack.getWidth(), y + 1.5);
visible.ensureVisible(x, y - dimBack.getHeight() + 1.5);
visible.ensureVisible(x + dimBack.getWidth(), y + 1.5);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(font.getFont());
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
g2d.drawString(shape.getText(), (float) x, (float) y);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(font.getFont());
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
g2d.drawString(text, (float) x, (float) y);
if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) {
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) {
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
}
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
final int ypos = (int) (y + 2.5);
g2d.setStroke(new BasicStroke((float) 1));
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
g2d.setStroke(new BasicStroke());
}
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
final int ypos = (int) (y + 2.5);
g2d.setStroke(new BasicStroke((float) 1));
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
g2d.setStroke(new BasicStroke());
}
if (fontConfiguration.containsStyle(FontStyle.WAVE)) {
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
final int ypos = (int) (y + 2.5) - 1;
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
if (fontConfiguration.containsStyle(FontStyle.WAVE)) {
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
final int ypos = (int) (y + 2.5) - 1;
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
}
for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) {
g2d.drawLine(i, ypos - 0, i + 3, ypos + 1);
g2d.drawLine(i + 3, ypos + 1, i + 6, ypos - 0);
}
}
for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) {
g2d.drawLine(i, ypos - 0, i + 3, ypos + 1);
g2d.drawLine(i + 3, ypos + 1, i + 6, ypos - 0);
if (fontConfiguration.containsStyle(FontStyle.STRIKE)) {
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
final FontMetrics fm = g2d.getFontMetrics(font.getFont());
final int ypos = (int) (y - fm.getDescent() - 0.5);
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
}
g2d.setStroke(new BasicStroke((float) 1.5));
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
g2d.setStroke(new BasicStroke());
}
}
if (fontConfiguration.containsStyle(FontStyle.STRIKE)) {
final Dimension2D dim = calculateDimension(
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
final FontMetrics fm = g2d.getFontMetrics(font.getFont());
final int ypos = (int) (y - fm.getDescent() - 0.5);
if (extended != null) {
g2d.setColor(mapper.toColor(extended));
}
g2d.setStroke(new BasicStroke((float) 1.5));
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
g2d.setStroke(new BasicStroke());
}
}
static public Dimension2D calculateDimension(StringBounder stringBounder, UFont font, String text) {

View File

@ -47,6 +47,7 @@ import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.posimo.DotPath;
import net.sourceforge.plantuml.svg.LengthAdjust;
import net.sourceforge.plantuml.svg.SvgGraphics;
import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic;
import net.sourceforge.plantuml.ugraphic.AbstractUGraphic;
@ -90,23 +91,24 @@ public class UGraphicSvg extends AbstractUGraphic<SvgGraphics> implements ClipCo
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, String backcolor,
boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
SvgCharSizeHack charSizeHack) {
this(minDim, colorMapper,
new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed, preserveAspectRatio),
textAsPath, linkTarget, charSizeHack);
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
this(minDim, colorMapper, new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed,
preserveAspectRatio, lengthAdjust), textAsPath, linkTarget, charSizeHack);
}
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, boolean textAsPath,
double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
SvgCharSizeHack charSizeHack) {
this(minDim, colorMapper, new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio),
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
this(minDim, colorMapper,
new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio, lengthAdjust),
textAsPath, linkTarget, charSizeHack);
}
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper mapper, HColorGradient gr,
boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
SvgCharSizeHack charSizeHack) {
this(minDim, mapper, new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio),
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
this(minDim, mapper,
new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio, lengthAdjust),
textAsPath, linkTarget, charSizeHack);
final SvgGraphics svg = getGraphicObject();

View File

@ -44,7 +44,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000;
public static int version() {
return 1202026;
return 1202100;
}
public static int versionPatched() {
@ -93,7 +93,7 @@ public class Version {
}
public static long compileTime() {
return 1608572707669L;
return 1610274305536L;
}
public static String compileTimeString() {

View File

@ -75,9 +75,8 @@ public class WBSDiagram extends UmlDiagram {
return new DiagramDescription("Work Breakdown Structure");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.WBS;
public WBSDiagram() {
super(UmlDiagramType.WBS);
}
@Override

View File

@ -43,6 +43,8 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class CommandComponent extends SingleLineCommand2<WireDiagram> {
@ -53,7 +55,9 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandComponent.class.getName(), RegexLeaf.start(), //
new RegexLeaf("INDENT", "([\\s\\t]*)"), //
new RegexLeaf("NAME", "\\$([\\w]+)"), //
new RegexLeaf("\\*"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NAME", "([\\w]+)"), //
new RegexOptional(new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\["), //
@ -62,6 +66,9 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
new RegexLeaf("HEIGHT", "([\\d]+)"), //
new RegexLeaf("\\]")) //
), //
new RegexOptional(new RegexConcat( //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("COLOR", "(#\\w+)?"))), //
RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end());
}
@ -80,7 +87,13 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
height = Integer.parseInt(heightString);
}
return diagram.addComponent(indent, name, width, height);
final String stringColor = arg.get("COLOR", 0);
HColor color = null;
if (stringColor != null) {
color = HColorSet.instance().getColorIfValid(stringColor);
}
return diagram.addComponent(indent, name, width, height, color);
}
}

View File

@ -0,0 +1,78 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.wire;
import net.sourceforge.plantuml.LineLocation;
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;
public class CommandPrint extends SingleLineCommand2<WireDiagram> {
public CommandPrint() {
super(false, getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandPrint.class.getName(), RegexLeaf.start(), //
new RegexLeaf("INDENT", "([\\s\\t]*)"), //
new RegexLeaf("print"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("\\("), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("[%g]"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TEXT", "(.*)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("[%g]"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) {
final String indent = arg.get("INDENT", 0);
final String text = arg.get("TEXT", 0);
return diagram.print(indent, text);
}
}

View File

@ -56,7 +56,7 @@ public class CommandSpot extends SingleLineCommand2<WireDiagram> {
return RegexConcat.build(CommandSpot.class.getName(), RegexLeaf.start(), //
new RegexLeaf("spot"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", "\\$([\\w][.\\w]*)"), //
new RegexLeaf("NAME", "([\\w][.\\w]*)"), //
new RegexOptional(new RegexConcat(//
new RegexLeaf("\\("), //
RegexLeaf.spaceZeroOrMore(), //

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -54,7 +55,7 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandWLink.class.getName(), RegexLeaf.start(), //
new RegexLeaf("NAME1", "\\$([\\w][.\\w]*)"), //
new RegexLeaf("NAME1", "([\\w][.\\w]*)"), //
new RegexOptional(new RegexConcat(//
new RegexLeaf("\\("), //
RegexLeaf.spaceZeroOrMore(), //
@ -67,13 +68,15 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
new RegexLeaf("\\)") //
)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "([-=])\\>"), //
new RegexLeaf("STYLE", "(\\<?[-=]{1,2}\\>|\\<?[-=]{1,2})"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NAME2", "\\$([\\w][.\\w]*)"), //
new RegexLeaf("NAME2", "([\\w][.\\w]*)"), //
new RegexOptional(new RegexConcat( //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("COLOR", "(#\\w+)?"))), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end());
}
@ -83,9 +86,12 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
final String name1 = arg.get("NAME1", 0);
final String x1 = arg.get("X1", 0);
final String y1 = arg.get("Y1", 0);
final String name2 = arg.get("NAME2", 0);
final WLinkType type = WLinkType.from(arg.get("STYLE", 0));
final String style = arg.get("STYLE", 0);
final WLinkType type = WLinkType.from(style);
final WArrowDirection direction = WArrowDirection.from(style);
final WOrientation orientation = WOrientation.from(style);
final String stringColor = arg.get("COLOR", 0);
HColor color = null;
@ -93,7 +99,18 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
color = HColorSet.instance().getColorIfValid(stringColor);
}
return diagram.link(name1, x1, y1, name2, type, color);
final Display label;
if (arg.get("MESSAGE", 0) == null) {
label = Display.NULL;
} else {
final String message = arg.get("MESSAGE", 0);
label = Display.getWithNewlines(message);
}
if (orientation == WOrientation.VERTICAL) {
return diagram.vlink(name1, x1, y1, name2, type, direction, color, label);
}
return diagram.hlink(name1, x1, y1, name2, type, direction, color, label);
}
}

View File

@ -0,0 +1,54 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.wire;
public enum WArrowDirection {
NORMAL, REVERSE, BOTH, NONE;
public static WArrowDirection from(String type) {
if (type.contains("<") && type.contains(">")) {
return BOTH;
}
if (type.contains(">")) {
return NORMAL;
}
if (type.contains("<")) {
return REVERSE;
}
return NONE;
}
}

View File

@ -41,30 +41,41 @@ import java.util.List;
import java.util.StringTokenizer;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.cucadiagram.Display;
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.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class WBlock {
private final static int STARTING_Y = 10;
private final String name;
private final double forcedWidth;
private final double forcedHeight;
private final HColor color;
private final List<WBlock> children = new ArrayList<WBlock>();
private UTranslate position = new UTranslate();
private final UTranslate position;
private WBlock parent;
private UTranslate futureGoto;
private UTranslate futureMove = new UTranslate(0, 20);
private UTranslate cursor = new UTranslate(10, STARTING_Y);
private WBlock addedToCursor = null;
private UTranslate futureOutHorizontal;
private UTranslate futureOutVertical;
private final List<WPrint> prints = new ArrayList<WPrint>();
public UTranslate getAbsolutePosition(String supx, String supy) {
if (parent == null) {
@ -113,10 +124,12 @@ public class WBlock {
return name + " " + position;
}
public WBlock(String name, double width, double height) {
public WBlock(String name, UTranslate position, double width, double height, HColor color) {
this.name = name;
this.forcedWidth = width;
this.forcedHeight = height;
this.color = color;
this.position = position;
}
private WBlock getChildByName(String name) {
@ -147,8 +160,8 @@ public class WBlock {
public CommandExecutionResult newColumn(int level) {
if (level == 0) {
final Dimension2D max = getNaturalDimension();
futureGoto = new UTranslate(max.getWidth() + 10, 20);
futureMove = new UTranslate();
this.cursor = new UTranslate(max.getWidth() + 10, STARTING_Y);
this.addedToCursor = null;
return CommandExecutionResult.ok();
}
return getLastChild().newColumn(level - 1);
@ -156,8 +169,8 @@ public class WBlock {
public CommandExecutionResult wgoto(int level, double x, double y) {
if (level == 0) {
futureGoto = new UTranslate(x, y);
futureMove = new UTranslate();
this.cursor = new UTranslate(x, y);
this.addedToCursor = null;
return CommandExecutionResult.ok();
}
return getLastChild().wgoto(level - 1, x, y);
@ -165,13 +178,24 @@ public class WBlock {
public CommandExecutionResult wmove(int level, double x, double y) {
if (level == 0) {
futureMove = futureMove.compose(new UTranslate(x, y));
this.cursor = this.cursor.compose(new UTranslate(x, y));
return CommandExecutionResult.ok();
}
return getLastChild().wmove(level - 1, x, y);
}
public CommandExecutionResult addComponent(int level, String name, double width, double height) {
public CommandExecutionResult print(StringBounder stringBounder, ISkinParam skinParam, int level, String text) {
if (level == 0) {
final WPrint print = new WPrint(skinParam, getNextPosition(), null, Display.getWithNewlines(text));
this.prints.add(print);
this.cursor = this.cursor.compose(UTranslate.dy(print.getHeight(stringBounder)));
return CommandExecutionResult.ok();
}
return getLastChild().print(stringBounder, skinParam, level - 1, text);
}
public CommandExecutionResult addBlock(int level, String name, double width, double height, HColor color) {
if (name.contains(".")) {
throw new IllegalArgumentException();
}
@ -179,8 +203,10 @@ public class WBlock {
return CommandExecutionResult.error("Component exists already");
}
if (level == 0) {
final WBlock newBlock = new WBlock(name, width, height);
newBlock.position = getNextPosition();
this.cursor = this.cursor.compose(UTranslate.dy(10));
final WBlock newBlock = new WBlock(name, getNextPosition(), width, height, color);
this.cursor = this.cursor.compose(UTranslate.dy(10));
this.addedToCursor = newBlock;
children.add(newBlock);
newBlock.parent = this;
@ -188,25 +214,16 @@ public class WBlock {
}
final WBlock last = getLastChild();
return last.addComponent(level - 1, name, width, height);
return last.addBlock(level - 1, name, width, height, color);
}
private UTranslate getNextPosition() {
final UTranslate result;
if (futureGoto != null) {
result = futureGoto.compose(futureMove);
} else {
final WBlock last = getLastChild();
if (last == null) {
result = futureMove.compose(UTranslate.dx(10));
} else {
final Dimension2D dim = last.getMaxDimension();
result = last.position.compose(UTranslate.dy(dim.getHeight())).compose(futureMove);
}
if (this.addedToCursor != null) {
final Dimension2D dim = this.addedToCursor.getMaxDimension();
this.cursor = this.cursor.compose(UTranslate.dy(dim.getHeight()));
}
futureGoto = null;
futureMove = new UTranslate(0, 20);
return result;
this.addedToCursor = null;
return this.cursor;
}
private WBlock getLastChild() {
@ -230,11 +247,18 @@ public class WBlock {
ug = ug.apply(HColorUtils.BLACK);
if (name.length() > 0) {
final URectangle rect = new URectangle(getMaxDimension());
ug.draw(rect);
UGraphic ugRect = ug;
if (color != null) {
ugRect = ugRect.apply(color.bg());
}
ugRect.draw(rect);
}
for (WBlock child : children) {
child.drawMe(ug.apply(child.position));
}
for (WPrint print : prints) {
print.drawMe(ug.apply(print.getPosition()));
}
}
private Dimension2D getMaxDimension() {
@ -260,20 +284,29 @@ public class WBlock {
return new Dimension2DDouble(x, y);
}
private UTranslate futureOut;
public UTranslate getNextOut(String x1, String y1, WLinkType type) {
public UTranslate getNextOutHorizontal(String x, String y, WLinkType type) {
final UTranslate result;
if (x1 != null && y1 != null) {
result = getAbsolutePosition(x1, y1);
} else if (futureOut == null) {
if (x != null && y != null) {
result = getAbsolutePosition(x, y);
} else if (futureOutHorizontal == null) {
result = getAbsolutePosition("100%", "5");
} else {
result = futureOut;
result = futureOutHorizontal;
}
futureOutHorizontal = result.compose(UTranslate.dy(type.spaceForNext()));
return result;
}
futureOut = result.compose(UTranslate.dy(type.ySpaceForNext()));
public UTranslate getNextOutVertical(String x, String y, WLinkType type) {
final UTranslate result;
if (x != null && y != null) {
result = getAbsolutePosition(x, y);
} else if (futureOutVertical == null) {
result = getAbsolutePosition("5", "100%");
} else {
result = futureOutVertical;
}
futureOutVertical = result.compose(UTranslate.dx(type.spaceForNext()));
return result;
}

View File

@ -0,0 +1,197 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.wire;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class WLinkHorizontal {
private final UTranslate start;
private final double destination;
private final WLinkType type;
private final WArrowDirection direction;
private final HColor color;
private final Display label;
private final ISkinParam skinParam;
public WLinkHorizontal(ISkinParam skinParam, UTranslate start, double destination, WLinkType type,
WArrowDirection direction, HColor color, Display label) {
this.start = start;
this.destination = destination;
this.skinParam = skinParam;
this.direction = direction;
this.type = type;
this.label = label;
this.color = color == null ? HColorUtils.BLACK : color;
}
private TextBlock getTextBlock() {
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
.changeColor(color);
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
}
public void drawMe(UGraphic ug) {
ug = ug.apply(color);
final TextBlock textBlock = getTextBlock();
final Dimension2D dimText = textBlock.calculateDimension(ug.getStringBounder());
UGraphic ugText = ug.apply(start);
final double len = destination - start.getDx();
if (type == WLinkType.NORMAL) {
ug = ug.apply(color.bg());
drawNormalArrow(ug);
ugText = ugText.apply(UTranslate.dy(-dimText.getHeight() / 2));
} else if (type == WLinkType.BUS) {
ug = ug.apply(HColorUtils.WHITE.bg());
drawBusArrow(ug);
ugText = ugText.apply(UTranslate.dy((20 - dimText.getHeight()) / 2 - 5));
}
if (dimText.getHeight() > 0) {
switch (direction) {
case NORMAL:
ugText = ugText.apply(UTranslate.dx(4));
break;
case REVERSE:
ugText = ugText.apply(UTranslate.dx(len - dimText.getWidth() - 4));
break;
default:
ugText = ugText.apply(UTranslate.dx((len - dimText.getWidth()) / 2));
break;
}
if (type == WLinkType.NORMAL) {
ugText.apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(new URectangle(dimText));
}
textBlock.drawU(ugText);
}
}
private void drawBusArrow(UGraphic ug) {
final double dx = destination - start.getDx() - 2;
final UPath path = new UPath();
if (direction == WArrowDirection.NONE) {
path.moveTo(0, 0);
path.lineTo(dx, 0);
path.lineTo(dx, 10);
path.lineTo(0, 10);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
}
if (direction == WArrowDirection.NORMAL) {
path.moveTo(0, 0);
path.lineTo(dx - 15, 0);
path.lineTo(dx - 15, -5);
path.lineTo(dx, 5);
path.lineTo(dx - 15, 15);
path.lineTo(dx - 15, 10);
path.lineTo(0, 10);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
}
if (direction == WArrowDirection.BOTH) {
path.moveTo(0, 5);
path.lineTo(15, -5);
path.lineTo(15, 0);
path.lineTo(dx - 15, 0);
path.lineTo(dx - 15, -5);
path.lineTo(dx, 5);
path.lineTo(dx - 15, 15);
path.lineTo(dx - 15, 10);
path.lineTo(15, 10);
path.lineTo(15, 15);
path.lineTo(0, 5);
path.closePath();
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
}
if (direction == WArrowDirection.REVERSE) {
path.moveTo(0, 5);
path.lineTo(15, -5);
path.lineTo(15, 0);
path.lineTo(dx, 0);
path.lineTo(dx, 10);
path.lineTo(15, 10);
path.lineTo(15, 15);
path.lineTo(0, 5);
path.closePath();
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
}
}
private void drawNormalArrow(UGraphic ug) {
final double dx = destination - start.getDx() - 2;
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.NORMAL) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(-5, -5);
path.lineTo(-5, 5);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dx(dx))).draw(path);
}
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.REVERSE) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(5, -5);
path.lineTo(5, 5);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
}
ug.apply(start.compose(UTranslate.dx(1))).draw(ULine.hline(dx));
}
}

View File

@ -40,16 +40,16 @@ public enum WLinkType {
NORMAL, BUS;
static public WLinkType from(String arg) {
if (arg.equals("-")) {
if (arg.contains("-")) {
return WLinkType.NORMAL;
}
if (arg.equals("=")) {
if (arg.contains("=")) {
return WLinkType.BUS;
}
throw new IllegalArgumentException();
}
public double ySpaceForNext() {
public double spaceForNext() {
switch (this) {
case NORMAL:
return 15;

View File

@ -0,0 +1,164 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.wire;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class WLinkVertical {
private final UTranslate start;
private final double destination;
private final WLinkType type;
private final WArrowDirection direction;
private final HColor color;
private final Display label;
private final ISkinParam skinParam;
public WLinkVertical(ISkinParam skinParam, UTranslate start, double destination, WLinkType type,
WArrowDirection direction, HColor color, Display label) {
this.start = start;
this.destination = destination;
this.skinParam = skinParam;
this.direction = direction;
this.type = type;
this.label = label;
this.color = color == null ? HColorUtils.BLACK : color;
}
private TextBlock getTextBlock() {
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
.changeColor(color);
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
}
public void drawMe(UGraphic ug) {
ug = ug.apply(color);
if (type == WLinkType.NORMAL) {
ug = ug.apply(color.bg());
drawNormalArrow(ug);
} else if (type == WLinkType.BUS) {
ug = ug.apply(HColorUtils.WHITE.bg());
drawBusArrow(ug);
}
}
private void drawBusArrow(UGraphic ug) {
final double dy = destination - start.getDy() - 2;
final UPath path = new UPath();
if (direction == WArrowDirection.NONE) {
path.moveTo(0, 0);
path.lineTo(0, dy);
path.lineTo(10, dy);
path.lineTo(10, 0);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
}
if (direction == WArrowDirection.NORMAL) {
path.moveTo(0, 0);
path.lineTo(0, dy - 15);
path.lineTo(-5, dy - 15);
path.lineTo(5, dy);
path.lineTo(15, dy - 15);
path.lineTo(10, dy - 15);
path.lineTo(10, 0);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
}
if (direction == WArrowDirection.BOTH) {
path.moveTo(5, 0);
path.lineTo(-5, 15);
path.lineTo(0, 15);
path.lineTo(0, dy - 15);
path.lineTo(-5, dy - 15);
path.lineTo(5, dy);
path.lineTo(15, dy - 15);
path.lineTo(10, dy - 15);
path.lineTo(10, 15);
path.lineTo(15, 15);
path.lineTo(5, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
}
if (direction == WArrowDirection.REVERSE) {
path.moveTo(5, 0);
path.lineTo(-5, 15);
path.lineTo(0, 15);
path.lineTo(0, dy);
path.lineTo(10, dy);
path.lineTo(10, 15);
path.lineTo(15, 15);
path.lineTo(5, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
} }
private void drawNormalArrow(UGraphic ug) {
final double dy = destination - start.getDy() - 2;
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.NORMAL) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(5, -5);
path.lineTo(-5, -5);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(dy))).draw(path);
}
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.REVERSE) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(5, 5);
path.lineTo(-5, 5);
path.lineTo(0, 0);
path.closePath();
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
}
ug.apply(start.compose(UTranslate.dy(1))).draw(ULine.vline(dy));
}
}

View File

@ -0,0 +1,48 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.wire;
public enum WOrientation {
HORIZONTAL, VERTICAL;
public static WOrientation from(String style) {
if (style.contains("==") || style.contains("--")) {
return WOrientation.VERTICAL;
}
return HORIZONTAL;
}
}

View File

@ -35,57 +35,49 @@
*/
package net.sourceforge.plantuml.wire;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
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.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class WLink {
public class WPrint {
private final UTranslate pos1;
private final double pos2x;
private final WLinkType type;
private final UTranslate position;
private final HColor color;
private final Display label;
private final ISkinParam skinParam;
public WLink(WBlock block1, String x1, String y1, WBlock block2, WLinkType type, HColor color) {
pos1 = block1.getNextOut(x1, y1, type);
pos2x = block2.getAbsolutePosition("0", "0").getDx();
this.type = type;
public WPrint(ISkinParam skinParam, UTranslate position, HColor color, Display label) {
this.position = position;
this.skinParam = skinParam;
this.label = label;
this.color = color == null ? HColorUtils.BLACK : color;
}
private TextBlock getTextBlock() {
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
.changeColor(color);
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
}
public UChange getPosition() {
return position;
}
public void drawMe(UGraphic ug) {
getTextBlock().drawU(ug);
}
final double dx = pos2x - pos1.getDx() - 2;
ug = ug.apply(color).apply(color.bg());
if (type == WLinkType.NORMAL) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(-5, -5);
path.lineTo(-5, 5);
path.lineTo(0, 0);
path.closePath();
ug.apply(pos1.compose(UTranslate.dx(dx))).draw(path);
ug.apply(pos1.compose(UTranslate.dx(1))).draw(ULine.hline(dx));
} else if (type == WLinkType.BUS) {
final UPath path = new UPath();
path.moveTo(0, 0);
path.lineTo(dx - 15, 0);
path.lineTo(dx - 15, -5);
path.lineTo(dx, 5);
path.lineTo(dx - 15, 15);
path.lineTo(dx - 15, 10);
path.lineTo(0, 10);
path.lineTo(0, 0);
path.closePath();
ug.apply(pos1.compose(UTranslate.dx(1))).draw(path);
}
public double getHeight(StringBounder stringBounder) {
return getTextBlock().calculateDimension(stringBounder).getHeight();
}
}

View File

@ -43,16 +43,19 @@ import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.AnnotatedWorker;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.Scale;
import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.TikzFontDistortion;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.UseStyle;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
@ -62,21 +65,22 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.ImageParameter;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class WireDiagram extends UmlDiagram {
private final WBlock root = new WBlock("", 0, 0);
private final WBlock root = new WBlock("", new UTranslate(), 0, 0, null);
private final List<Spot> spots = new ArrayList<Spot>();
private final List<WLink> links = new ArrayList<WLink>();
private final List<WLinkHorizontal> hlinks = new ArrayList<WLinkHorizontal>();
private final List<WLinkVertical> vlinks = new ArrayList<WLinkVertical>();
public DiagramDescription getDescription() {
return new DiagramDescription("Wire Diagram");
}
@Override
public UmlDiagramType getUmlDiagramType() {
return UmlDiagramType.WIRE;
public WireDiagram() {
super(UmlDiagramType.WIRE);
}
@Override
@ -145,19 +149,22 @@ public class WireDiagram extends UmlDiagram {
for (Spot spot : spots) {
spot.drawMe(ug);
}
for (WLink link : links) {
for (WLinkHorizontal link : hlinks) {
link.drawMe(ug);
}
for (WLinkVertical link : vlinks) {
link.drawMe(ug);
}
}
public CommandExecutionResult addComponent(String indent, String name, int width, int height) {
final int level = indent.replace(" ", "\t").length();
return this.root.addComponent(level, name, width, height);
public CommandExecutionResult addComponent(String indent, String name, int width, int height, HColor color) {
final int level = computeIndentationLevel(indent);
return this.root.addBlock(level, name, width, height, color);
}
public CommandExecutionResult newColumn(String indent) {
final int level = indent.replace(" ", "\t").length();
final int level = computeIndentationLevel(indent);
return this.root.newColumn(level);
}
@ -172,16 +179,29 @@ public class WireDiagram extends UmlDiagram {
}
public CommandExecutionResult wgoto(String indent, double x, double y) {
final int level = indent.replace(" ", "\t").length();
final int level = computeIndentationLevel(indent);
return this.root.wgoto(level, x, y);
}
public CommandExecutionResult wmove(String indent, double x, double y) {
final int level = indent.replace(" ", "\t").length();
final int level = computeIndentationLevel(indent);
return this.root.wmove(level, x, y);
}
public CommandExecutionResult link(String name1, String x1, String y1, String name2, WLinkType type, HColor color) {
public CommandExecutionResult print(String indent, String text) {
final int level = computeIndentationLevel(indent);
final StringBounder stringBounder = FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault());
return this.root.print(stringBounder, getSkinParam(), level, text);
}
private int computeIndentationLevel(String indent) {
final int level = indent.replace(" ", "\t").length();
return level;
}
public CommandExecutionResult vlink(String name1, String x1, String y1, String name2, WLinkType type,
WArrowDirection direction, HColor color, Display label) {
final WBlock block1 = this.root.getBlock(name1);
if (block1 == null) {
return CommandExecutionResult.error("No such element " + name1);
@ -190,8 +210,30 @@ public class WireDiagram extends UmlDiagram {
if (block2 == null) {
return CommandExecutionResult.error("No such element " + name2);
}
final WLink link = new WLink(block1, x1, y1, block2, type, color);
this.links.add(link);
final UTranslate start = block1.getNextOutVertical(x1, y1, type);
final double destination = block2.getAbsolutePosition("0", "0").getDy();
this.vlinks.add(new WLinkVertical(getSkinParam(), start, destination, type, direction, color, label));
return CommandExecutionResult.ok();
}
public CommandExecutionResult hlink(String name1, String x1, String y1, String name2, WLinkType type,
WArrowDirection direction, HColor color, Display label) {
final WBlock block1 = this.root.getBlock(name1);
if (block1 == null) {
return CommandExecutionResult.error("No such element " + name1);
}
final WBlock block2 = this.root.getBlock(name2);
if (block2 == null) {
return CommandExecutionResult.error("No such element " + name2);
}
final UTranslate start = block1.getNextOutHorizontal(x1, y1, type);
final double destination = block2.getAbsolutePosition("0", "0").getDx();
this.hlinks.add(new WLinkHorizontal(getSkinParam(), start, destination, type, direction, color, label));
return CommandExecutionResult.ok();
}

View File

@ -59,6 +59,7 @@ public class WireDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandMove());
cmds.add(new CommandWLink());
cmds.add(new CommandNewColumn());
cmds.add(new CommandPrint());
return cmds;
}

View File

@ -0,0 +1,273 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.yaml;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.json.JsonArray;
import net.sourceforge.plantuml.json.JsonObject;
import net.sourceforge.plantuml.json.JsonValue;
public class SimpleYamlParser {
private static final String KEY = "([_0-9\\w][- _0-9\\w]*)";
private JsonObject result;
private final List<Integer> pendingIndents = new ArrayList<Integer>();
public JsonObject parse(List<String> lines) {
List<String> tmp = new ArrayList<String>();
for (String s : lines) {
if (s.trim().length() == 0)
continue;
if (s.trim().startsWith("#"))
continue;
tmp.add(s);
}
tmp = mergeMultiline(tmp);
result = new JsonObject();
pendingIndents.clear();
pendingIndents.add(0);
for (String s : tmp) {
parseSingleLine(s);
}
return result;
}
private List<String> mergeMultiline(List<String> tmp) {
final List<String> result = new ArrayList<String>();
for (int i = 0; i < tmp.size(); i++) {
if (nameOnly(tmp.get(i)) != null && textOnly(tmp.get(i + 1))) {
final StringBuilder sb = new StringBuilder(tmp.get(i));
while (textOnly(tmp.get(i + 1))) {
sb.append(" " + tmp.get(i + 1).trim());
i++;
}
result.add(sb.toString());
} else {
result.add(tmp.get(i));
}
}
return result;
}
private String[] dashNameAndValue(String s) {
final Pattern p1 = Pattern.compile("^\\s*[-]\\s*" + KEY + "\\s*:\\s*(\\S.*)$");
final Matcher m1 = p1.matcher(s);
if (m1.matches()) {
final String name = m1.group(1);
final String data = m1.group(2).trim();
return new String[] { name, data };
}
return null;
}
private String[] nameAndValue(String s) {
final Pattern p1 = Pattern.compile("^\\s*" + KEY + "\\s*:\\s*(\\S.*)$");
final Matcher m1 = p1.matcher(s);
if (m1.matches()) {
final String name = m1.group(1);
final String data = m1.group(2).trim();
return new String[] { name, data };
}
return null;
}
private String nameOnly(String s) {
final Pattern p1 = Pattern.compile("^\\s*" + KEY + "\\s*:\\s*\\|?\\s*$");
final Matcher m1 = p1.matcher(s);
if (m1.matches()) {
final String name = m1.group(1);
return name;
}
return null;
}
private String listedValue(String s) {
final Pattern p1 = Pattern.compile("^\\s*[-]\\s*(\\S.*)$");
final Matcher m1 = p1.matcher(s);
if (m1.matches()) {
final String name = m1.group(1).trim();
return name;
}
return null;
}
private boolean textOnly(String s) {
if (isList(s))
return false;
return s.indexOf(':') == -1;
}
private void parseSingleLine(String s) {
// System.err.println("s=" + s);
final int indent = getIndent(s);
if (isListStrict(s)) {
muteToArray(indent);
return;
}
final String[] dashNameAndValue = dashNameAndValue(s);
if (dashNameAndValue != null) {
muteToArray(indent);
parseSingleLine(s.replaceFirst("[-]", " "));
return;
}
final String listedValue = listedValue(s);
if (listedValue != null) {
final JsonArray array = getForceArray(indent);
array.add(listedValue);
return;
}
final JsonObject working = getWorking(indent);
if (working == null) {
System.err.println("ERROR: ignoring " + s);
return;
}
final String[] nameAndValue = nameAndValue(s);
if (nameAndValue != null) {
final String name = nameAndValue[0];
final String data = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(nameAndValue[1], "\"");
working.add(name, data);
return;
}
final String nameOnly = nameOnly(s);
if (nameOnly != null) {
working.add(nameOnly, new JsonObject());
return;
}
throw new UnsupportedOperationException(s);
}
private JsonArray getForceArray(int indent) {
while (getLastIndent() > indent - 1)
pendingIndents.remove(pendingIndents.size() - 1);
final JsonObject last = search(result, pendingIndents.size());
final String field = last.names().get(last.size() - 1);
if (last.get(field) instanceof JsonArray == false) {
last.set(field, new JsonArray());
}
return (JsonArray) last.get(field);
}
private void muteToArray(int indent) {
while (getLastIndent() > indent)
pendingIndents.remove(pendingIndents.size() - 1);
final JsonObject last = search(result, pendingIndents.size());
final String field = last.names().get(last.size() - 1);
if (last.get(field) instanceof JsonArray == false) {
last.set(field, new JsonArray());
} else {
((JsonArray) last.get(field)).add(new JsonObject());
}
}
private boolean isList(String s) {
return s.trim().startsWith("-");
}
private boolean isListStrict(String s) {
return s.trim().equals("-");
}
private int getLastIndent() {
return pendingIndents.get(pendingIndents.size() - 1);
}
private JsonObject getWorking(int indent) {
if (indent > getLastIndent()) {
pendingIndents.add(indent);
return search(result, pendingIndents.size());
}
if (indent == getLastIndent()) {
return search(result, pendingIndents.size());
}
final int idx = pendingIndents.indexOf(indent);
if (idx == -1) {
return null;
}
while (pendingIndents.size() > idx + 1)
pendingIndents.remove(pendingIndents.size() - 1);
return search(result, pendingIndents.size());
}
private static JsonObject search(JsonObject current, int size) {
if (size <= 1) {
return current;
}
final String last = current.names().get(current.size() - 1);
// System.err.println("last=" + last);
JsonValue tmp = current.get(last);
if (tmp instanceof JsonArray) {
JsonArray array = (JsonArray) tmp;
if (array.size() == 0) {
tmp = new JsonObject();
array.add(tmp);
} else {
tmp = array.get(array.size() - 1);
}
}
return search((JsonObject) tmp, size - 1);
}
private int getIndent(String s) {
int indent = 0;
for (int i = 0; i < s.length(); i++) {
final char ch = s.charAt(i);
if (ch == ' ' || ch == '\t') {
indent++;
} else {
return indent;
}
}
return 0;
}
}

View File

@ -0,0 +1,79 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.yaml;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.plantuml.StringLocated;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.command.PSystemAbstractFactory;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.DiagramType;
import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.json.JsonObject;
import net.sourceforge.plantuml.jsondiagram.JsonDiagram;
public class YamlDiagramFactory extends PSystemAbstractFactory {
public YamlDiagramFactory() {
super(DiagramType.YAML);
}
public Diagram createSystem(UmlSource source) {
JsonObject yaml = null;
try {
final List<String> list = new ArrayList<String>();
final Iterator<StringLocated> it = source.iterator2();
it.next();
while (true) {
final String line = it.next().getString();
if (it.hasNext() == false) {
break;
}
list.add(line);
}
yaml = new SimpleYamlParser().parse(list);
} catch (Exception e) {
e.printStackTrace();
}
final JsonDiagram result = new JsonDiagram(UmlDiagramType.YAML, yaml, new ArrayList<String>());
result.setSource(source);
return result;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.