diff --git a/pom.xml b/pom.xml index e7b378ff1..e9c4b2ca5 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ net.sourceforge.plantuml plantuml - 2017.09-SNAPSHOT + 2017.10-SNAPSHOT jar PlantUML diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index f649cf20f..7057ff936 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -38,11 +38,13 @@ package net.sourceforge.plantuml; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.code.AsciiEncoder; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.Version; @@ -51,9 +53,10 @@ public class BlockUml { private final List data; private final int startLine; private Diagram system; + private final Defines localDefines; BlockUml(String... strings) { - this(convert(strings), 0); + this(convert(strings), 0, Defines.createEmpty()); } public String getFlashData() { @@ -80,8 +83,9 @@ public class BlockUml { return result; } - public BlockUml(List strings, int startLine) { + public BlockUml(List strings, int startLine, Defines defines) { this.startLine = startLine; + this.localDefines = defines; final CharSequence2 s0 = strings.get(0).trin(); if (StartUtils.startsWithSymbolAnd("start", s0) == false) { throw new IllegalArgumentException(); @@ -156,4 +160,20 @@ public class BlockUml { return (Version.compileTime() / 1000L / 60) * 1000L * 60 + Version.beta() * 1000L * 3600; } + public boolean isStartDef(String name) { + final String signature = "@startdef(id=" + name + ")"; + return data.get(0).toString().equalsIgnoreCase(signature); + } + + public List getDefinition() { + if (data.get(0).toString().startsWith("@startdef") == false) { + throw new IllegalStateException(); + } + return Collections.unmodifiableList(data.subList(1, data.size() - 1)); + } + + public Defines getLocalDefines() { + return localDefines; + } + } diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index 68a22ce36..84d2dd388 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -52,18 +52,20 @@ import net.sourceforge.plantuml.preproc.ReadLineReader; import net.sourceforge.plantuml.preproc.UncommentReadLine; import net.sourceforge.plantuml.utils.StartUtils; -final public class BlockUmlBuilder { +public final class BlockUmlBuilder implements DefinitionsContainer { private final List blocks = new ArrayList(); private Set usedFiles = new HashSet(); private final UncommentReadLine reader2; + private final Defines defines; public BlockUmlBuilder(List config, String charset, Defines defines, Reader reader, File newCurrentDir, String desc) throws IOException { Preprocessor includer = null; + this.defines = defines; try { reader2 = new UncommentReadLine(new ReadLineReader(reader, desc)); - includer = new Preprocessor(reader2, charset, defines, newCurrentDir); + includer = new Preprocessor(reader2, charset, defines, newCurrentDir, this); init(includer, config); } finally { if (includer != null) { @@ -107,7 +109,7 @@ final public class BlockUmlBuilder { } if (StartUtils.isArobaseEndDiagram(s) && current2 != null) { current2.addAll(1, convert(config, s.getLocation())); - blocks.add(new BlockUml(current2, startLine)); + blocks.add(new BlockUml(current2, startLine, defines.cloneMe())); current2 = null; reader2.setPaused(false); } @@ -130,10 +132,14 @@ final public class BlockUmlBuilder { return Collections.unmodifiableSet(usedFiles); } - /* - * private List getStrings(Reader reader) throws IOException { final List result = new - * ArrayList(); Preprocessor includer = null; try { includer = new Preprocessor(reader, defines); String s = - * null; while ((s = includer.readLine()) != null) { result.add(s); } } finally { if (includer != null) { - * includer.close(); } } return Collections.unmodifiableList(result); } - */ + public List getDefinition(String name) { + for (BlockUml block : blocks) { + if (block.isStartDef(name)) { + this.defines.importFrom(block.getLocalDefines()); + return block.getDefinition(); + } + } + return Collections.emptyList(); + } + } diff --git a/src/net/sourceforge/plantuml/DefinitionsContainer.java b/src/net/sourceforge/plantuml/DefinitionsContainer.java new file mode 100644 index 000000000..a45f583c7 --- /dev/null +++ b/src/net/sourceforge/plantuml/DefinitionsContainer.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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; + +import java.util.List; + +public interface DefinitionsContainer { + + public List getDefinition(String name); + +} diff --git a/src/net/sourceforge/plantuml/DirWatcher.java b/src/net/sourceforge/plantuml/DirWatcher.java index fb5516562..3b681a69d 100644 --- a/src/net/sourceforge/plantuml/DirWatcher.java +++ b/src/net/sourceforge/plantuml/DirWatcher.java @@ -78,8 +78,8 @@ public class DirWatcher { final FileWatcher watcher = modifieds.get(f); if (watcher == null || watcher.hasChanged()) { - final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), - option.getConfig(), option.getCharset(), option.getFileFormatOption()); + final SourceFileReader sourceFileReader = new SourceFileReader(Defines.createWithFileName(f), f, + option.getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); final Set files = FileWithSuffix.convert(sourceFileReader.getIncludedFiles()); files.add(f); for (GeneratedImage g : sourceFileReader.getGeneratedImages()) { @@ -106,8 +106,8 @@ public class DirWatcher { final FileWatcher watcher = modifieds.get(f); if (watcher == null || watcher.hasChanged()) { - final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), - option.getConfig(), option.getCharset(), option.getFileFormatOption()); + final SourceFileReader sourceFileReader = new SourceFileReader(Defines.createWithFileName(f), f, + option.getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); if (sourceFileReader.hasError()) { return f; } diff --git a/src/net/sourceforge/plantuml/DirWatcher2.java b/src/net/sourceforge/plantuml/DirWatcher2.java index 19bae4d21..2e3c6b6c5 100644 --- a/src/net/sourceforge/plantuml/DirWatcher2.java +++ b/src/net/sourceforge/plantuml/DirWatcher2.java @@ -82,7 +82,7 @@ public class DirWatcher2 { final FileWatcher watcher = modifieds.get(f); if (watcher == null || watcher.hasChanged()) { - final SourceFileReader sourceFileReader = new SourceFileReader(option.getDefaultDefines(), f, + final SourceFileReader sourceFileReader = new SourceFileReader(option.getDefaultDefines(f), f, option.getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); modifieds.put(f, new FileWatcher(Collections.singleton(f))); diff --git a/src/net/sourceforge/plantuml/FileFormatOption.java b/src/net/sourceforge/plantuml/FileFormatOption.java index 8a36a5f8c..2ce5ace8c 100644 --- a/src/net/sourceforge/plantuml/FileFormatOption.java +++ b/src/net/sourceforge/plantuml/FileFormatOption.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml; import java.awt.geom.AffineTransform; import java.io.Serializable; +import java.util.Random; import net.sourceforge.plantuml.graphic.StringBounder; @@ -55,9 +56,10 @@ public class FileFormatOption implements Serializable { private final boolean useRedForError; private final String svgLinkTarget; private final String hoverColor; + private final Random rnd; public FileFormatOption(FileFormat fileFormat) { - this(fileFormat, null, true, false, "_top", false, null); + this(fileFormat, null, true, false, "_top", false, null, new Random()); } public StringBounder getDefaultStringBounder() { @@ -72,12 +74,16 @@ public class FileFormatOption implements Serializable { return withMetadata; } + public final Random getRandom() { + return rnd; + } + public FileFormatOption(FileFormat fileFormat, boolean withMetadata) { - this(fileFormat, null, false, false, "_top", false, null); + this(fileFormat, null, false, false, "_top", false, null, new Random()); } private FileFormatOption(FileFormat fileFormat, AffineTransform at, boolean withMetadata, boolean useRedForError, - String svgLinkTarget, boolean debugsvek, String hoverColor) { + String svgLinkTarget, boolean debugsvek, String hoverColor, Random rnd) { this.hoverColor = hoverColor; this.fileFormat = fileFormat; this.affineTransform = at; @@ -85,18 +91,27 @@ public class FileFormatOption implements Serializable { this.useRedForError = useRedForError; this.svgLinkTarget = svgLinkTarget; this.debugsvek = debugsvek; + this.rnd = rnd; } public FileFormatOption withUseRedForError() { - return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek, hoverColor); + return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek, + hoverColor, rnd); } public FileFormatOption withSvgLinkTarget(String svgLinkTarget) { - return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, debugsvek, hoverColor); + return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, + debugsvek, hoverColor, rnd); } public FileFormatOption withHoverColor(String hoverColor) { - return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, debugsvek, hoverColor); + return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, + debugsvek, hoverColor, rnd); + } + + public FileFormatOption withFixedRandom() { + return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, + debugsvek, hoverColor, new Random(42)); } @Override diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index 15e098941..b8b6b1563 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -46,6 +46,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import net.sourceforge.plantuml.api.ApiWarning; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; @@ -64,6 +65,7 @@ public class Option { private boolean pipe = false; private String pipeDelimitor; private boolean pipeMap = false; + private boolean pipeNoStdErr = false; private boolean syntax = false; private boolean checkOnly = false; private boolean failfast = false; @@ -84,14 +86,16 @@ public class Option { public Option() { } - private FileFormat fileFormat = FileFormat.PNG; + private FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG); - public FileFormat getFileFormat() { - return fileFormat; + @Deprecated + @ApiWarning(willBeRemoved = "in next major release") + final public void setFileFormat(FileFormat fileFormat) { + setFileFormatOption(new FileFormatOption(fileFormat)); } - public void setFileFormat(FileFormat fileFormat) { - this.fileFormat = fileFormat; + final public void setFileFormatOption(FileFormatOption newFormat) { + this.fileFormatOption = newFormat; } public Option(String... arg) throws InterruptedException, IOException { @@ -101,39 +105,41 @@ public class Option { for (int i = 0; i < arg.length; i++) { String s = arg[i]; if (s.equalsIgnoreCase("-tsvg") || s.equalsIgnoreCase("-svg")) { - setFileFormat(FileFormat.SVG); + setFileFormatOption(new FileFormatOption(FileFormat.SVG)); + } else if (s.equalsIgnoreCase("-tsvg:nornd") || s.equalsIgnoreCase("-svg:nornd")) { + setFileFormatOption(new FileFormatOption(FileFormat.SVG).withFixedRandom()); } else if (s.equalsIgnoreCase("-thtml") || s.equalsIgnoreCase("-html")) { - setFileFormat(FileFormat.HTML); + setFileFormatOption(new FileFormatOption(FileFormat.HTML)); } else if (s.equalsIgnoreCase("-tscxml") || s.equalsIgnoreCase("-scxml")) { - setFileFormat(FileFormat.SCXML); + setFileFormatOption(new FileFormatOption(FileFormat.SCXML)); } else if (s.equalsIgnoreCase("-txmi") || s.equalsIgnoreCase("-xmi")) { - setFileFormat(FileFormat.XMI_STANDARD); + setFileFormatOption(new FileFormatOption(FileFormat.XMI_STANDARD)); } else if (s.equalsIgnoreCase("-txmi:argo") || s.equalsIgnoreCase("-xmi:argo")) { - setFileFormat(FileFormat.XMI_ARGO); + setFileFormatOption(new FileFormatOption(FileFormat.XMI_ARGO)); } else if (s.equalsIgnoreCase("-txmi:star") || s.equalsIgnoreCase("-xmi:star")) { - setFileFormat(FileFormat.XMI_STAR); + setFileFormatOption(new FileFormatOption(FileFormat.XMI_STAR)); } else if (s.equalsIgnoreCase("-teps") || s.equalsIgnoreCase("-eps")) { - setFileFormat(FileFormat.EPS); + setFileFormatOption(new FileFormatOption(FileFormat.EPS)); } else if (s.equalsIgnoreCase("-teps:text") || s.equalsIgnoreCase("-eps:text")) { - setFileFormat(FileFormat.EPS_TEXT); + setFileFormatOption(new FileFormatOption(FileFormat.EPS_TEXT)); } else if (s.equalsIgnoreCase("-ttxt") || s.equalsIgnoreCase("-txt")) { - setFileFormat(FileFormat.ATXT); + setFileFormatOption(new FileFormatOption(FileFormat.ATXT)); } else if (s.equalsIgnoreCase("-tutxt") || s.equalsIgnoreCase("-utxt")) { - setFileFormat(FileFormat.UTXT); + setFileFormatOption(new FileFormatOption(FileFormat.UTXT)); } else if (s.equalsIgnoreCase("-braille") || s.equalsIgnoreCase("-tbraille")) { - setFileFormat(FileFormat.BRAILLE_PNG); + setFileFormatOption(new FileFormatOption(FileFormat.BRAILLE_PNG)); } else if (s.equalsIgnoreCase("-png") || s.equalsIgnoreCase("-tpng")) { - setFileFormat(FileFormat.PNG); + setFileFormatOption(new FileFormatOption(FileFormat.PNG)); } else if (s.equalsIgnoreCase("-vdx") || s.equalsIgnoreCase("-tvdx")) { - setFileFormat(FileFormat.VDX); + setFileFormatOption(new FileFormatOption(FileFormat.VDX)); } else if (s.equalsIgnoreCase("-latex") || s.equalsIgnoreCase("-tlatex")) { - setFileFormat(FileFormat.LATEX); + setFileFormatOption(new FileFormatOption(FileFormat.LATEX)); } else if (s.equalsIgnoreCase("-latex:nopreamble") || s.equalsIgnoreCase("-tlatex:nopreamble")) { - setFileFormat(FileFormat.LATEX_NO_PREAMBLE); + setFileFormatOption(new FileFormatOption(FileFormat.LATEX_NO_PREAMBLE)); } else if (s.equalsIgnoreCase("-base64") || s.equalsIgnoreCase("-tbase64")) { - setFileFormat(FileFormat.BASE64); + setFileFormatOption(new FileFormatOption(FileFormat.BASE64)); } else if (s.equalsIgnoreCase("-pdf") || s.equalsIgnoreCase("-tpdf")) { - setFileFormat(FileFormat.PDF); + setFileFormatOption(new FileFormatOption(FileFormat.PDF)); } else if (s.equalsIgnoreCase("-overwrite")) { OptionFlags.getInstance().setOverwrite(true); } else if (s.equalsIgnoreCase("-output") || s.equalsIgnoreCase("-o")) { @@ -182,6 +188,15 @@ public class Option { } else if (nb.matches("\\d+")) { this.nbThreads = Integer.parseInt(nb); } + } else if (s.equalsIgnoreCase("-timeout")) { + i++; + if (i == arg.length) { + continue; + } + final String timeSeconds = arg[i]; + if (timeSeconds.matches("\\d+")) { + OptionFlags.getInstance().setTimeoutMs(Integer.parseInt(timeSeconds) * 1000L); + } } else if (s.equalsIgnoreCase("-failfast")) { this.failfast = true; } else if (s.equalsIgnoreCase("-failfast2")) { @@ -213,6 +228,8 @@ public class Option { pipeDelimitor = arg[i]; } else if (s.equalsIgnoreCase("-pipemap")) { pipeMap = true; + } else if (s.equalsIgnoreCase("-pipenostderr")) { + pipeNoStdErr = true; } else if (s.equalsIgnoreCase("-pattern")) { pattern = true; } else if (s.equalsIgnoreCase("-syntax")) { @@ -377,8 +394,8 @@ public class Option { return Collections.unmodifiableList(excludes); } - public Defines getDefaultDefines() { - final Defines result = new Defines(); + public Defines getDefaultDefines(File f) { + final Defines result = Defines.createWithFileName(f); for (Map.Entry ent : defines.entrySet()) { result.define(ent.getKey(), Arrays.asList(ent.getValue())); @@ -432,7 +449,7 @@ public class Option { } public FileFormatOption getFileFormatOption() { - final FileFormatOption fileFormatOption = new FileFormatOption(getFileFormat()); + // final FileFormatOption fileFormatOption = new FileFormatOption(getFileFormat()); if (debugsvek) { fileFormatOption.setDebugSvek(true); } @@ -507,4 +524,8 @@ public class Option { return pipeDelimitor; } + public final boolean isPipeNoStdErr() { + return pipeNoStdErr; + } + } diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java index edaae7ff3..70799f427 100644 --- a/src/net/sourceforge/plantuml/OptionFlags.java +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -120,6 +120,7 @@ public class OptionFlags { private boolean overwrite; private boolean enableStats = defaultForStats(); private String fileSeparator = "_"; + private long timeoutMs = 15 * 60 * 1000L; // 15 minutes private File logData; private OptionFlags() { @@ -321,4 +322,11 @@ public class OptionFlags { this.enableStats = enableStats; } + public final long getTimeoutMs() { + return timeoutMs; + } + + public final void setTimeoutMs(long timeoutMs) { + this.timeoutMs = timeoutMs; + } } diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java index 95e816829..3b9e2c35c 100644 --- a/src/net/sourceforge/plantuml/OptionPrint.java +++ b/src/net/sourceforge/plantuml/OptionPrint.java @@ -126,6 +126,8 @@ public class OptionPrint { System.out.println(" -duration\t\tTo print the duration of complete diagrams processing"); System.out.println(" -nbthread N\t\tTo use (N) threads for processing"); System.out.println(" -nbthread auto\tTo use " + Option.defaultNbThreads() + " threads for processing"); + System.out + .println(" -timeout N\t\tProcessing timeout in (N) seconds. Defaults to 15 minutes (900 seconds)."); System.out.println(" -author[s]\t\tTo print information about PlantUML authors"); System.out.println(" -overwrite\t\tTo allow to overwrite read only files"); System.out.println(" -printfonts\t\tTo print fonts available on your system"); diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index ff274b6fb..8cc906661 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.creole.PSystemCreoleFactory; import net.sourceforge.plantuml.cute.PSystemCuteFactory; import net.sourceforge.plantuml.dedication.PSystemDedicationFactory; +import net.sourceforge.plantuml.definition.PSystemDefinitionFactory; import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory; import net.sourceforge.plantuml.directdot.PSystemDotFactory; import net.sourceforge.plantuml.ditaa.PSystemDitaaFactory; @@ -171,6 +172,7 @@ public class PSystemBuilder { factories.add(new PSystemLogoFactory()); factories.add(new PSystemSudokuFactory()); } + factories.add(new PSystemDefinitionFactory()); factories.add(new PSystemMathFactory(DiagramType.MATH)); factories.add(new PSystemLatexFactory(DiagramType.LATEX)); // factories.add(new PSystemStatsFactory()); diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java index 9fc8f5fed..2ce637a34 100644 --- a/src/net/sourceforge/plantuml/PSystemError.java +++ b/src/net/sourceforge/plantuml/PSystemError.java @@ -57,6 +57,7 @@ import net.sourceforge.plantuml.graphic.GraphicStrings; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorSimple; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; @@ -175,7 +176,7 @@ public class PSystemError extends AbstractPSystem { ug.apply(new UTranslate(1, 1)).draw(message); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } diff --git a/src/net/sourceforge/plantuml/Pipe.java b/src/net/sourceforge/plantuml/Pipe.java index 3734043f1..161d4f6e4 100644 --- a/src/net/sourceforge/plantuml/Pipe.java +++ b/src/net/sourceforge/plantuml/Pipe.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.io.PrintStream; import net.sourceforge.plantuml.core.Diagram; @@ -61,6 +62,7 @@ public class Pipe { public boolean managePipe() throws IOException { boolean error = false; + final boolean noStdErr = option.isPipeNoStdErr(); do { final String source = readOneDiagram(); @@ -68,7 +70,7 @@ public class Pipe { ps.flush(); return error; } - final SourceStringReader sourceStringReader = new SourceStringReader(new Defines(), source, + final SourceStringReader sourceStringReader = new SourceStringReader(Defines.createEmpty(), source, option.getConfig()); if (option.isSyntax()) { @@ -78,12 +80,7 @@ public class Pipe { ps.println(system.getDescription()); } else if (system instanceof PSystemError) { error = true; - ps.println("ERROR"); - final PSystemError sys = (PSystemError) system; - ps.println(sys.getHigherErrorPosition()); - for (ErrorUml er : sys.getErrorsUml()) { - ps.println(er.getError()); - } + printErrorText(ps, (PSystemError) system); } else { ps.println("OTHER"); ps.println(system.getDescription()); @@ -92,19 +89,18 @@ public class Pipe { final String result = sourceStringReader.getCMapData(0, option.getFileFormatOption()); ps.println(result); } else { - final DiagramDescription result = sourceStringReader.generateImage(ps, 0, option.getFileFormatOption()); - if (option.getPipeDelimitor() != null) { - ps.println(option.getPipeDelimitor()); - } + final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps; + final DiagramDescription result = sourceStringReader.generateImage(os, 0, option.getFileFormatOption()); if (result != null && "(error)".equalsIgnoreCase(result.getDescription())) { error = true; - System.err.println("ERROR"); - final Diagram system = sourceStringReader.getBlocks().get(0).getDiagram(); - final PSystemError sys = (PSystemError) system; - System.err.println(sys.getHigherErrorPosition()); - for (ErrorUml er : sys.getErrorsUml()) { - System.err.println(er.getError()); - } + manageErrors(noStdErr ? ps : System.err, sourceStringReader); + } else if (noStdErr) { + final ByteArrayOutputStream baos = (ByteArrayOutputStream) os; + baos.close(); + ps.write(baos.toByteArray()); + } + if (option.getPipeDelimitor() != null) { + ps.println(option.getPipeDelimitor()); } } ps.flush(); @@ -112,6 +108,22 @@ public class Pipe { return error; } + private void manageErrors(final PrintStream output, final SourceStringReader sourceStringReader) { + // if (option.getPipeDelimitor() != null) { + // output.println(option.getPipeDelimitor()); + // } + printErrorText(output, (PSystemError) sourceStringReader.getBlocks().get(0).getDiagram()); + } + + private void printErrorText(final PrintStream output, final PSystemError sys) { + output.println("ERROR"); + output.println(sys.getHigherErrorPosition()); + for (ErrorUml er : sys.getErrorsUml()) { + output.println(er.getError()); + } + output.flush(); + } + private boolean isFinished(String s) { return s == null || s.startsWith("@end"); } @@ -150,7 +162,7 @@ public class Pipe { } break; } - if (read != '\r') { + if (read != '\r' && read != '\n') { baos.write(read); } if (read == '\n') { diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java index bc2929a6e..a2186c890 100644 --- a/src/net/sourceforge/plantuml/Run.java +++ b/src/net/sourceforge/plantuml/Run.java @@ -74,6 +74,7 @@ public class Run { public static void main(String[] argsArray) throws IOException, InterruptedException { final long start = System.currentTimeMillis(); + saveCommandLine(argsArray); final Option option = new Option(argsArray); ProgressBar.setEnable(option.isTextProgressBar()); if (OptionFlags.getInstance().isDumpStats()) { @@ -173,6 +174,21 @@ public class Run { } } + private static String commandLine = ""; + + public static final String getCommandLine() { + return commandLine; + } + + private static void saveCommandLine(String[] argsArray) { + final StringBuilder sb = new StringBuilder(); + for (String s : argsArray) { + sb.append(s); + sb.append(" "); + } + commandLine = sb.toString(); + } + public static void forceOpenJdkResourceLoad() { final BufferedImage imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); final Graphics2D gg = imDummy.createGraphics(); @@ -228,7 +244,7 @@ public class Run { private static void goFtp(Option option) throws IOException { final int ftpPort = option.getFtpPort(); System.err.println("ftpPort=" + ftpPort); - final FtpServer ftpServer = new FtpServer(ftpPort, option.getFileFormat()); + final FtpServer ftpServer = new FtpServer(ftpPort, option.getFileFormatOption().getFileFormat()); ftpServer.go(); } @@ -379,10 +395,10 @@ public class Run { } final ISourceFileReader sourceFileReader; if (option.getOutputFile() == null) { - sourceFileReader = new SourceFileReader(option.getDefaultDefines(), f, option.getOutputDir(), + sourceFileReader = new SourceFileReader(option.getDefaultDefines(f), f, option.getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); } else { - sourceFileReader = new SourceFileReader2(option.getDefaultDefines(), f, option.getOutputFile(), + sourceFileReader = new SourceFileReader2(option.getDefaultDefines(f), f, option.getOutputFile(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); } if (option.isComputeurl()) { @@ -414,4 +430,5 @@ public class Run { return result; } + } diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 9ddb6e60d..d667047d5 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -189,7 +189,8 @@ public class SkinParam implements ISkinParam { if (value == null) { return null; } - final boolean acceptTransparent = param == ColorParam.background; + final boolean acceptTransparent = param == ColorParam.background + || param == ColorParam.sequenceGroupBodyBackground; return getIHtmlColorSet().getColorIfValid(value, acceptTransparent); } diff --git a/src/net/sourceforge/plantuml/SourceFileReader.java b/src/net/sourceforge/plantuml/SourceFileReader.java index 2351a4932..7a17bf0db 100644 --- a/src/net/sourceforge/plantuml/SourceFileReader.java +++ b/src/net/sourceforge/plantuml/SourceFileReader.java @@ -70,18 +70,19 @@ public class SourceFileReader implements ISourceFileReader { } public SourceFileReader(File file, File outputDirectory, String charset) throws IOException { - this(new Defines(), file, outputDirectory, Collections. emptyList(), charset, new FileFormatOption( - FileFormat.PNG)); + this(Defines.createWithFileName(file), file, outputDirectory, Collections. emptyList(), charset, + new FileFormatOption(FileFormat.PNG)); } public SourceFileReader(final File file, File outputDirectory) throws IOException { - this(new Defines(), file, outputDirectory, Collections. emptyList(), null, new FileFormatOption( - FileFormat.PNG)); + this(Defines.createWithFileName(file), file, outputDirectory, Collections. emptyList(), null, + new FileFormatOption(FileFormat.PNG)); } public SourceFileReader(final File file, File outputDirectory, FileFormatOption fileFormatOption) throws IOException { - this(new Defines(), file, outputDirectory, Collections. emptyList(), null, fileFormatOption); + this(Defines.createWithFileName(file), file, outputDirectory, Collections. emptyList(), null, + fileFormatOption); } public SourceFileReader(Defines defines, final File file, File outputDirectory, List config, @@ -210,6 +211,9 @@ public class SourceFileReader implements ISourceFileReader { } final List exportDiagrams = PSystemUtils.exportDiagrams(system, suggested, fileFormatOption); + if (exportDiagrams.size() > 1) { + cpt += exportDiagrams.size() - 1; + } OptionFlags.getInstance().logData(file, system); for (FileImageData fdata : exportDiagrams) { diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java index 2bea472d4..78ec22e4d 100644 --- a/src/net/sourceforge/plantuml/SourceStringReader.java +++ b/src/net/sourceforge/plantuml/SourceStringReader.java @@ -59,11 +59,11 @@ public class SourceStringReader { final private List blocks; public SourceStringReader(String source) { - this(new Defines(), source, Collections. emptyList()); + this(Defines.createEmpty(), source, Collections. emptyList()); } public SourceStringReader(String source, String charset) { - this(new Defines(), source, "UTF-8", Collections. emptyList()); + this(Defines.createEmpty(), source, "UTF-8", Collections. emptyList()); } public SourceStringReader(Defines defines, String source, List config) { @@ -71,7 +71,7 @@ public class SourceStringReader { } public SourceStringReader(String source, File newCurrentDir) { - this(new Defines(), source, "UTF-8", Collections. emptyList(), newCurrentDir); + this(Defines.createEmpty(), source, "UTF-8", Collections. emptyList(), newCurrentDir); } public SourceStringReader(Defines defines, String source, String charset, List config) { diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java index 814a66df5..4801db7e5 100644 --- a/src/net/sourceforge/plantuml/StringUtils.java +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -276,6 +276,9 @@ public class StringUtils { } public static String eventuallyRemoveStartingAndEndingDoubleQuote(String s) { + if (s == null) { + return s; + } return eventuallyRemoveStartingAndEndingDoubleQuote(s, "\"([:"); } diff --git a/src/net/sourceforge/plantuml/SvgString.java b/src/net/sourceforge/plantuml/SvgString.java new file mode 100644 index 000000000..f580d4e88 --- /dev/null +++ b/src/net/sourceforge/plantuml/SvgString.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SvgString { + + private final String svg; + private final double scale; + + public SvgString(String svg, double scale) { + this.svg = svg; + this.scale = scale; + } + + public String getSvg() { + String result = svg; + if (result.startsWith(""); + result = "" + result.substring(idx + 1); + } + if (result.startsWith("") == false) { + throw new IllegalArgumentException(); + } + return result; + } + + public int getData(String name) { + final Pattern p = Pattern.compile("(?i)" + name + "\\W+(\\d+)"); + final Matcher m = p.matcher(svg); + if (m.find()) { + final String s = m.group(1); + return Integer.parseInt(s); + } + throw new IllegalStateException("Cannot find " + name); + } + + public double getScale() { + return scale; + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java index 5a1f37c29..77d86f0d8 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java @@ -69,7 +69,7 @@ public class ActivityDiagram extends CucaDiagram { final IEntity result; if (leafExist(code)) { result = getOrCreateLeafDefault(code, type, null); - if (result.getEntityType() != type) { + if (result.getLeafType() != type) { // throw new IllegalArgumentException("Already known: " + code + " " + result.getType() + " " + type); return null; } @@ -100,11 +100,11 @@ public class ActivityDiagram extends CucaDiagram { } private void updateLasts(final IEntity result) { - if (result.getEntityType() == LeafType.NOTE) { + if (result.getLeafType() == LeafType.NOTE) { return; } this.lastEntityConsulted = result; - if (result.getEntityType() == LeafType.BRANCH) { + if (result.getLeafType() == LeafType.BRANCH) { lastEntityBrancheConsulted = result; } } diff --git a/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java b/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java index d78e557f1..5afcef45c 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java @@ -46,7 +46,7 @@ public class ConditionalContext { private final ConditionalContext parent; public ConditionalContext(ConditionalContext parent, IEntity branch, Direction direction) { - if (branch.getEntityType() != LeafType.BRANCH) { + if (branch.getLeafType() != LeafType.BRANCH) { throw new IllegalArgumentException(); } this.branch = branch; diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java index c4e64ef0a..ca2c0d977 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java @@ -250,7 +250,7 @@ public class CommandLinkActivity extends SingleLineCommand2 { static LeafType getTypeIfExisting(ActivityDiagram system, Code code) { if (system.leafExist(code)) { final IEntity ent = system.getLeafsget(code); - if (ent.getEntityType() == LeafType.BRANCH) { + if (ent.getLeafType() == LeafType.BRANCH) { return LeafType.BRANCH; } } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index a73ad5ab5..272f3e07f 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -315,10 +315,10 @@ public class ActivityDiagram3 extends UmlDiagram { return CommandExecutionResult.error("Cannot find if"); } - public void startRepeat(HtmlColor color) { + public void startRepeat(HtmlColor color, Display label) { manageSwimlaneStrategy(); final InstructionRepeat instructionRepeat = new InstructionRepeat(swinlanes.getCurrentSwimlane(), current(), - nextLinkRenderer(), color); + nextLinkRenderer(), color, label); current().add(instructionRepeat); setCurrent(instructionRepeat); setNextLinkRendererInternal(LinkRendering.none()); @@ -340,6 +340,20 @@ public class ActivityDiagram3 extends UmlDiagram { } + public CommandExecutionResult backwardWhile(Display label) { + manageSwimlaneStrategy(); + if (current() instanceof InstructionRepeat) { + final InstructionRepeat instructionRepeat = (InstructionRepeat) current(); +// final LinkRendering back = new LinkRendering(linkColor).withDisplay(linkLabel); + instructionRepeat.setBackward(label); +// setCurrent(instructionRepeat.getParent()); +// this.setNextLinkRendererInternal(LinkRendering.none()); + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("Cannot find repeat"); + + } + public void doWhile(Display test, Display yes, HtmlColor color) { manageSwimlaneStrategy(); final InstructionWhile instructionWhile = new InstructionWhile(swinlanes.getCurrentSwimlane(), current(), test, diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java index 6a0a57b6b..fc77602da 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandActivityLegacy1; import net.sourceforge.plantuml.activitydiagram3.command.CommandActivityLong3; import net.sourceforge.plantuml.activitydiagram3.command.CommandArrow3; import net.sourceforge.plantuml.activitydiagram3.command.CommandArrowLong3; +import net.sourceforge.plantuml.activitydiagram3.command.CommandBackward3; import net.sourceforge.plantuml.activitydiagram3.command.CommandBreak; import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3; import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf2; @@ -112,6 +113,7 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory { cmds.add(new CommandRepeat3()); cmds.add(new CommandRepeatWhile3()); cmds.add(new CommandRepeatWhile3Multilines()); + cmds.add(new CommandBackward3()); cmds.add(new CommandWhile3()); cmds.add(new CommandWhileEnd3()); cmds.add(new CommandFork3()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java index 2e2557cb4..a6bd54c06 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.activitydiagram3; import java.util.Set; +import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileKilled; @@ -56,14 +57,18 @@ public class InstructionRepeat implements Instruction { private final HtmlColor color; private boolean killed = false; + private Display backward = Display.NULL; private Display test = Display.NULL; private Display yes = Display.NULL; private Display out = Display.NULL; + private final Display startLabel; private boolean testCalled = false; private LinkRendering endRepeatLinkRendering = LinkRendering.none(); private LinkRendering backRepeatLinkRendering = LinkRendering.none(); - public InstructionRepeat(Swimlane swimlane, Instruction parent, LinkRendering nextLinkRenderer, HtmlColor color) { + public InstructionRepeat(Swimlane swimlane, Instruction parent, LinkRendering nextLinkRenderer, HtmlColor color, + Display startLabel) { + this.startLabel = startLabel; this.parent = parent; this.swimlane = swimlane; this.nextLinkRenderer = nextLinkRenderer; @@ -73,14 +78,20 @@ public class InstructionRepeat implements Instruction { this.color = color; } + public void setBackward(Display label) { + this.backward = label; + } + public void add(Instruction ins) { repeatList.add(ins); } public Ftile createFtile(FtileFactory factory) { + final Ftile back = Display.isNull(backward) ? null : factory.activity(backward, swimlane, BoxStyle.PLAIN, + Colors.empty()); final Ftile result = factory.repeat(swimlane, repeatList.getSwimlaneOut(), - factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering), test, yes, out, color, - backRepeatLinkRendering); + startLabel, factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering), test, yes, out, + color, backRepeatLinkRendering, back); if (killed) { return new FtileKilled(result); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java new file mode 100644 index 000000000..7b797e7c2 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.activitydiagram3.command; + +import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Display; + +public class CommandBackward3 extends SingleLineCommand2 { + + public CommandBackward3() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("backward"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf(":"), // + new RegexLeaf("LABEL", "(.*)"), // + new RegexLeaf(";$")); + } + + @Override + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); + return diagram.backwardWhile(label); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java index d8bf9519b..911f48eb5 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java @@ -41,6 +41,7 @@ import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.color.ColorParser; @@ -54,14 +55,17 @@ public class CommandRepeat3 extends SingleLineCommand2 { return new RegexConcat(new RegexLeaf("^"), // ColorParser.exp4(), // new RegexLeaf("repeat"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("LABEL", "(?::(.*?))?"), // new RegexLeaf(";?$")); } @Override protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); - - diagram.startRepeat(color); + final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); + + diagram.startRepeat(color, label); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java index df1874e09..c6f9eea74 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java @@ -74,8 +74,8 @@ public interface FtileFactory { public Ftile assembly(Ftile tile1, Ftile tile2); - public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Ftile repeat, Display test, Display yes, Display out, - HtmlColor color, LinkRendering backRepeatLinkRendering); + public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test, Display yes, + Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward); public Ftile createWhile(Swimlane swimlane, Ftile whileBlock, Display test, Display yes, Display out, LinkRendering afterEndwhile, HtmlColor color, Instruction specialOut); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java index 32f142192..07461b528 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java @@ -141,9 +141,10 @@ public class FtileFactoryDelegator implements FtileFactory { return factory.assembly(tile1, tile2); } - public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Ftile repeat, Display test, Display yes, Display out, - HtmlColor color, LinkRendering backRepeatLinkRendering) { - return factory.repeat(swimlane, swimlaneOut, repeat, test, yes, out, color, backRepeatLinkRendering); + public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test, Display yes, + Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward) { + return factory.repeat(swimlane, swimlaneOut, startLabel, repeat, test, yes, out, color, backRepeatLinkRendering, + backward); } public Ftile createWhile(Swimlane swimlane, Ftile whileBlock, Display test, Display yes, Display out, diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java index e71d5f29b..d01e9c2a6 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.activitydiagram3.LinkRendering; import net.sourceforge.plantuml.activitydiagram3.ftile.Arrows; +import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; import net.sourceforge.plantuml.activitydiagram3.ftile.Connection; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileBreak; @@ -58,6 +59,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorAndStyle; import net.sourceforge.plantuml.graphic.Rainbow; +import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -69,8 +71,8 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator { } @Override - public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, final Ftile repeat, Display test, Display yes, - Display out, HtmlColor color, LinkRendering backRepeatLinkRendering) { + public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, final Ftile repeat, Display test, + Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward) { final ConditionStyle conditionStyle = skinParam().getConditionStyle(); @@ -85,9 +87,12 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator { final FontConfiguration fcDiamond = new FontConfiguration(skinParam(), FontParam.ACTIVITY_DIAMOND, null); final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null); - Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, repeat, test, yes, out, - borderColor, backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), fcDiamond, - fcArrow); + final Ftile backStart = Display.isNull(startLabel) ? null : this.activity(startLabel, swimlane, BoxStyle.PLAIN, + Colors.empty()); + + Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, backStart, repeat, test, yes, + out, borderColor, backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), + fcDiamond, fcArrow, backward); final List weldingPoints = repeat.getWeldingPoints(); if (weldingPoints.size() > 0) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java index c62b08418..8bed0718b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java @@ -79,6 +79,7 @@ class FtileRepeat extends AbstractFtile { private final Ftile repeat; private final Ftile diamond1; private final Ftile diamond2; + private final Ftile backward; private final TextBlock tbTest; @Override @@ -86,12 +87,13 @@ class FtileRepeat extends AbstractFtile { return Arrays.asList(repeat, diamond1, diamond2); } - private FtileRepeat(Ftile repeat, Ftile diamond1, Ftile diamond2, TextBlock tbTest) { + private FtileRepeat(Ftile repeat, Ftile diamond1, Ftile diamond2, TextBlock tbTest, Ftile backward) { super(repeat.skinParam()); this.repeat = repeat; this.diamond1 = diamond1; this.diamond2 = diamond2; this.tbTest = tbTest; + this.backward = backward; } public Swimlane getSwimlaneIn() { @@ -100,7 +102,6 @@ class FtileRepeat extends AbstractFtile { public Swimlane getSwimlaneOut() { return diamond2.getSwimlaneOut(); - // return getSwimlaneIn(); } public Set getSwimlanes() { @@ -108,9 +109,9 @@ class FtileRepeat extends AbstractFtile { } public static Ftile create(LinkRendering backRepeatLinkRendering, Swimlane swimlane, Swimlane swimlaneOut, - Ftile repeat, Display test, Display yes, Display out, HtmlColor borderColor, HtmlColor backColor, - Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle, ISkinSimple spriteContainer, - FontConfiguration fcDiamond, FontConfiguration fcArrow) { + Ftile backStart, Ftile repeat, Display test, Display yes, Display out, HtmlColor borderColor, + HtmlColor backColor, Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle, + ISkinSimple spriteContainer, FontConfiguration fcDiamond, FontConfiguration fcArrow, Ftile backward) { final FontConfiguration fontConfiguration1 = conditionStyle == ConditionStyle.INSIDE ? fcDiamond : fcArrow; @@ -120,19 +121,24 @@ class FtileRepeat extends AbstractFtile { final TextBlock yesTb = yes.create(fcArrow, HorizontalAlignment.LEFT, spriteContainer); final TextBlock outTb = out.create(fcArrow, HorizontalAlignment.LEFT, spriteContainer); - final Ftile diamond1 = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane); + final Ftile diamond1; + if (backStart == null) { + diamond1 = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane); + } else { + diamond1 = backStart; + } final FtileRepeat result; if (conditionStyle == ConditionStyle.INSIDE) { final Ftile diamond2 = new FtileDiamondInside(repeat.skinParam(), backColor, borderColor, swimlaneOut, tbTest).withEast(yesTb).withSouth(outTb); - result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0)); + result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward); } else if (conditionStyle == ConditionStyle.DIAMOND) { final Ftile diamond2 = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane) .withEast(tbTest); - result = new FtileRepeat(repeat, diamond1, diamond2, tbTest); + result = new FtileRepeat(repeat, diamond1, diamond2, tbTest, backward); } else if (conditionStyle == ConditionStyle.FOO1) { final Ftile diamond2 = new FtileDiamondFoo1(repeat.skinParam(), backColor, borderColor, swimlane, tbTest); - result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0)); + result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward); } else { throw new IllegalStateException(); } @@ -147,7 +153,13 @@ class FtileRepeat extends AbstractFtile { final TextBlock tbbackLink1 = backLink1 == null ? null : backLink1.create(fcArrow, HorizontalAlignment.LEFT, spriteContainer, CreoleMode.SIMPLE_LINE); if (repeat.getSwimlaneIn() == repeat.getSwimlaneOut()) { - conns.add(result.new ConnectionBackSimple(backRepeatLinkRendering.getRainbow(arrowColor), tbbackLink1)); + if (backward == null) { + conns.add(result.new ConnectionBackSimple(backRepeatLinkRendering.getRainbow(arrowColor), tbbackLink1)); + } else { + conns.add(result.new ConnectionBackBackward1(backRepeatLinkRendering.getRainbow(arrowColor), + tbbackLink1)); + conns.add(result.new ConnectionBackBackward2(backRepeatLinkRendering.getRainbow(arrowColor))); + } } else { conns.add(result.new ConnectionBackComplex1(backRepeatLinkRendering.getRainbow(arrowColor))); conns.add(result.new ConnectionBackComplexHorizontalOnly(backRepeatLinkRendering.getRainbow(arrowColor), @@ -335,6 +347,86 @@ class FtileRepeat extends AbstractFtile { } + class ConnectionBackBackward1 extends AbstractConnection { + private final Rainbow arrowColor; + private final TextBlock tbback; + + public ConnectionBackBackward1(Rainbow arrowColor, TextBlock tbback) { + super(diamond2, backward); + this.arrowColor = arrowColor; + this.tbback = tbback; + } + + private Point2D getP1(final StringBounder stringBounder) { + return getTranslateDiamond2(stringBounder).getTranslated(new Point2D.Double(0, 0)); + } + + private Point2D getP2(final StringBounder stringBounder) { + final FtileGeometry dim = backward.calculateDimension(stringBounder); + return getTranslateBackward(stringBounder).getTranslated(new Point2D.Double(dim.getLeft(), dim.getOutY())); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + + final Snake snake = new Snake(arrowColor, Arrows.asToUp()); + snake.setLabel(tbback); + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + final Dimension2D dimDiamond2 = diamond2.calculateDimension(stringBounder); + final double x1 = p1.getX() + dimDiamond2.getWidth(); + final double y1 = p1.getY() + dimDiamond2.getHeight() / 2; + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + snake.addPoint(x1, y1); + snake.addPoint(x2, y1); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + } + + class ConnectionBackBackward2 extends AbstractConnection { + private final Rainbow arrowColor; + + public ConnectionBackBackward2(Rainbow arrowColor) { + super(backward, diamond1); + this.arrowColor = arrowColor; + } + + private Point2D getP1(final StringBounder stringBounder) { + final FtileGeometry dim = backward.calculateDimension(stringBounder); + return getTranslateBackward(stringBounder).getTranslated(new Point2D.Double(dim.getLeft(), dim.getInY())); + } + + private Point2D getP2(final StringBounder stringBounder) { + return getTranslateDiamond1(stringBounder).getTranslated(new Point2D.Double(0, 0)); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + + final Snake snake = new Snake(arrowColor, Arrows.asToLeft()); + snake.emphasizeDirection(Direction.UP); + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + final Dimension2D dimDiamond1 = diamond1.calculateDimension(stringBounder); + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2.getX() + dimDiamond1.getWidth(); + final double y2 = p2.getY() + dimDiamond1.getHeight() / 2; + + snake.addPoint(x1, y1); + snake.addPoint(x1, y2); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + } + class ConnectionBackSimple extends AbstractConnection { private final Rainbow arrowColor; private final TextBlock tbback; @@ -385,6 +477,9 @@ class FtileRepeat extends AbstractFtile { ug.apply(getTranslateForRepeat(stringBounder)).draw(repeat); ug.apply(getTranslateDiamond1(stringBounder)).draw(diamond1); ug.apply(getTranslateDiamond2(stringBounder)).draw(diamond2); + if (backward != null) { + ug.apply(getTranslateBackward(stringBounder)).draw(backward); + } } @@ -402,6 +497,9 @@ class FtileRepeat extends AbstractFtile { double width = getLeft(stringBounder) + getRight(stringBounder); width = Math.max(width, w + 2 * Diamond.diamondHalfSize); + if (backward != null) { + width += backward.calculateDimension(stringBounder).getWidth(); + } final double height = dimDiamond1.getHeight() + dimRepeat.getHeight() + dimDiamond2.getHeight() + 8 * Diamond.diamondHalfSize; return new Dimension2DDouble(width + 2 * Diamond.diamondHalfSize, height); @@ -439,6 +537,15 @@ class FtileRepeat extends AbstractFtile { return new UTranslate(left - dimDiamond1.getWidth() / 2, 0); } + private UTranslate getTranslateBackward(StringBounder stringBounder) { + final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); + final Dimension2D dimBackward = backward.calculateDimension(stringBounder); + final double x = dimTotal.getWidth() - dimBackward.getWidth(); + final double y = (dimTotal.getHeight() - dimBackward.getHeight()) / 2; + + return new UTranslate(x, y); + } + private UTranslate getTranslateDiamond2(StringBounder stringBounder) { final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimDiamond2 = diamond2.calculateDimension(stringBounder); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java index a05b2a194..2f90ff96e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java @@ -116,8 +116,8 @@ public class VCompactFactory implements FtileFactory { return new FtileAssemblySimple(tile1, tile2); } - public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Ftile repeat, Display test, Display yes, Display out, - HtmlColor color, LinkRendering backRepeatLinkRendering) { + public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test, Display yes, + Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward) { return repeat; } diff --git a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java index cd3689de6..c3f555e90 100644 --- a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java +++ b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java @@ -47,6 +47,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.GeneratedImage; import net.sourceforge.plantuml.Option; import net.sourceforge.plantuml.OptionFlags; @@ -190,8 +191,8 @@ public class PlantUmlTask extends Task { if (OptionFlags.getInstance().isVerbose()) { this.log("Processing " + f.getAbsolutePath()); } - final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), - option.getConfig(), option.getCharset(), option.getFileFormatOption()); + final SourceFileReader sourceFileReader = new SourceFileReader(Defines.createWithFileName(f), f, + option.getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); if (option.isCheckOnly()) { return sourceFileReader.hasError(); @@ -300,43 +301,43 @@ public class PlantUmlTask extends Task { public void setFormat(String s) { if ("scxml".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.SCXML); + option.setFileFormatOption(new FileFormatOption(FileFormat.SCXML)); } if ("xmi".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.XMI_STANDARD); + option.setFileFormatOption(new FileFormatOption(FileFormat.XMI_STANDARD)); } if ("xmi:argo".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.XMI_ARGO); + option.setFileFormatOption(new FileFormatOption(FileFormat.XMI_ARGO)); } if ("xmi:start".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.XMI_STAR); + option.setFileFormatOption(new FileFormatOption(FileFormat.XMI_STAR)); } if ("eps".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.EPS); + option.setFileFormatOption(new FileFormatOption(FileFormat.EPS)); } if ("braille".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.BRAILLE_PNG); + option.setFileFormatOption(new FileFormatOption(FileFormat.BRAILLE_PNG)); } if ("pdf".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.PDF); + option.setFileFormatOption(new FileFormatOption(FileFormat.PDF)); } if ("latex".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.LATEX); + option.setFileFormatOption(new FileFormatOption(FileFormat.LATEX)); } if ("latex:nopreamble".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.LATEX_NO_PREAMBLE); + option.setFileFormatOption(new FileFormatOption(FileFormat.LATEX_NO_PREAMBLE)); } if ("eps:text".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.EPS_TEXT); + option.setFileFormatOption(new FileFormatOption(FileFormat.EPS_TEXT)); } if ("svg".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.SVG); + option.setFileFormatOption(new FileFormatOption(FileFormat.SVG)); } if ("txt".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.ATXT); + option.setFileFormatOption(new FileFormatOption(FileFormat.ATXT)); } if ("utxt".equalsIgnoreCase(s)) { - option.setFileFormat(FileFormat.UTXT); + option.setFileFormatOption(new FileFormatOption(FileFormat.UTXT)); } } diff --git a/src/net/sourceforge/plantuml/api/ApiWarning.java b/src/net/sourceforge/plantuml/api/ApiWarning.java new file mode 100644 index 000000000..2d6553a38 --- /dev/null +++ b/src/net/sourceforge/plantuml/api/ApiWarning.java @@ -0,0 +1,13 @@ +package net.sourceforge.plantuml.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD }) +public @interface ApiWarning { + + String willBeRemoved() default ""; +} diff --git a/src/net/sourceforge/plantuml/bpm/BpmBranch.java b/src/net/sourceforge/plantuml/bpm/BpmBranch.java new file mode 100644 index 000000000..f1eaf67f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/BpmBranch.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +public class BpmBranch { + + private final int uid; + private int counter = 1; + + public BpmBranch(int uid) { + this.uid = uid; + } + + public int incAndGetCounter() { + counter++; + return counter; + } + + private String getEntryId() { + return "$branchA" + uid; + } + + private String getExitId() { + return "$branchB" + uid; + } + + public BpmElement getEntryElement() { + return new BpmElement(getEntryId(), BpmElementType.MERGE, null); + } + + public BpmElement getElseElement() { + return new BpmElement(getExitId(), BpmElementType.MERGE, null); + } + + public BpmEvent getResumeEntryEvent() { + return new BpmEventResume(getEntryId()); + } + + public BpmEvent getGoToEndEvent() { + return new BpmEventGoto(getExitId()); + } + +} diff --git a/src/net/sourceforge/plantuml/bpm/BpmDiagram.java b/src/net/sourceforge/plantuml/bpm/BpmDiagram.java index 691fb4013..715dc598c 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmDiagram.java +++ b/src/net/sourceforge/plantuml/bpm/BpmDiagram.java @@ -36,7 +36,9 @@ package net.sourceforge.plantuml.bpm; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import net.sourceforge.plantuml.FileFormatOption; @@ -52,9 +54,9 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder; public class BpmDiagram extends UmlDiagram { private final BpmElement start = new BpmElement(null, BpmElementType.START); - private BpmElement last = start; private List events = new ArrayList(); + private Deque branches = new ArrayDeque(); public DiagramDescription getDescription() { return new DiagramDescription("(Bpm Diagram)"); @@ -80,69 +82,112 @@ public class BpmDiagram extends UmlDiagram { private UDrawable getUDrawable() { final Grid grid = createGrid(); + cleanGrid(grid); final GridArray gridArray = grid.toArray(SkinParam.create(getUmlDiagramType())); - gridArray.addEdges(edges); + // gridArray.addEdges(edges); System.err.println("gridArray=" + gridArray); return gridArray; } + private void cleanGrid(Grid grid) { + // while (true) { + // final boolean v1 = new CleanerEmptyLine().clean(grid); + // final boolean v2 = new CleanerInterleavingLines().clean(grid); + // if (v1 == false && v2 == false) { + // return; + // } + // } + } + public CommandExecutionResult addEvent(BpmEvent event) { this.events.add(event); return CommandExecutionResult.ok(); } private Coord current; - private final List edges = new ArrayList(); + private Cell last; private Grid createGrid() { final Grid grid = new Grid(); this.current = grid.getRoot(); - this.edges.clear(); + // this.edges.clear(); + last = grid.getCell(current); grid.getCell(current).setData(start); for (BpmEvent event : events) { if (event instanceof BpmEventAdd) { - addInGrid(grid, ((BpmEventAdd) event).getElement()); + final BpmEventAdd tmp = (BpmEventAdd) event; + addInGrid(grid, tmp.getElement()); } else if (event instanceof BpmEventResume) { final String idDestination = ((BpmEventResume) event).getId(); current = grid.getById(idDestination); - last = (BpmElement) grid.getCell(current).getData(); + last = grid.getCell(current); if (last == null) { throw new IllegalStateException(); } final Navigator nav = grid.linesOf(current); final Line newLine = new Line(); nav.insertAfter(newLine); - final Row row = current.getRow(); - current = new Coord(row, newLine); + final Col row = current.getCol(); + current = new Coord(newLine, row); } else if (event instanceof BpmEventGoto) { - final String idDestination = ((BpmEventGoto) event).getId(); - edges.add(new BpmEdge(last, (BpmElement) grid.getCell(grid.getById(idDestination)).getData())); + final BpmEventGoto tmp = (BpmEventGoto) event; + final String idDestination = tmp.getId(); current = grid.getById(idDestination); - last = (BpmElement) grid.getCell(current).getData(); + final Cell src = last; + last = grid.getCell(current); if (last == null) { throw new IllegalStateException(); } final Navigator nav = grid.linesOf(current); final Line newLine = new Line(); nav.insertAfter(newLine); - final Row row = current.getRow(); - current = new Coord(row, newLine); + final Col row = current.getCol(); + current = new Coord(newLine, row); + src.addConnectionTo(last); } else { throw new IllegalStateException(); } } + grid.addConnections(); + // for (GridEdge edge : edges) { + // System.err.println("EDGE=" + edge.getEdgeDirection()); + // edge.addLineIn(grid); + // } + // grid.addEdge(edges); return grid; } private void addInGrid(Grid grid, BpmElement element) { - final Navigator nav = grid.rowsOf(current); - final Row newRow = new Row(); + final Navigator nav = grid.colsOf(current); + final Col newRow = new Col(); nav.insertAfter(newRow); - current = new Coord(newRow, current.getLine()); + current = new Coord(current.getLine(), newRow); grid.getCell(current).setData(element); - edges.add(new BpmEdge(last, element)); - last = element; + last.addConnectionTo(grid.getCell(current)); + last = grid.getCell(current); } + + public CommandExecutionResult newBranch() { + final BpmBranch branch = new BpmBranch(events.size()); + branches.addLast(branch); + return addEvent(new BpmEventAdd(branch.getEntryElement())); + } + + public CommandExecutionResult elseBranch() { + final BpmBranch branch = branches.getLast(); + final int counter = branch.incAndGetCounter(); + if (counter == 2) { + addEvent(new BpmEventAdd(branch.getElseElement())); + return addEvent(branch.getResumeEntryEvent()); + } + addEvent(branch.getGoToEndEvent()); + return addEvent(branch.getResumeEntryEvent()); + } + + public CommandExecutionResult endBranch() { + final BpmBranch branch = branches.removeLast(); + return addEvent(branch.getGoToEndEvent()); + } } diff --git a/src/net/sourceforge/plantuml/bpm/BpmDiagramFactory.java b/src/net/sourceforge/plantuml/bpm/BpmDiagramFactory.java index 67b3ba8a0..5ce77be9f 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmDiagramFactory.java +++ b/src/net/sourceforge/plantuml/bpm/BpmDiagramFactory.java @@ -56,6 +56,9 @@ public class BpmDiagramFactory extends UmlDiagramFactory { result.add(new CommandMerge()); result.add(new CommandResume()); result.add(new CommandGoto()); + result.add(new CommandNewBranch()); + result.add(new CommandElseBranch()); + result.add(new CommandEndBranch()); return result; } diff --git a/src/net/sourceforge/plantuml/bpm/BpmElement.java b/src/net/sourceforge/plantuml/bpm/BpmElement.java index af1d57f67..8fa0363aa 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmElement.java +++ b/src/net/sourceforge/plantuml/bpm/BpmElement.java @@ -71,6 +71,9 @@ public class BpmElement implements Placeable { @Override public String toString() { + if (id == null) { + return type.toString() + "(" + display + ")"; + } return type.toString() + "(" + id + ")"; } @@ -92,10 +95,10 @@ public class BpmElement implements Placeable { return new FtileDiamond(skinParam, backColor, borderColor, null); } if (type == BpmElementType.DOCKED_EVENT) { - final UFont font = new UFont("Serif", Font.PLAIN, 14); + final UFont font = UFont.serif(14); return new FtileBox(skinParam, display, font, null, BoxStyle.PLAIN); } - final UFont font = new UFont("Serif", Font.PLAIN, 14); + final UFont font = UFont.serif(14); final FontConfiguration fc = new FontConfiguration(font, HtmlColorUtils.RED, HtmlColorUtils.RED, false); if (Display.isNull(display)) { return Display.getWithNewlines(type.toString()).create(fc, HorizontalAlignment.LEFT, skinParam); diff --git a/src/net/sourceforge/plantuml/bpm/BpmEventAdd.java b/src/net/sourceforge/plantuml/bpm/BpmEventAdd.java index e7fb42a8c..c6c408366 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmEventAdd.java +++ b/src/net/sourceforge/plantuml/bpm/BpmEventAdd.java @@ -45,4 +45,5 @@ public class BpmEventAdd implements BpmEvent { public final BpmElement getElement() { return element; } + } diff --git a/src/net/sourceforge/plantuml/bpm/Cell.java b/src/net/sourceforge/plantuml/bpm/Cell.java index 568aa3188..139ec1542 100644 --- a/src/net/sourceforge/plantuml/bpm/Cell.java +++ b/src/net/sourceforge/plantuml/bpm/Cell.java @@ -35,9 +35,14 @@ */ package net.sourceforge.plantuml.bpm; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class Cell { private Placeable data; + private final List destinations = new ArrayList(); public final Placeable getData() { return data; @@ -55,4 +60,12 @@ public class Cell { return super.toString() + " " + data; } + public void addConnectionTo(Cell other) { + this.destinations.add(other); + } + + public List getDestinations() { + return Collections.unmodifiableList(destinations); + } + } diff --git a/src/net/sourceforge/plantuml/bpm/Chain.java b/src/net/sourceforge/plantuml/bpm/Chain.java index ee67cf8b0..54cadf769 100644 --- a/src/net/sourceforge/plantuml/bpm/Chain.java +++ b/src/net/sourceforge/plantuml/bpm/Chain.java @@ -46,4 +46,6 @@ public interface Chain extends Comparator { public List toList(); + public boolean remove(O data); + } diff --git a/src/net/sourceforge/plantuml/bpm/ChainImpl.java b/src/net/sourceforge/plantuml/bpm/ChainImpl.java index 6a3aab19d..4c6fe2c58 100644 --- a/src/net/sourceforge/plantuml/bpm/ChainImpl.java +++ b/src/net/sourceforge/plantuml/bpm/ChainImpl.java @@ -46,6 +46,38 @@ public class ChainImpl implements Chain { private final List negative = new ArrayList(); private int currentVersion; + public boolean remove(O data) { + updateStructuralVersion(); + boolean result = positive.remove(data); + if (result == false) { + result = negative.remove(data); + } + return result; + } + + public int compare(O a, O b) { + if (a.equals(b)) { + return 0; + } + for (int i = negative.size() - 1; i >= 0; i--) { + if (a.equals(negative.get(i))) { + return -1; + } + if (b.equals(negative.get(i))) { + return 1; + } + } + for (O cur : positive) { + if (a.equals(cur)) { + return -1; + } + if (b.equals(cur)) { + return 1; + } + } + throw new UnsupportedOperationException(); + } + public List toList() { final List result = new ArrayList(); for (O element : negative) { @@ -207,8 +239,4 @@ public class ChainImpl implements Chain { } } - public int compare(O a, O b) { - throw new UnsupportedOperationException(); - } - } diff --git a/src/net/sourceforge/plantuml/applet/VersionApplet.java b/src/net/sourceforge/plantuml/bpm/CleanerEmptyLine.java similarity index 76% rename from src/net/sourceforge/plantuml/applet/VersionApplet.java rename to src/net/sourceforge/plantuml/bpm/CleanerEmptyLine.java index 2882a595a..f7b5536ad 100644 --- a/src/net/sourceforge/plantuml/applet/VersionApplet.java +++ b/src/net/sourceforge/plantuml/bpm/CleanerEmptyLine.java @@ -31,28 +31,22 @@ * * Original Author: Arnaud Roques * + * */ -package net.sourceforge.plantuml.applet; +package net.sourceforge.plantuml.bpm; -import java.applet.Applet; -import java.awt.Graphics; +public class CleanerEmptyLine implements GridCleaner { -import net.sourceforge.plantuml.version.Version; + public boolean clean(Grid grid) { + boolean result = false; + for (Line line : grid.lines().toList()) { + if (grid.usedColsOf(line).isEmpty()) { + grid.removeLine(line); + result = true; + } -public class VersionApplet extends Applet { - - @Override - public void init() { - super.init(); + } + return result; } - @Override - public void start() { - super.start(); - } - - @Override - public void paint(Graphics g) { - g.drawString(Version.versionString(), 0, 10); - } } diff --git a/src/net/sourceforge/plantuml/bpm/CleanerInterleavingLines.java b/src/net/sourceforge/plantuml/bpm/CleanerInterleavingLines.java new file mode 100644 index 000000000..6dfde043c --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/CleanerInterleavingLines.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.SortedSet; + +public class CleanerInterleavingLines implements GridCleaner { + + public boolean clean(Grid grid) { + boolean result = false; + Line previous = null; + for (Line line : grid.lines().toList()) { + if (previous != null) { + final Collection cols1 = grid.usedColsOf(previous); + final Collection cols2 = grid.usedColsOf(line); + if (Collections.disjoint(cols1, cols2)) { +// final SortedSet used1 = grid.colsConnectedTo(previous); +// final SortedSet used2 = grid.colsConnectedTo(line); +// if (mergeable(used1, used2)) { +// System.err.println("CAN BE MERGE!"); +// grid.mergeLines(previous, line); +// result = true; +// } + } + } + previous = line; + } + return result; + } + + private boolean mergeable(SortedSet used1, SortedSet used2) { + final Comparator s = used1.comparator(); + assert s == used2.comparator(); + if (s.compare(used1.last(), used2.first()) <= 0) { + return true; + } + if (s.compare(used2.last(), used1.first()) <= 0) { + return true; + } + return false; + } +} diff --git a/src/net/sourceforge/plantuml/bpm/Row.java b/src/net/sourceforge/plantuml/bpm/Col.java similarity index 98% rename from src/net/sourceforge/plantuml/bpm/Row.java rename to src/net/sourceforge/plantuml/bpm/Col.java index e7a3b5719..9aa9f5bf5 100644 --- a/src/net/sourceforge/plantuml/bpm/Row.java +++ b/src/net/sourceforge/plantuml/bpm/Col.java @@ -35,6 +35,6 @@ */ package net.sourceforge.plantuml.bpm; -public class Row { +public class Col { } diff --git a/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java b/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java index 002855cd2..4b9f3b0cb 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java +++ b/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java @@ -59,7 +59,8 @@ public class CommandDockedEvent extends SingleLineCommand2 { protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { final String label = arg.get("LABEL", 0); - final BpmEvent event = new BpmEventAdd(new BpmElement(null, BpmElementType.DOCKED_EVENT, label)); + final BpmElement element = new BpmElement(null, BpmElementType.DOCKED_EVENT, label); + final BpmEvent event = new BpmEventAdd(element); return diagram.addEvent(event); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java b/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java new file mode 100644 index 000000000..b0fd49bbe --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandElseBranch extends SingleLineCommand2 { + + public CommandElseBranch() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("else"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + return diagram.elseBranch(); + } + +} diff --git a/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java b/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java new file mode 100644 index 000000000..c2153803c --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandEndBranch extends SingleLineCommand2 { + + public CommandEndBranch() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("end branch"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + return diagram.endBranch(); + } + +} diff --git a/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java b/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java new file mode 100644 index 000000000..de26cf921 --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandNewBranch extends SingleLineCommand2 { + + public CommandNewBranch() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("new branch"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + return diagram.newBranch(); + } + +} diff --git a/src/net/sourceforge/plantuml/bpm/ConnectorPuzzle.java b/src/net/sourceforge/plantuml/bpm/ConnectorPuzzle.java new file mode 100644 index 000000000..1317f6bb5 --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/ConnectorPuzzle.java @@ -0,0 +1,160 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.InnerStrategy; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class ConnectorPuzzle implements Placeable, TextBlock { + + public static enum Where { + NORTH(1), EAST(2), SOUTH(4), WEST(8); + + private int coding; + + private Where(int coding) { + this.coding = coding; + } + + String toShortString() { + return name().substring(0, 1); + } + } + + private static final ConnectorPuzzle all[] = new ConnectorPuzzle[16]; + private final int type; + + static { + for (int i = 0; i < all.length; i++) { + all[i] = new ConnectorPuzzle(i); + } + } + + public ConnectorPuzzle append(ConnectorPuzzle before) { + return all[this.type | before.type]; + } + + public static ConnectorPuzzle get(String value) { + int num = 0; + for (Where w : Where.values()) { + if (value.contains(w.toShortString())) { + num += w.coding; + } + } + return all[num]; + } + + public boolean have(Where where) { + return (type & where.coding) != 0; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + for (Where w : Where.values()) { + if (have(w)) { + sb.append(w.toShortString()); + } + } + if (sb.length() == 0) { + sb.append("NONE"); + } + + return sb.toString(); + } + + private ConnectorPuzzle(int type) { + this.type = type; + } + + public Dimension2D getDimension(StringBounder stringBounder, ISkinParam skinParam) { + return new Dimension2DDouble(20, 20); + } + + public TextBlock toTextBlock(ISkinParam skinParam) { + return this; + } + + public String getId() { + throw new UnsupportedOperationException(); + } + + public void drawU(UGraphic ug) { + // System.err.println("DRAWING " + toString()); + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)); + for (Where w : Where.values()) { + if (have(w)) { + drawLine(ug, w); + } + } + + } + + private void drawLine(UGraphic ug, Where w) { + if (w == Where.WEST) { + ug.apply(new UTranslate(0, 10)).draw(new ULine(10, 0)); + } + if (w == Where.EAST) { + ug.apply(new UTranslate(10, 10)).draw(new ULine(10, 0)); + } + if (w == Where.NORTH) { + ug.apply(new UTranslate(10, 0)).draw(new ULine(0, 10)); + } + if (w == Where.SOUTH) { + ug.apply(new UTranslate(10, 10)).draw(new ULine(0, 10)); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return new Dimension2DDouble(20, 20); + } + + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/bpm/Coord.java b/src/net/sourceforge/plantuml/bpm/Coord.java index 1c03aeb2e..42ea95e50 100644 --- a/src/net/sourceforge/plantuml/bpm/Coord.java +++ b/src/net/sourceforge/plantuml/bpm/Coord.java @@ -37,19 +37,24 @@ package net.sourceforge.plantuml.bpm; public class Coord { - private final Row row; private final Line line; + private final Col col; - public Coord(Row row, Line line) { + public Coord(Line line, Col row) { if (line == null || row == null) { throw new IllegalArgumentException(); } this.line = line; - this.row = row; + this.col = row; } - public final Row getRow() { - return row; + public final Col getCol() { + return col; + } + + @Override + public String toString() { + return "line=" + line + " col=" + col; } public final Line getLine() { @@ -58,13 +63,13 @@ public class Coord { @Override public int hashCode() { - return row.hashCode() + line.hashCode(); + return line.hashCode() + col.hashCode(); } @Override public boolean equals(Object obj) { final Coord other = (Coord) obj; - return this.row == other.row && this.line == other.line; + return this.line == other.line && this.col == other.col; } } diff --git a/src/net/sourceforge/plantuml/bpm/Grid.java b/src/net/sourceforge/plantuml/bpm/Grid.java index 0f34a53fd..e576174d6 100644 --- a/src/net/sourceforge/plantuml/bpm/Grid.java +++ b/src/net/sourceforge/plantuml/bpm/Grid.java @@ -35,38 +35,42 @@ */ package net.sourceforge.plantuml.bpm; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.ISkinParam; public class Grid { - private final Chain rows; private final Chain lines; + private final Chain cols; private final Coord root; private final Map cells = new HashMap(); public Grid() { - this.root = new Coord(new Row(), new Line()); - this.rows = new ChainImpl(root.getRow()); + this.root = new Coord(new Line(), new Col()); this.lines = new ChainImpl(root.getLine()); + this.cols = new ChainImpl(root.getCol()); this.cells.put(root, new Cell()); } public Cell getCell(Coord coord) { - return getCell(coord.getRow(), coord.getLine()); + return getCell(coord.getLine(), coord.getCol()); } - public Cell getCell(Row row, Line line) { - if (rows.contains(row) == false) { - throw new IllegalArgumentException(); - } + public Cell getCell(Line line, Col col) { if (lines.contains(line) == false) { throw new IllegalArgumentException(); } - final Coord coord = new Coord(row, line); + if (cols.contains(col) == false) { + throw new IllegalArgumentException(); + } + final Coord coord = new Coord(line, col); Cell result = cells.get(coord); if (result == null) { result = new Cell(); @@ -75,6 +79,62 @@ public class Grid { return result; } + // private Set edgeWith(Cell someCell) { + // // final Set result = new HashSet(); + // // for (GridEdge edge : edges) { + // // if (edge.match(someCell)) { + // // result.add(edge); + // // } + // // } + // // return Collections.unmodifiableSet(result); + // throw new UnsupportedOperationException(); + // + // } + // + // private Collection getCellsConnectedTo(Cell someCell) { + // final Set result = new HashSet(); + // final Set myEdges = edgeWith(someCell); + // for (Cell cell : cells.values()) { + // for (GridEdge edge : myEdges) { + // assert edge.match(someCell); + // if (edge.match(cell)) { + // result.add(cell); + // } + // } + // } + // return Collections.unmodifiableSet(result); + // } + // + // private SortedSet getColsConnectedTo(Cell someCell) { + // final SortedSet result = new TreeSet(cols); + // final Set myEdges = edgeWith(someCell); + // for (Map.Entry ent : cells.entrySet()) { + // for (GridEdge edge : myEdges) { + // assert edge.match(someCell); + // if (edge.match(ent.getValue())) { + // result.add(ent.getKey().getCol()); + // } + // } + // } + // return Collections.unmodifiableSortedSet(result); + // } + + // public SortedSet colsConnectedTo(Line line) { + // final SortedSet result = new TreeSet(cols); + // for (Map.Entry ent : cells.entrySet()) { + // final Cell cell = ent.getValue(); + // if (cell == null || cell.getData() == null) { + // continue; + // } + // if (ent.getKey().getLine() != line) { + // continue; + // } + // result.addAll(getColsConnectedTo(ent.getValue())); + // + // } + // return Collections.unmodifiableSortedSet(result); + // } + public Coord getById(String id) { for (Map.Entry ent : cells.entrySet()) { final Cell cell = ent.getValue(); @@ -92,15 +152,15 @@ public class Grid { return root; } - public final Chain rows() { - return rows; - } - public final Chain lines() { return lines; } - private final Coord getCoord(Cell cell) { + public final Chain cols() { + return cols; + } + + public final Coord getCoord(Cell cell) { for (Map.Entry ent : cells.entrySet()) { if (ent.getValue() == cell) { return ent.getKey(); @@ -109,35 +169,173 @@ public class Grid { throw new IllegalArgumentException(); } - public final Navigator rowsOf(Coord coord) { - return rows.navigator(coord.getRow()); - } - public final Navigator linesOf(Coord coord) { return lines.navigator(coord.getLine()); } - public final Navigator rowsOf(Cell cell) { - return rowsOf(getCoord(cell)); + public final Navigator colsOf(Coord coord) { + return cols.navigator(coord.getCol()); } public final Navigator linesOf(Cell cell) { return linesOf(getCoord(cell)); } + public final Navigator colsOf(Cell cell) { + return colsOf(getCoord(cell)); + } + public final GridArray toArray(ISkinParam skinParam) { - final List rows = this.rows.toList(); final List lines = this.lines.toList(); - final GridArray result = new GridArray(skinParam, rows.size(), lines.size()); + final List cols = this.cols.toList(); + final GridArray result = new GridArray(skinParam, lines.size(), cols.size()); for (Map.Entry ent : cells.entrySet()) { - final int r = rows.indexOf(ent.getKey().getRow()); final int l = lines.indexOf(ent.getKey().getLine()); + final int r = cols.indexOf(ent.getKey().getCol()); if (r == -1 || l == -1) { throw new IllegalStateException(); } - result.setData(r, l, ent.getValue().getData()); + result.setData(l, r, ent.getValue().getData()); } return result; } + // public boolean isRowEmpty(Col row) { + // System.err.println("Testing Row " + row); + // for (Map.Entry ent : cells.entrySet()) { + // final Cell cell = ent.getValue(); + // if (cell == null || cell.getData() == null) { + // continue; + // } + // if (ent.getKey().getCol() == row) { + // System.err.println("Not empty " + cell + " " + cell.getData()); + // return false; + // } + // } + // System.err.println("EMPTY!!!"); + // return true; + // } + + // public boolean isLineEmpty(Line line) { + // for (Map.Entry ent : cells.entrySet()) { + // final Cell cell = ent.getValue(); + // if (cell == null || cell.getData() == null) { + // continue; + // } + // if (ent.getKey().getLine() == line) { + // return false; + // } + // } + // return true; + // } + + public Set usedColsOf(Line line) { + final Set result = new HashSet(); + for (Map.Entry ent : cells.entrySet()) { + final Cell cell = ent.getValue(); + if (cell == null || cell.getData() == null) { + continue; + } + if (ent.getKey().getLine() == line) { + result.add(ent.getKey().getCol()); + } + } + return Collections.unmodifiableSet(result); + } + + public void removeLine(Line line) { + assert usedColsOf(line).isEmpty(); + final boolean done = lines.remove(line); + if (done == false) { + throw new IllegalArgumentException(); + } + } + + // public void addEdge(Collection other) { + // this.edges.addAll(other); + // } + + public void mergeLines(Line source, Line dest) { + final Map supp = new HashMap(); + + for (Iterator> it = cells.entrySet().iterator(); it.hasNext();) { + final Map.Entry ent = it.next(); + final Cell cell = ent.getValue(); + if (cell == null || cell.getData() == null) { + continue; + } + if (ent.getKey().getLine() == source) { + supp.put(new Coord(dest, ent.getKey().getCol()), cell); + it.remove(); + } + } + cells.putAll(supp); + removeLine(source); + } + + public void addConnections() { + for (Map.Entry ent : new HashMap(cells).entrySet()) { + final List dests = ent.getValue().getDestinations(); + final Coord src = ent.getKey(); + for (int i = 0; i < dests.size(); i++) { + final Coord dest = getCoord(dests.get(i)); + final boolean startHorizontal = i == 0; + if (startHorizontal) { + System.err.println("DrawingHorizontal " + ent.getValue() + " --> " + dests.get(i) + " " + i); + drawHorizontal(src, dest); + } else { + // drawVertical(src, dest); + } + } + } + } + + private void drawVertical(final Coord src, final Coord dest) { + for (Navigator itLine = Navigators.iterate(lines, src.getLine(), dest.getLine()); itLine.get() != dest + .getLine();) { + final Line cur = itLine.next(); + if (cur != dest.getLine()) { + Cell tmp = getCell(cur, src.getCol()); + addPuzzle(tmp, "NS"); + } + } + for (Navigator itCol = Navigators.iterate(cols, src.getCol(), dest.getCol()); itCol.get() != dest.getCol();) { + final Col cur = itCol.next(); + if (cur != dest.getCol()) { + Cell tmp = getCell(dest.getLine(), cur); + addPuzzle(tmp, "EW"); + } + } + + } + + private void drawHorizontal(final Coord src, final Coord dest) { + for (Navigator itCol = Navigators.iterate(cols, src.getCol(), dest.getCol()); itCol.get() != dest.getCol();) { + final Col cur = itCol.next(); + if (cur != dest.getCol()) { + Cell tmp = getCell(src.getLine(), cur); + addPuzzle(tmp, "EW"); + } + } + System.err.println("src=" + src + " " + getCell(src)); + System.err.println("dest=" + dest + " " + getCell(dest)); + for (Navigator itLine = Navigators.iterate(lines, src.getLine(), dest.getLine()); itLine.get() != dest + .getLine();) { + final Line cur = itLine.next(); + if (cur != dest.getLine()) { + Cell tmp = getCell(cur, src.getCol()); + addPuzzle(tmp, "NS"); + } + } + } + + private void addPuzzle(Cell tmp, String direction) { + ConnectorPuzzle after = ConnectorPuzzle.get(direction); + final ConnectorPuzzle before = (ConnectorPuzzle) tmp.getData(); + if (before != null) { + after = after.append(before); + } + tmp.setData(after); + } + } diff --git a/src/net/sourceforge/plantuml/bpm/GridArray.java b/src/net/sourceforge/plantuml/bpm/GridArray.java index 5d7cdfce0..d2a984882 100644 --- a/src/net/sourceforge/plantuml/bpm/GridArray.java +++ b/src/net/sourceforge/plantuml/bpm/GridArray.java @@ -37,8 +37,6 @@ package net.sourceforge.plantuml.bpm; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.List; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.graphic.HtmlColorUtils; @@ -51,34 +49,35 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class GridArray implements UDrawable { - private final int rows; private final int lines; + private final int cols; private final Placeable data[][]; private final ISkinParam skinParam; - private final List edges = new ArrayList(); - public GridArray(ISkinParam skinParam, int rows, int lines) { + // private final List edges = new ArrayList(); + + public GridArray(ISkinParam skinParam, int lines, int cols) { this.skinParam = skinParam; - this.rows = rows; this.lines = lines; - this.data = new Placeable[rows][lines]; + this.cols = cols; + this.data = new Placeable[lines][cols]; } @Override public String toString() { - return "" + lines + "x" + rows; + return "" + lines + "x" + cols; } - public void setData(int r, int l, Placeable element) { - data[r][l] = element; + public void setData(int l, int c, Placeable element) { + data[l][c] = element; } - public Placeable getData(int r, int l) { - return data[r][l]; + public Placeable getData(int l, int c) { + return data[l][c]; } public final int getRows() { - return rows; + return cols; } public final int getLines() { @@ -87,8 +86,8 @@ public class GridArray implements UDrawable { private double getHeightOfLine(StringBounder stringBounder, int line) { double height = 0; - for (int i = 0; i < rows; i++) { - final Placeable cell = data[i][line]; + for (int i = 0; i < cols; i++) { + final Placeable cell = data[line][i]; if (cell == null) { continue; } @@ -97,10 +96,10 @@ public class GridArray implements UDrawable { return height; } - private double getWidthOfRow(StringBounder stringBounder, int row) { + private double getWidthOfCol(StringBounder stringBounder, int col) { double width = 0; for (int i = 0; i < lines; i++) { - final Placeable cell = data[row][i]; + final Placeable cell = data[i][col]; if (cell == null) { continue; } @@ -115,48 +114,74 @@ public class GridArray implements UDrawable { // printMe(); final StringBounder stringBounder = ug.getStringBounder(); - for (BpmEdge edge : edges) { - // System.err.println("Drawing " + edge); - final int from[] = getCoord(edge.getFrom()); - final int to[] = getCoord(edge.getTo()); - final Point2D pt1 = getCenterOf(stringBounder, from[0], from[1]); - final Point2D pt2 = getCenterOf(stringBounder, to[0], to[1]); - drawArrow(ug, pt1, pt2); - } + + // for (GridEdge edge : edges) { + // // System.err.println("Drawing " + edge); + // final int from[] = getCoord(edge.getFrom()); + // final int to[] = getCoord(edge.getTo()); + // final Point2D pt1 = getCenterOf(stringBounder, from[0], from[1]); + // final Point2D pt2 = getCenterOf(stringBounder, to[0], to[1]); + // drawArrow(ug, pt1, pt2); + // } + double dy = 0; + drawInternalGrid(ug); for (int l = 0; l < lines; l++) { double dx = 0; final double heightOfLine = getHeightOfLine(stringBounder, l); - for (int r = 0; r < rows; r++) { - final double widthOfRow = getWidthOfRow(stringBounder, r); - final Placeable cell = data[r][l]; + for (int r = 0; r < cols; r++) { + final double widthOfCol = getWidthOfCol(stringBounder, r); + final Placeable cell = data[l][r]; if (cell != null) { final Dimension2D dim = cell.getDimension(stringBounder, skinParam); cell.toTextBlock(skinParam).drawU( - ug.apply(new UTranslate(dx + (widthOfRow - dim.getWidth()) / 2, dy - + (heightOfLine - dim.getHeight()) / 2))); + ug.apply(new UTranslate(dx + (widthOfCol + margin - dim.getWidth()) / 2, dy + + (heightOfLine + margin - dim.getHeight()) / 2))); } - dx += widthOfRow + margin; + dx += widthOfCol + margin; } dy += heightOfLine + margin; } } + private void drawInternalGrid(UGraphic ug) { + double heightMax = 0; + for (int l = 0; l < lines; l++) { + heightMax += getHeightOfLine(ug.getStringBounder(), l) + margin; + } + double widthMax = 0; + for (int c = 0; c < cols; c++) { + widthMax += getWidthOfCol(ug.getStringBounder(), c) + margin; + } + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK)); + double y = 0; + for (int l = 0; l < lines; l++) { + ug.apply(new UTranslate(0, y)).draw(new ULine(widthMax, 0)); + y += getHeightOfLine(ug.getStringBounder(), l) + margin; + } + double x = 0; + for (int c = 0; c < cols; c++) { + ug.apply(new UTranslate(x, 0)).draw(new ULine(0, heightMax)); + x += getWidthOfCol(ug.getStringBounder(), c) + margin; + } + + } + private void drawArrow(UGraphic ug, Point2D pt1, Point2D pt2) { ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)); final ULine line = new ULine(pt2.getX() - pt1.getX(), pt2.getY() - pt1.getY()); ug.apply(new UTranslate(pt1)).draw(line); } - private Point2D getCenterOf(StringBounder stringBounder, int r, int l) { - double x = getWidthOfRow(stringBounder, r) / 2; - for (int i = 0; i < r; i++) { - final double widthOfRow = getWidthOfRow(stringBounder, i); - x += widthOfRow + margin; + private Point2D getCenterOf(StringBounder stringBounder, int c, int l) { + double x = getWidthOfCol(stringBounder, c) / 2 + margin / 2; + for (int i = 0; i < c; i++) { + final double widthOfCol = getWidthOfCol(stringBounder, i); + x += widthOfCol + margin; } - double y = getHeightOfLine(stringBounder, l) / 2; + double y = getHeightOfLine(stringBounder, l) / 2 + margin / 2; for (int i = 0; i < l; i++) { final double heightOfLine = getHeightOfLine(stringBounder, i); y += heightOfLine + margin; @@ -164,12 +189,12 @@ public class GridArray implements UDrawable { return new Point2D.Double(x, y); } - private int[] getCoord(Placeable element) { + private int[] getCoord(Cell someCell) { for (int l = 0; l < lines; l++) { - for (int r = 0; r < rows; r++) { - final Placeable cell = data[r][l]; - if (cell == element) { - return new int[] { r, l }; + for (int c = 0; c < cols; c++) { + final Placeable cell = data[l][c]; + if (cell == someCell.getData()) { + return new int[] { c, l }; } } } @@ -178,8 +203,8 @@ public class GridArray implements UDrawable { private void printMe() { for (int l = 0; l < lines; l++) { - for (int r = 0; r < rows; r++) { - final Placeable cell = data[r][l]; + for (int c = 0; c < cols; c++) { + final Placeable cell = data[l][c]; System.err.print(cell); System.err.print(" ; "); } @@ -187,8 +212,8 @@ public class GridArray implements UDrawable { } } - public void addEdges(List edges) { - this.edges.addAll(edges); - } + // void addEdgesInternal(List edges) { + // this.edges.addAll(edges); + // } } diff --git a/src/net/sourceforge/plantuml/bpm/BpmEdge.java b/src/net/sourceforge/plantuml/bpm/GridCleaner.java similarity index 73% rename from src/net/sourceforge/plantuml/bpm/BpmEdge.java rename to src/net/sourceforge/plantuml/bpm/GridCleaner.java index 8527bfbca..1c3eefec1 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmEdge.java +++ b/src/net/sourceforge/plantuml/bpm/GridCleaner.java @@ -31,33 +31,12 @@ * * Original Author: Arnaud Roques * + * */ package net.sourceforge.plantuml.bpm; -public class BpmEdge { +public interface GridCleaner { - private final BpmElement from; - private final BpmElement to; - - public BpmEdge(BpmElement from, BpmElement to) { - if (from == null || to == null) { - throw new IllegalArgumentException(); - } - this.from = from; - this.to = to; - } - - public final BpmElement getFrom() { - return from; - } - - public final BpmElement getTo() { - return to; - } - - @Override - public String toString() { - return from.toString() + "-->" + to.toString(); - } + public boolean clean(Grid grid); } diff --git a/src/net/sourceforge/plantuml/bpm/Navigators.java b/src/net/sourceforge/plantuml/bpm/Navigators.java new file mode 100644 index 000000000..cc1ea2397 --- /dev/null +++ b/src/net/sourceforge/plantuml/bpm/Navigators.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.bpm; + +public final class Navigators { + + private Navigators() { + + } + + public static Navigator iterate(final Chain orig, final O from, final O to) { + if (orig.compare(from, to) <= 0) { + return orig.navigator(from); + } + return reverse(orig.navigator(to)); + } + + public static Navigator reverse(final Navigator orig) { + return new Navigator() { + + public O next() { + return orig.previous(); + } + + public O previous() { + return orig.next(); + } + + public O get() { + return orig.get(); + } + + public void set(O data) { + orig.set(data); + } + + public void insertBefore(O data) { + throw new UnsupportedOperationException(); + } + + public void insertAfter(O data) { + throw new UnsupportedOperationException(); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java b/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java index a306e5235..52daed8ad 100644 --- a/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java @@ -58,7 +58,16 @@ public abstract class AbstractEntityDiagram extends CucaDiagram { } final public DiagramDescription getDescription() { - return new DiagramDescription("(" + getLeafssize() + " entities)"); + final StringBuilder result = new StringBuilder("(" + getLeafssize() + " entities"); + final String id = getSource().getId(); + if (id == null) { + result.append(")"); + } else { + result.append(", "); + result.append(id); + result.append(")"); + } + return new DiagramDescription(result.toString()); } } diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index 15998b692..ffa50c6e2 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -117,7 +117,7 @@ public class ClassDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandImport()); final FactoryTipOnEntityCommand factoryTipOnEntityCommand = new FactoryTipOnEntityCommand(new RegexLeaf( - "ENTITY", "(" + CommandCreateClass.CODE_NO_DOTDOT + "|[%g][^%g]+[%g])::([^%s]+)")); + "ENTITY", "(" + CommandCreateClass.CODE_NO_DOTDOT + "|[%g][^%g]+[%g])::([%g][^%g]+[%g]|[^%s]+)")); cmds.add(factoryTipOnEntityCommand.createMultiLine(true)); cmds.add(factoryTipOnEntityCommand.createMultiLine(false)); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java index 303231098..d7e1fa97b 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java @@ -73,7 +73,7 @@ public class CommandCreateClass extends SingleLineCommand2 { private static RegexConcat getRegexConcat() { return new RegexConcat(new RegexLeaf("^"), // new RegexLeaf("TYPE", // - "(interface|enum|annotation|abstract[%s]+class|abstract|class|entity)[%s]+"), // + "(interface|enum|annotation|abstract[%s]+class|abstract|class|entity|circle)[%s]+"), // new RegexOr(// new RegexConcat(// new RegexLeaf("DISPLAY1", "[%g](.+)[%g]"), // diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index 50cc7c0b8..13183be24 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -160,7 +160,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2 extends PSy } first = false; if (StartUtils.isArobaseEndDiagram(s)) { - if (source.getTotalLineCount() == 2) { + if (source.getTotalLineCount() == 2 && source.isStartDef() == false) { return buildEmptyError(source, s.getLocation()); } if (system != null) { diff --git a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java index 7a5a57e7d..a70f5f232 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java @@ -106,7 +106,8 @@ public final class FactoryTipOnEntityCommand implements SingleMultiFactoryComman Url url = null; if (line0.get("URL", 0) != null) { - final UrlBuilder urlBuilder = new UrlBuilder(system.getSkinParam().getValue("topurl"), ModeUrl.STRICT); + final UrlBuilder urlBuilder = new UrlBuilder(system.getSkinParam().getValue("topurl"), + ModeUrl.STRICT); url = urlBuilder.getUrl(line0.get("URL", 0)); } @@ -121,7 +122,7 @@ public final class FactoryTipOnEntityCommand implements SingleMultiFactoryComman final String pos = line0.get("POSITION", 0); final Code code = Code.of(line0.get("ENTITY", 0)); - final String member = line0.get("ENTITY", 1); + final String member = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(line0.get("ENTITY", 1)); if (code == null) { return CommandExecutionResult.error("Nothing to note to"); } @@ -143,33 +144,6 @@ public final class FactoryTipOnEntityCommand implements SingleMultiFactoryComman diagram.addLink(link); } tips.putTip(member, lines.toDisplay()); - - // final IEntity note = diagram.createLeaf(UniqueSequence.getCode("GMN"), Display.create(s), LeafType.NOTE, - // null); - // note.setSpecificBackcolor(diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0))); - // if (url != null) { - // note.addUrl(url); - // } - // - // final Position position = Position.valueOf(StringUtils.goUpperCase(pos)).withRankdir( - // diagram.getSkinParam().getRankdir()); - // final Link link; - // - // final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); - // if (position == Position.RIGHT) { - // link = new Link(cl1, note, type, null, 1); - // link.setHorizontalSolitary(true); - // } else if (position == Position.LEFT) { - // link = new Link(note, cl1, type, null, 1); - // link.setHorizontalSolitary(true); - // } else if (position == Position.BOTTOM) { - // link = new Link(cl1, note, type, null, 2); - // } else if (position == Position.TOP) { - // link = new Link(note, cl1, type, null, 2); - // } else { - // throw new IllegalArgumentException(); - // } - // diagram.addLink(link); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/core/Diagram.java b/src/net/sourceforge/plantuml/core/Diagram.java index d40e57ff2..012808123 100644 --- a/src/net/sourceforge/plantuml/core/Diagram.java +++ b/src/net/sourceforge/plantuml/core/Diagram.java @@ -54,7 +54,7 @@ public interface Diagram { * @param os * where to write the image * @param num - * useually 0 (index of the image to be exported for this diagram). + * usually 0 (index of the image to be exported for this diagram). * @param fileFormat * file format to use * diff --git a/src/net/sourceforge/plantuml/core/DiagramType.java b/src/net/sourceforge/plantuml/core/DiagramType.java index 6b645552e..3b6de5813 100644 --- a/src/net/sourceforge/plantuml/core/DiagramType.java +++ b/src/net/sourceforge/plantuml/core/DiagramType.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.core; import net.sourceforge.plantuml.utils.StartUtils; public enum DiagramType { - UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, UNKNOWN; + UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, UNKNOWN; static public DiagramType getTypeFromArobaseStart(String s) { s = s.toLowerCase(); @@ -84,6 +84,9 @@ public enum DiagramType { if (StartUtils.startsWithSymbolAnd("startlatex", s)) { return LATEX; } + if (StartUtils.startsWithSymbolAnd("startdef", s)) { + return DEFINITION; + } return UNKNOWN; } } diff --git a/src/net/sourceforge/plantuml/core/UmlSource.java b/src/net/sourceforge/plantuml/core/UmlSource.java index 75d51966d..fbadb5d18 100644 --- a/src/net/sourceforge/plantuml/core/UmlSource.java +++ b/src/net/sourceforge/plantuml/core/UmlSource.java @@ -38,6 +38,8 @@ package net.sourceforge.plantuml.core; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.CharSequence2Impl; @@ -192,4 +194,16 @@ final public class UmlSource { return Display.empty(); } + public boolean isStartDef() { + return source.get(0).startsWith("@startdef"); + } + + public String getId() { + final Pattern p = Pattern.compile("id=([\\w]+)\\b"); + final Matcher m = p.matcher(source.get(0)); + if (m.find()) { + return m.group(1); + } + return null; + } } diff --git a/src/net/sourceforge/plantuml/creole/AtomEmbededSystem.java b/src/net/sourceforge/plantuml/creole/AtomEmbededSystem.java index 47af0d342..04b0e27a0 100644 --- a/src/net/sourceforge/plantuml/creole/AtomEmbededSystem.java +++ b/src/net/sourceforge/plantuml/creole/AtomEmbededSystem.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; import net.sourceforge.plantuml.ugraphic.UShape; @@ -109,7 +110,7 @@ class AtomEmbededSystem implements Atom { // } // private Diagram getSystem() throws IOException, InterruptedException { - final BlockUml blockUml = new BlockUml(lines2, 0); + final BlockUml blockUml = new BlockUml(lines2, 0, Defines.createEmpty()); return blockUml.getDiagram(); } diff --git a/src/net/sourceforge/plantuml/creole/AtomImg.java b/src/net/sourceforge/plantuml/creole/AtomImg.java index 2e2083c8a..b72defaa7 100644 --- a/src/net/sourceforge/plantuml/creole/AtomImg.java +++ b/src/net/sourceforge/plantuml/creole/AtomImg.java @@ -71,7 +71,7 @@ public class AtomImg implements Atom { } public static Atom create(String src, final ImgValign valign, final int vspace, final double scale) { - final UFont font = new UFont("Monospaced", Font.PLAIN, 14); + final UFont font = UFont.monospaced(14); final FontConfiguration fc = FontConfiguration.blackBlueTrue(font); if (src.startsWith(DATA_IMAGE_PNG_BASE64)) { diff --git a/src/net/sourceforge/plantuml/creole/AtomMath.java b/src/net/sourceforge/plantuml/creole/AtomMath.java index 469787df0..fb1025119 100644 --- a/src/net/sourceforge/plantuml/creole/AtomMath.java +++ b/src/net/sourceforge/plantuml/creole/AtomMath.java @@ -40,6 +40,7 @@ import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorSimple; import net.sourceforge.plantuml.graphic.StringBounder; @@ -90,7 +91,7 @@ public class AtomMath implements Atom { } final Color fore = getColor(foreground, Color.BLACK); if (isSvg) { - final String svg = math.getSvg(fore, back); + final SvgString svg = math.getSvg(scale, fore, back); ug.draw(new UImageSvg(svg)); } else { ug.draw(new UImage(math.getImage(scale, fore, back))); diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreole.java b/src/net/sourceforge/plantuml/creole/PSystemCreole.java index 65dcbaa6c..69d9fd138 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreole.java +++ b/src/net/sourceforge/plantuml/creole/PSystemCreole.java @@ -72,7 +72,7 @@ public class PSystemCreole extends AbstractPSystem { final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final Display display = Display.create(lines); - final UFont font = new UFont("Serif", Font.PLAIN, 14); + final UFont font = UFont.serif(14); final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(font); final Sheet sheet = new CreoleParser(fontConfiguration, HorizontalAlignment.LEFT, null, CreoleMode.FULL) .createSheet(display); diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock1.java b/src/net/sourceforge/plantuml/creole/SheetBlock1.java index f0920c6e4..e0813565d 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock1.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock1.java @@ -46,6 +46,7 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.ugraphic.MinMax; @@ -154,7 +155,7 @@ public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, S } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock2.java b/src/net/sourceforge/plantuml/creole/SheetBlock2.java index a2b1aa5b7..d4a6eba60 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock2.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock2.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -81,8 +82,8 @@ public class SheetBlock2 extends AbstractTextBlock implements TextBlock, Atom { } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - return block.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return block.getInnerPosition(member, stringBounder, strategy); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java index 4c78342cc..b3cce3590 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java @@ -207,4 +207,8 @@ public class Bodier { return TextBlockUtils.mergeTB(bb1, bb2, HorizontalAlignment.LEFT); } + public List getRawBody() { + return Collections.unmodifiableList(rawBody); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java index 1af1cca79..28ec670ce 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.creole.CreoleParser; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockLineBefore; @@ -85,7 +86,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo this.titleConfig = new FontConfiguration(skinParam, fontParam, stereotype); this.lineFirst = true; - this.align = HorizontalAlignment.LEFT; + this.align = skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT); this.manageHorizontalLine = true; this.manageModifier = manageModifier; this.entity = entity; @@ -104,7 +105,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo this.titleConfig = new FontConfiguration(skinParam, fontParam, stereotype); this.lineFirst = false; - this.align = align; + this.align = skinParam.getDefaultTextAlignment(align); this.manageHorizontalLine = manageHorizontalLine; this.manageModifier = manageModifier; @@ -163,8 +164,8 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo } } } - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, entity), - separator, title)); + blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, + entity), separator, title)); if (blocks.size() == 1) { this.area2 = blocks.get(0); @@ -231,8 +232,8 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo return Collections.unmodifiableList(urls); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - return getArea(stringBounder).getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return getArea(stringBounder).getInnerPosition(member, stringBounder, strategy); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index 25ca2424f..aa032fc10 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -116,7 +116,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, result = createLeafInternal(code, Display.getWithNewlines(code), type, getCurrentGroup(), symbol); result.setUSymbol(symbol); } - if (result.getEntityType() == LeafType.CLASS && type == LeafType.OBJECT) { + if (result.getLeafType() == LeafType.CLASS && type == LeafType.OBJECT) { if (result.muteToType(type, symbol) == false) { return null; } @@ -286,6 +286,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, if (aspect != null) { result.add("aspect=" + aspect + ";"); } + final String ratio = getPragma().getValue("ratio"); + if (ratio != null) { + result.add("ratio=" + ratio + ";"); + } return result.toArray(new String[result.size()]); } @@ -547,8 +551,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, final List links = getLinks(); for (int i = links.size() - 1; i >= 0; i--) { final Link link = links.get(i); - if (link.getEntity1().getEntityType() != LeafType.NOTE - && link.getEntity2().getEntityType() != LeafType.NOTE) { + if (link.getEntity1().getLeafType() != LeafType.NOTE && link.getEntity2().getLeafType() != LeafType.NOTE) { return link; } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index da443bcd3..ffbff27b5 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -80,12 +80,6 @@ public class Display implements Iterable { private final boolean isNull; private final CreoleMode defaultCreoleMode; -// public Display removeUrlHiddenNewLineUrl() { -// final String full = UrlBuilder.purgeUrl(asStringWithHiddenNewLine()); -// return new Display(StringUtils.splitHiddenNewLine(full), this.naturalHorizontalAlignment, this.isNull, -// this.defaultCreoleMode); -// } - public final static Display NULL = new Display(null, null, true, CreoleMode.FULL); public boolean isWhite() { @@ -116,9 +110,16 @@ public class Display implements Iterable { final List result = new ArrayList(); final StringBuilder current = new StringBuilder(); HorizontalAlignment naturalHorizontalAlignment = null; + boolean mathMode = false; for (int i = 0; i < s.length(); i++) { final char c = s.charAt(i); - if (c == '\\' && i < s.length() - 1) { + final String sub = s.substring(i); + if (sub.startsWith("") || sub.startsWith("")) { + mathMode = true; + } else if (sub.startsWith("") || sub.startsWith("")) { + mathMode = false; + } + if (mathMode == false && c == '\\' && i < s.length() - 1) { final char c2 = s.charAt(i + 1); i++; if (c2 == 'n' || c2 == 'r' || c2 == 'l') { @@ -300,27 +301,6 @@ public class Display implements Iterable { return Collections.unmodifiableList(result); } -// public Url initUrl() { -// if (this.size() == 0) { -// return null; -// } -// final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); -// return urlBuilder.getUrl(StringUtils.trin(this.get(0).toString())); -// } - -// public Display removeHeadingUrl(Url url) { -// if (url == null) { -// return this; -// } -// final Display result = new Display(this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); -// result.display.add(UrlBuilder.purgeUrl(this.get(0).toString())); -// result.display.addAll(this.subList(1, this.size()).display); -// if (result.isWhite() && url.getLabel() != null) { -// return Display.getWithNewlines(url.getLabel()); -// } -// return result; -// } - public boolean hasUrl() { final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.ANYWHERE); for (CharSequence s : this) { @@ -376,7 +356,8 @@ public class Display implements Iterable { public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, ISkinSimple spriteContainer, CreoleMode modeSimpleLine) { - return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, modeSimpleLine, null, null); + return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, modeSimpleLine, + null, null); } public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, diff --git a/src/net/sourceforge/plantuml/cucadiagram/Election.java b/src/net/sourceforge/plantuml/cucadiagram/Election.java index be13d6160..f2cd70135 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Election.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Election.java @@ -46,24 +46,24 @@ class Election { private final Map all = new HashMap(); - public void addCandidat(String display, Member candidat) { - all.put(display, candidat); + public void addCandidate(String display, Member candidate) { + all.put(display, candidate); } - private Member getCandidat(String shortName) { - List list = getAllCandidatContains(shortName); + private Member getCandidate(String shortName) { + List list = getAllCandidateContains(shortName); if (list.size() == 1) { return list.get(0); } - list = getAllCandidatContainsStrict(shortName); + list = getAllCandidateContainsStrict(shortName); if (list.size() == 1) { return list.get(0); } return null; } - private List getAllCandidatContains(String shortName) { + private List getAllCandidateContains(String shortName) { final List result = new ArrayList(); for (Map.Entry ent : all.entrySet()) { if (ent.getKey().contains(shortName)) { @@ -73,7 +73,7 @@ class Election { return result; } - private List getAllCandidatContainsStrict(String shortName) { + private List getAllCandidateContainsStrict(String shortName) { final List result = new ArrayList(); for (Map.Entry ent : all.entrySet()) { final String key = ent.getKey(); @@ -87,7 +87,7 @@ class Election { public Map getAllElected(Collection shortNames) { final Map memberWithPort = new HashMap(); for (String shortName : shortNames) { - final Member m = getCandidat(shortName); + final Member m = getCandidate(shortName); if (m != null) { memberWithPort.put(m, shortName); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java index e8bd72d96..9e7ad7b55 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java @@ -40,7 +40,7 @@ public class EntityGenderUtils { static public EntityGender byEntityType(final LeafType type) { return new EntityGender() { public boolean contains(IEntity test) { - return test.getEntityType() == type; + return test.getLeafType() == type; } }; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java index e7e313104..674a732f9 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java @@ -89,7 +89,7 @@ public class GroupRoot implements IGroup { } - public LeafType getEntityType() { + public LeafType getLeafType() { throw new UnsupportedOperationException(); } @@ -172,7 +172,7 @@ public class GroupRoot implements IGroup { } - public void overideImage(IEntityImage img, LeafType state) { + public void overrideImage(IEntityImage img, LeafType state) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java index eb1db069a..938cc4ecf 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java +++ b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java @@ -54,7 +54,7 @@ public interface IEntity extends SpecificBackcolorable, Hideable, Removeable, Li public void setUSymbol(USymbol symbol); - public LeafType getEntityType(); + public LeafType getLeafType(); public Display getDisplay(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/IGroup.java b/src/net/sourceforge/plantuml/cucadiagram/IGroup.java index c04e58e81..d7fc7ab79 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/IGroup.java +++ b/src/net/sourceforge/plantuml/cucadiagram/IGroup.java @@ -61,7 +61,7 @@ public interface IGroup extends IEntity { public PackageStyle getPackageStyle(); - public void overideImage(IEntityImage img, LeafType state); + public void overrideImage(IEntityImage img, LeafType state); public SingleStrategy getSingleStrategy(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java index 40ed15a2e..c5b8bac67 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java @@ -41,7 +41,7 @@ public enum LeafType { EMPTY_PACKAGE, - ABSTRACT_CLASS, CLASS, INTERFACE, ANNOTATION, LOLLIPOP, NOTE, TIPS, OBJECT, ASSOCIATION, ENUM, + ABSTRACT_CLASS, CLASS, INTERFACE, ANNOTATION, LOLLIPOP, NOTE, TIPS, OBJECT, ASSOCIATION, ENUM, CIRCLE, USECASE, @@ -57,12 +57,12 @@ public enum LeafType { STILL_UNKNOWN; - public static LeafType getLeafType(String arg0) { - arg0 = StringUtils.goUpperCase(arg0); - if (arg0.startsWith("ABSTRACT")) { + public static LeafType getLeafType(String type) { + type = StringUtils.goUpperCase(type); + if (type.startsWith("ABSTRACT")) { return LeafType.ABSTRACT_CLASS; } - return LeafType.valueOf(arg0); + return LeafType.valueOf(type); } public boolean isLikeClass() { diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index 9c13138bd..38653fe8f 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -374,7 +374,7 @@ public class Link implements Hideable, Removeable { } public boolean containsType(LeafType type) { - if (getEntity1().getEntityType() == type || getEntity2().getEntityType() == type) { + if (getEntity1().getLeafType() == type || getEntity2().getLeafType() == type) { return true; } return false; diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java index 1dee06ede..3957ffde0 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java @@ -66,7 +66,7 @@ public enum LinkDecor { ARROW(10, true, 0.5), ARROW_TRIANGLE(10, true, 0.8), ARROW_AND_CIRCLE(10, false, 0.5), CIRCLE(0, false, 0.5), CIRCLE_CONNECT(0, false, 0.5), PARENTHESIS(0, false, OptionFlags.USE_INTERFACE_EYE2 ? 0.5 - : 1.0), SQUARRE(0, false, 0.5), + : 1.0), SQUARE(0, false, 0.5), CIRCLE_CROSS(0, false, 0.5), PLUS(0, false, 1.5), SQUARRE_toberemoved(30, false, 0); @@ -121,7 +121,7 @@ public enum LinkDecor { return new ExtremityFactoryDiamond(true, backgroundColor); } else if (this == LinkDecor.CIRCLE) { return new ExtremityFactoryCircle(); - } else if (this == LinkDecor.SQUARRE) { + } else if (this == LinkDecor.SQUARE) { return new ExtremityFactorySquarre(); } else if (this == LinkDecor.PARENTHESIS) { return new ExtremityFactoryParenthesis(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkHat.java b/src/net/sourceforge/plantuml/cucadiagram/LinkHat.java index ab69b3e7f..526ea3161 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkHat.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkHat.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.cucadiagram; public enum LinkHat { - NONE /*, SQUARRE, CIRCLE, CIRCLE_CONNECT; + NONE /*, SQUARE, CIRCLE, CIRCLE_CONNECT; public ExtremityFactory getExtremityFactory() { if (this == LinkHat.CIRCLE) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkType.java b/src/net/sourceforge/plantuml/cucadiagram/LinkType.java index f21786b42..177e2393c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkType.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkType.java @@ -196,8 +196,8 @@ public class LinkType { return decor2; } - public boolean isExtendsOrAgregationOrCompositionOrPlus() { - return isExtends() || isAgregationOrComposition() || isPlus(); + public boolean isExtendsOrAggregationOrCompositionOrPlus() { + return isExtends() || isAggregationOrComposition() || isPlus(); } private boolean isExtends() { @@ -208,7 +208,7 @@ public class LinkType { return decor1 == LinkDecor.PLUS || decor2 == LinkDecor.PLUS; } - private boolean isAgregationOrComposition() { + private boolean isAggregationOrComposition() { return decor1 == LinkDecor.AGREGATION || decor2 == LinkDecor.AGREGATION || decor1 == LinkDecor.COMPOSITION || decor2 == LinkDecor.COMPOSITION; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java index a96a3c7e8..385edc66d 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockLineBefore; @@ -137,7 +138,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW double y = 0; final Election election = new Election(); for (Member m : members) { - election.addCandidat(m.getDisplay(false), m); + election.addCandidate(m.getDisplay(false), m); } final Map memberWithPort = election.getAllElected(leaf.getPortShortNames()); for (Member m : members) { @@ -196,8 +197,8 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - return bloc.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return bloc.getInnerPosition(member, stringBounder, strategy); } } @@ -236,7 +237,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { final ULayoutGroup group = getLayout(stringBounder); final Dimension2D dim = calculateDimension(stringBounder); return group.getInnerPosition(member, dim.getWidth(), dim.getHeight(), stringBounder); diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierActivity.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierActivity.java index e63dc2193..b3aa1e821 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierActivity.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierActivity.java @@ -72,7 +72,7 @@ public final class CucaDiagramSimplifierActivity { // } final IEntityImage img = computeImage(g); - g.overideImage(img, LeafType.ACTIVITY); + g.overrideImage(img, LeafType.ACTIVITY); changed = true; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierState.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierState.java index b58951984..fa6e9fe86 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierState.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifierState.java @@ -66,7 +66,7 @@ public final class CucaDiagramSimplifierState { for (IGroup g : groups) { if (diagram.isAutarkic(g)) { final IEntityImage img = computeImage(g); - g.overideImage(img, g.getGroupType() == GroupType.CONCURRENT_STATE ? LeafType.STATE_CONCURRENT + g.overrideImage(img, g.getGroupType() == GroupType.CONCURRENT_STATE ? LeafType.STATE_CONCURRENT : LeafType.STATE); changed = true; diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java b/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java index f93e8247d..57d5f04fe 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java @@ -42,12 +42,11 @@ import java.io.OutputStream; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.api.MyRunnable; import net.sourceforge.plantuml.api.TimeoutExecutor; public class ProcessRunner { - // http://steveliles.github.io/invoking_processes_from_java.html - public static long TIMEOUT = 15 * 60 * 1000L; private final String[] cmd; @@ -72,7 +71,9 @@ public class ProcessRunner { this.state = ProcessState.RUNNING(); final MainThread mainThread = new MainThread(cmd, dir, redirection, in); try { - final boolean done = new TimeoutExecutor(TIMEOUT).executeNow(mainThread); + // http://steveliles.github.io/invoking_processes_from_java.html + final long timeoutMs = OptionFlags.getInstance().getTimeoutMs(); + final boolean done = new TimeoutExecutor(timeoutMs).executeNow(mainThread); } finally { changeState.lock(); try { @@ -216,7 +217,7 @@ public class ProcessRunner { } public String getString() { - if (sb==null) { + if (sb == null) { return ""; } return sb.toString(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java index c8d7a4bda..26f0da739 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java @@ -74,7 +74,7 @@ public class EntityFactory { } public boolean isHidden(ILeaf leaf) { - if (hiddenTypes.contains(leaf.getEntityType())) { + if (hiddenTypes.contains(leaf.getLeafType())) { return true; } final Stereotype stereotype = leaf.getStereotype(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index 47df31704..e9e8b0966 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -156,7 +156,7 @@ final class EntityImpl implements ILeaf, IGroup { this.parentContainer = container; } - public LeafType getEntityType() { + public LeafType getLeafType() { return leafType; } @@ -417,7 +417,7 @@ final class EntityImpl implements ILeaf, IGroup { // ---- other - public void overideImage(IEntityImage img, LeafType leafType) { + public void overrideImage(IEntityImage img, LeafType leafType) { checkGroup(); this.svekImage = img; this.url = null; @@ -462,6 +462,9 @@ final class EntityImpl implements ILeaf, IGroup { } public USymbol getUSymbol() { + if (getLeafType() == LeafType.CIRCLE) { + return USymbol.INTERFACE; + } if (symbol != null && stereotype != null && stereotype.getSprite() != null) { return symbol.withStereoAlignment(HorizontalAlignment.RIGHT); } diff --git a/src/net/sourceforge/plantuml/definition/PSystemDefinition.java b/src/net/sourceforge/plantuml/definition/PSystemDefinition.java new file mode 100644 index 000000000..9b166dae1 --- /dev/null +++ b/src/net/sourceforge/plantuml/definition/PSystemDefinition.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.definition; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; +import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class PSystemDefinition extends AbstractPSystem implements UDrawable { + + private final List lines = new ArrayList(); + private final String startLine; + + public PSystemDefinition(String startLine) { + this.startLine = startLine; + } + + public DiagramDescription getDescription() { + return new DiagramDescription("(Definition)"); + } + + @Override + final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormatOption) + throws IOException { + final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, "", "", 0, 0, null, + false); + imageBuilder.setUDrawable(this); + + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); + } + + public void drawU(UGraphic ug) { + final UFont font = UFont.sansSerif(14); + final FontConfiguration fc = new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); + Display.getWithNewlines(startLine).create(fc, HorizontalAlignment.LEFT, new SpriteContainerEmpty()).drawU(ug); + } + + public void doCommandLine(String line) { + this.lines.add(line); + } + +} diff --git a/src/net/sourceforge/plantuml/definition/PSystemDefinitionFactory.java b/src/net/sourceforge/plantuml/definition/PSystemDefinitionFactory.java new file mode 100644 index 000000000..1307a5a1a --- /dev/null +++ b/src/net/sourceforge/plantuml/definition/PSystemDefinitionFactory.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.definition; + +import net.sourceforge.plantuml.command.PSystemBasicFactory; +import net.sourceforge.plantuml.core.DiagramType; + +public class PSystemDefinitionFactory extends PSystemBasicFactory { + + public PSystemDefinitionFactory() { + super(DiagramType.DEFINITION); + } + + public PSystemDefinition init(String startLine) { + if (getDiagramType() == DiagramType.DEFINITION) { + return new PSystemDefinition(startLine); + } + return null; + } + + @Override + public PSystemDefinition executeLine(PSystemDefinition system, String line) { + system.doCommandLine(line); + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java index 6c3ae04ef..487c3e9ad 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java @@ -106,7 +106,7 @@ public class DescriptionDiagram extends AbstractEntityDiagram { private boolean isUsecase() { for (ILeaf leaf : getLeafsvalues()) { - final LeafType type = leaf.getEntityType(); + final LeafType type = leaf.getLeafType(); final USymbol usymbol = leaf.getUSymbol(); if (type == LeafType.USECASE || usymbol == USymbol.ACTOR) { return true; @@ -121,7 +121,7 @@ public class DescriptionDiagram extends AbstractEntityDiagram { final LeafType defaultType = isUsecase() ? LeafType.DESCRIPTION : LeafType.DESCRIPTION; final USymbol defaultSymbol = isUsecase() ? USymbol.ACTOR : USymbol.INTERFACE; for (ILeaf leaf : getLeafsvalues()) { - if (leaf.getEntityType() == LeafType.STILL_UNKNOWN) { + if (leaf.getLeafType() == LeafType.STILL_UNKNOWN) { leaf.muteToType(defaultType, defaultSymbol); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java index 6227ee59c..0708c5556 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.descdiagram.DescriptionDiagram; @@ -163,6 +164,9 @@ public class CommandCreateElementFull extends SingleLineCommand2 2 ? codeRaw.charAt(0) : 0; } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java index e2108b17f..cbead183b 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java @@ -141,6 +141,9 @@ public class CommandCreateElementMultilines extends CommandMultilines2 { if (head1.equals("(0")) { d1 = LinkDecor.CIRCLE_CONNECT; } else if (head1.equals("#")) { - d1 = LinkDecor.SQUARRE; + d1 = LinkDecor.SQUARE; } else if (head1.equals("0")) { d1 = LinkDecor.CIRCLE; } else if (head1.equals("(")) { @@ -133,7 +133,7 @@ public class CommandLinkElement extends SingleLineCommand2 { if (head2.equals("0)")) { d2 = LinkDecor.CIRCLE_CONNECT; } else if (head2.equals("#")) { - d2 = LinkDecor.SQUARRE; + d2 = LinkDecor.SQUARE; } else if (head2.equals("0")) { d2 = LinkDecor.CIRCLE; } else if (head2.equals(")")) { diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java index 3ace979e2..a3a2a0196 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; 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.Code; import net.sourceforge.plantuml.cucadiagram.Display; @@ -62,10 +63,31 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2\\>))?"), // + new RegexLeaf("[%s]*as[%s]+"), // + new RegexLeaf("CODE1", "([^#%s{}]+)") // + ), // + new RegexConcat( // + new RegexLeaf("CODE2", "([^#%s{}%g]+)"), // + new RegexLeaf("STEREOTYPE2", "(?:[%s]+(\\<\\<.+\\>\\>))?"), // + new RegexLeaf("[%s]*as[%s]+"), // + new RegexLeaf("DISPLAY2", "([%g][^%g]+[%g])") // + ), // + new RegexConcat( // + new RegexLeaf("DISPLAY3", "([^#%s{}%g]+)"), // + new RegexLeaf("STEREOTYPE3", "(?:[%s]+(\\<\\<.+\\>\\>))?"), // + new RegexLeaf("[%s]*as[%s]+"), // + new RegexLeaf("CODE3", "([^#%s{}%g]+)") // + ), // + new RegexLeaf("CODE8", "([%g][^%g]+[%g])"), // + new RegexLeaf("CODE9", "([^#%s{}%g]*)") // + ), // new RegexLeaf("[%s]*"), // new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // new RegexLeaf("[%s]*"), // @@ -77,24 +99,25 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2 tilesBoxes = new HashMap(); private Tile lastTile; - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/golem/Tile.java b/src/net/sourceforge/plantuml/golem/Tile.java index 55a19e0bd..f9b5b0b9a 100644 --- a/src/net/sourceforge/plantuml/golem/Tile.java +++ b/src/net/sourceforge/plantuml/golem/Tile.java @@ -62,7 +62,7 @@ public class Tile extends AbstractTextBlock implements TextBlock { private static double SIZE = 40; private final int num; - private final UFont numberFont = new UFont("Monospaced", Font.PLAIN, 11); + private final UFont numberFont = UFont.monospaced(11); private final FontConfiguration fc = FontConfiguration.blackBlueTrue(numberFont); private final Map geometries; diff --git a/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java index 5be2f984c..073639dbc 100644 --- a/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java +++ b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java @@ -51,12 +51,12 @@ abstract class AbstractEntityImage { private final IEntity entity; final private HtmlColor red = HtmlColorUtils.MY_RED; - + final private HtmlColor yellow = HtmlColorUtils.MY_YELLOW; private final HtmlColor yellowNote = HtmlColorUtils.COL_FBFB77; - final private UFont font14 = new UFont("SansSerif", Font.PLAIN, 14); - final private UFont font17 = new UFont("Courier", Font.BOLD, 17); + final private UFont font14 = UFont.sansSerif(14); + final private UFont font17 = UFont.courier(17).bold(); final private HtmlColor green = HtmlColorUtils.COL_ADD1B2; final private HtmlColor violet = HtmlColorUtils.COL_B4A7E5; final private HtmlColor blue = HtmlColorUtils.COL_A9DCDF; diff --git a/src/net/sourceforge/plantuml/graphic/AbstractTextBlock.java b/src/net/sourceforge/plantuml/graphic/AbstractTextBlock.java index 94cd300fa..c93528151 100644 --- a/src/net/sourceforge/plantuml/graphic/AbstractTextBlock.java +++ b/src/net/sourceforge/plantuml/graphic/AbstractTextBlock.java @@ -39,7 +39,7 @@ import java.awt.geom.Rectangle2D; public abstract class AbstractTextBlock implements TextBlock { - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { throw new UnsupportedOperationException("member=" + member + " " + getClass().toString()); } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/DateEventUtils.java b/src/net/sourceforge/plantuml/graphic/DateEventUtils.java index bd6aeebed..1b3f28e55 100644 --- a/src/net/sourceforge/plantuml/graphic/DateEventUtils.java +++ b/src/net/sourceforge/plantuml/graphic/DateEventUtils.java @@ -153,7 +153,7 @@ public class DateEventUtils { // } // // public static TextBlock getComment(final List asList, HtmlColor color) { -// final UFont font = new UFont("SansSerif", Font.BOLD, 14); +// final UFont font = UFont.sansSerif(14).bold(); // TextBlock comment = Display.create(asList).create( // new FontConfiguration(font, color, HtmlColorUtils.BLUE, true), HorizontalAlignment.LEFT, // new SpriteContainerEmpty()); diff --git a/src/net/sourceforge/plantuml/graphic/EmbededSystemLine.java b/src/net/sourceforge/plantuml/graphic/EmbededSystemLine.java index 4a6b0b842..f2dae4158 100644 --- a/src/net/sourceforge/plantuml/graphic/EmbededSystemLine.java +++ b/src/net/sourceforge/plantuml/graphic/EmbededSystemLine.java @@ -51,6 +51,7 @@ import net.sourceforge.plantuml.EmbededDiagram; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; import net.sourceforge.plantuml.ugraphic.UShape; @@ -104,7 +105,7 @@ class EmbededSystemLine extends AbstractTextBlock implements Line { } private Diagram getSystem() throws IOException, InterruptedException { - final BlockUml blockUml = new BlockUml(lines2, 0); + final BlockUml blockUml = new BlockUml(lines2, 0, Defines.createEmpty()); return blockUml.getDiagram(); } diff --git a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java index 7b84e71c1..88cb722f3 100644 --- a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java +++ b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java @@ -175,7 +175,7 @@ public class FontConfiguration { } public FontConfiguration changeSize(float size) { - return new FontConfiguration(styles, motherFont, motherColor, currentFont.deriveSize(size), currentColor, + return new FontConfiguration(styles, motherFont, motherColor, currentFont.withSize(size), currentColor, extendedColor, fontPosition, svgAttributes, hyperlink, hyperlinkColor, useUnderlineForHyperlink, tabSize); } diff --git a/src/net/sourceforge/plantuml/graphic/FontPosition.java b/src/net/sourceforge/plantuml/graphic/FontPosition.java index 4f80e8051..53a789d9a 100644 --- a/src/net/sourceforge/plantuml/graphic/FontPosition.java +++ b/src/net/sourceforge/plantuml/graphic/FontPosition.java @@ -58,7 +58,7 @@ public enum FontPosition { if (size < 2) { size = 2; } - return font.deriveSize((float) size); + return font.withSize((float) size); } public String getHtmlTag() { diff --git a/src/net/sourceforge/plantuml/graphic/FontStyle.java b/src/net/sourceforge/plantuml/graphic/FontStyle.java index be6b653a9..0b051f0c5 100644 --- a/src/net/sourceforge/plantuml/graphic/FontStyle.java +++ b/src/net/sourceforge/plantuml/graphic/FontStyle.java @@ -47,13 +47,13 @@ public enum FontStyle { public UFont mutateFont(UFont font) { if (this == PLAIN) { - return font.deriveStyle(Font.PLAIN); + return font.withStyle(Font.PLAIN); } if (this == ITALIC) { - return font.deriveStyle(font.getStyle() | Font.ITALIC); + return font.withStyle(font.getStyle() | Font.ITALIC); } if (this == BOLD) { - return font.deriveStyle(font.getStyle() | Font.BOLD); + return font.withStyle(font.getStyle() | Font.BOLD); } return font; } diff --git a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java index defd30195..bca81dca9 100644 --- a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java +++ b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.svek.IEntityImage; +import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -74,11 +75,11 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { public static IEntityImage createForError(List strings, boolean useRed) { if (useRed) { - return new GraphicStrings(strings, new UFont("SansSerif", Font.BOLD, 14), HtmlColorUtils.BLACK, + return new GraphicStrings(strings, UFont.sansSerif(14).bold(), HtmlColorUtils.BLACK, HtmlColorUtils.RED_LIGHT, null, null); } - return new GraphicStrings(strings, new UFont("SansSerif", Font.BOLD, 14), HtmlColorSet.getInstance() - .getColorIfValid("#33FF02"), HtmlColorUtils.BLACK, null, null); + return new GraphicStrings(strings, UFont.sansSerif(14).bold(), HtmlColorSet.getInstance().getColorIfValid( + "#33FF02"), HtmlColorUtils.BLACK, null, null); } public static TextBlockBackcolored createGreenOnBlackMonospaced(List strings) { @@ -99,11 +100,11 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { } private static UFont sansSerif12() { - return new UFont("SansSerif", Font.PLAIN, 12); + return UFont.sansSerif(12); } private static UFont monospaced14() { - return new UFont("Monospaced", Font.PLAIN, 14); + return UFont.monospaced(14); } private GraphicStrings(List strings, UFont font, HtmlColor maincolor, HtmlColor background, @@ -169,8 +170,8 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { return background; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public boolean isHidden() { diff --git a/src/net/sourceforge/plantuml/graphic/InnerStrategy.java b/src/net/sourceforge/plantuml/graphic/InnerStrategy.java new file mode 100644 index 000000000..28d5c7b43 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/InnerStrategy.java @@ -0,0 +1,51 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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; + +public enum InnerStrategy { + STRICT, LAZZY; + + public boolean check(final String data, String candidate) { + if (this == STRICT) { + return data.startsWith(candidate); + } + if (this == LAZZY) { + return data.contains(candidate); + } + throw new IllegalStateException(); + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index fb8b7dd7c..6488a2a07 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -227,7 +227,9 @@ public class QuoteUtils { "Fv ba oevpbynvg cyhf fbhirag, ba nhenvg zbvaf yn grgr nhk orgvfrf.", "Wr invf yhv snver har beqbaanapr, rg har frirer...", "Znvf vy pbaanvg cnf Enbhy, pr zrp! vy in nibve ha erirvy cravoyr.", - "W'nv ibhyh rger qvcybzngr n pnhfr qr ibhf gbhf, rivgre dhr yr fnat pbhyr."); + "W'nv ibhyh rger qvcybzngr n pnhfr qr ibhf gbhf, rivgre dhr yr fnat pbhyr.", + "Vtabenapr oevatf punbf, abg xabjyrqtr.", "Yrneavat vf nyjnlf n cnvashy cebprff.", + "V'z fbeel, ner lbh sebz gur cnfg ?", "Unir lbh gevrq gheavat vg bss naq ba ntnva ?"); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlock.java b/src/net/sourceforge/plantuml/graphic/TextBlock.java index 893aa570e..2ff628f6e 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlock.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlock.java @@ -44,7 +44,7 @@ public interface TextBlock extends UDrawable, UShape { public Dimension2D calculateDimension(StringBounder stringBounder); - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy); } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockLineBefore.java b/src/net/sourceforge/plantuml/graphic/TextBlockLineBefore.java index bb41d5564..8e84710fe 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockLineBefore.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockLineBefore.java @@ -87,8 +87,8 @@ public class TextBlockLineBefore extends AbstractTextBlock implements TextBlock, } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - return textBlock.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return textBlock.getInnerPosition(member, stringBounder, strategy); } public Ports getPorts(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockMarged.java b/src/net/sourceforge/plantuml/graphic/TextBlockMarged.java index 17c038418..19d3d73a3 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockMarged.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockMarged.java @@ -71,8 +71,8 @@ class TextBlockMarged extends AbstractTextBlock implements TextBlock, WithPorts } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - final Rectangle2D parent = textBlock.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + final Rectangle2D parent = textBlock.getInnerPosition(member, stringBounder, strategy); if (parent == null) { return null; } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockTitle.java b/src/net/sourceforge/plantuml/graphic/TextBlockTitle.java index f9c5e7500..0c449db1f 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockTitle.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockTitle.java @@ -71,7 +71,7 @@ public class TextBlockTitle implements TextBlock { return new Dimension2DDouble(width, height); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java index 372213f90..a6684346e 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -165,13 +165,14 @@ public class TextBlockUtils { return bloc.calculateDimension(stringBounder); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - if (display.startsWith(member)) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + if (strategy.check(display, member)) { final Dimension2D dim = calculateDimension(stringBounder); return new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight()); } return null; } + }; } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockVertical2.java b/src/net/sourceforge/plantuml/graphic/TextBlockVertical2.java index 9f5482954..ba6fd8ca3 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockVertical2.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockVertical2.java @@ -121,11 +121,11 @@ public class TextBlockVertical2 extends AbstractTextBlock implements TextBlock, } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { double y = 0; for (TextBlock block : blocks) { final Dimension2D dimb = block.calculateDimension(stringBounder); - final Rectangle2D result = block.getInnerPosition(member, stringBounder); + final Rectangle2D result = block.getInnerPosition(member, stringBounder, strategy); if (result != null) { return new UTranslate(0, y).apply(result); } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockWidthAdapter.java b/src/net/sourceforge/plantuml/graphic/TextBlockWidthAdapter.java index 2af9734e4..e5d56d6f8 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockWidthAdapter.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockWidthAdapter.java @@ -39,26 +39,26 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ugraphic.UGraphic; -public class TextBlockWidthAdapter extends AbstractTextBlock implements TextBlock { +public class TextBlockWidthAdapter implements TextBlockWidth { - private final TextBlockWidth textBlockWidth; + private final TextBlock textBlock; private final double width; - // public final void setWidth(double width) { - // this.width = width; - // } - - public TextBlockWidthAdapter(TextBlockWidth textBlockWidth, double widthToUse) { - this.textBlockWidth = textBlockWidth; + public TextBlockWidthAdapter(TextBlock textBlock, double widthToUse) { + this.textBlock = textBlock; this.width = widthToUse; } public void drawU(UGraphic ug) { - textBlockWidth.asTextBlock(width).drawU(ug); + textBlock.drawU(ug); } public Dimension2D calculateDimension(StringBounder stringBounder) { - return textBlockWidth.calculateDimension(stringBounder); + return textBlock.calculateDimension(stringBounder); + } + + public TextBlock asTextBlock(double widthToUse) { + return textBlock; } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java b/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java index de474c097..cf201594b 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java @@ -69,8 +69,8 @@ public class TextBlockWithUrl implements TextBlock { return block.calculateDimension(stringBounder); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - return block.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return block.getInnerPosition(member, stringBounder, strategy); } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TileImageSvg.java b/src/net/sourceforge/plantuml/graphic/TileImageSvg.java index 0b5f12cfb..6cc8ebfa1 100644 --- a/src/net/sourceforge/plantuml/graphic/TileImageSvg.java +++ b/src/net/sourceforge/plantuml/graphic/TileImageSvg.java @@ -41,6 +41,7 @@ import java.io.IOException; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImageSvg; @@ -53,7 +54,7 @@ public class TileImageSvg extends AbstractTextBlock implements TextBlock { } private UImageSvg createSvg(File svgFile) throws IOException { - return new UImageSvg(FileUtils.readSvg(svgFile)); + return new UImageSvg(new SvgString(FileUtils.readSvg(svgFile), 1)); } public Dimension2D calculateDimension(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java b/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java index 2f2f37224..eefeba165 100644 --- a/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java +++ b/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java @@ -84,7 +84,7 @@ public final class CucaDiagramHtmlMaker { if (hasSome(type)) { pw.println("

" + type.toHtml() + "

"); for (final IEntity ent : diagram.getLeafsvalues()) { - if (ent.getEntityType() != type) { + if (ent.getLeafType() != type) { continue; } export(ent); @@ -106,7 +106,7 @@ public final class CucaDiagramHtmlMaker { private boolean hasSome(final LeafType type) { for (IEntity ent : diagram.getLeafsvalues()) { - if (ent.getEntityType() == type) { + if (ent.getLeafType() == type) { return true; } } @@ -118,7 +118,7 @@ public final class CucaDiagramHtmlMaker { final PrintWriter pw = new PrintWriter(f); pw.println(""); pw.println("" + StringUtils.unicodeForHtml(entity.getCode().getFullName()) + ""); - pw.println("

" + entity.getEntityType().toHtml() + "

"); + pw.println("

" + entity.getLeafType().toHtml() + "

"); for (CharSequence s : entity.getDisplay()) { pw.println(StringUtils.unicodeForHtml(s.toString())); pw.println("
"); @@ -209,8 +209,8 @@ public final class CucaDiagramHtmlMaker { if (link.contains(ent) == false) { continue; } - if (link.getEntity1().getEntityType() == LeafType.NOTE - || link.getEntity2().getEntityType() == LeafType.NOTE) { + if (link.getEntity1().getLeafType() == LeafType.NOTE + || link.getEntity2().getLeafType() == LeafType.NOTE) { result.add(link.getOther(ent)); } } @@ -223,8 +223,8 @@ public final class CucaDiagramHtmlMaker { if (link.contains(ent) == false) { continue; } - if (link.getEntity1().getEntityType() == LeafType.NOTE - || link.getEntity2().getEntityType() == LeafType.NOTE) { + if (link.getEntity1().getLeafType() == LeafType.NOTE + || link.getEntity2().getLeafType() == LeafType.NOTE) { continue; } result.add(link); diff --git a/src/net/sourceforge/plantuml/html/LinkHtmlPrinter.java b/src/net/sourceforge/plantuml/html/LinkHtmlPrinter.java index f4b20ab89..7b52c6b59 100644 --- a/src/net/sourceforge/plantuml/html/LinkHtmlPrinter.java +++ b/src/net/sourceforge/plantuml/html/LinkHtmlPrinter.java @@ -176,7 +176,7 @@ public final class LinkHtmlPrinter { } static String urlOf(IEntity ent) { - if (ent.getEntityType() == LeafType.NOTE) { + if (ent.getLeafType() == LeafType.NOTE) { throw new IllegalArgumentException(); } if (ent.getCode().getFullName().matches("[-\\w_ .]+")) { diff --git a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java index b32907642..5cbfdf524 100644 --- a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java +++ b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java @@ -310,7 +310,7 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker { final IEntityImage image = printEntityInternal(ent); final Dimension2D dim = image.calculateDimension(stringBounder); final Shape shape = new Shape(image, image.getShapeType(), dim.getWidth(), dim.getHeight(), - dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(), ent.getEntityPosition()); + dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(stringBounder), ent.getEntityPosition()); dotStringFactory.addShape(shape); getBibliotekon().putShape(ent, shape); } @@ -568,7 +568,7 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker { final IEntityImage image = printEntityInternal(ent); final Dimension2D dim = image.calculateDimension(stringBounder); final Shape shape = new Shape(image, image.getShapeType(), dim.getWidth(), dim.getHeight(), - dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(), ent.getEntityPosition()); + dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(stringBounder), ent.getEntityPosition()); // dotStringFactory.addShape(shape); getBibliotekon().putShape(ent, shape); } diff --git a/src/net/sourceforge/plantuml/math/AsciiMath.java b/src/net/sourceforge/plantuml/math/AsciiMath.java index 833d79fee..52754f792 100644 --- a/src/net/sourceforge/plantuml/math/AsciiMath.java +++ b/src/net/sourceforge/plantuml/math/AsciiMath.java @@ -48,6 +48,8 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import net.sourceforge.plantuml.SvgString; + public class AsciiMath implements ScientificEquation { private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/"; @@ -87,10 +89,10 @@ public class AsciiMath implements ScientificEquation { return builder.getDimension(); } - public String getSvg(Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, + public SvgString getSvg(double scale, Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException, IOException { - return builder.getSvg(foregroundColor, backgroundColor); + return builder.getSvg(scale, foregroundColor, backgroundColor); } public BufferedImage getImage(double scale, Color foregroundColor, Color backgroundColor) diff --git a/src/net/sourceforge/plantuml/math/ConverterSvg.java b/src/net/sourceforge/plantuml/math/ConverterSvg.java index 055189232..28bb366ae 100644 --- a/src/net/sourceforge/plantuml/math/ConverterSvg.java +++ b/src/net/sourceforge/plantuml/math/ConverterSvg.java @@ -78,7 +78,7 @@ public class ConverterSvg { private Dimension dimension; - public String getSvg(boolean fontAsShapes, Color backgroundColor) throws ClassNotFoundException, + public String getSvg(double scale, boolean fontAsShapes, Color backgroundColor) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException, IOException { // DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); diff --git a/src/net/sourceforge/plantuml/math/LatexBuilder.java b/src/net/sourceforge/plantuml/math/LatexBuilder.java index 6c186bda0..a9d139755 100644 --- a/src/net/sourceforge/plantuml/math/LatexBuilder.java +++ b/src/net/sourceforge/plantuml/math/LatexBuilder.java @@ -44,6 +44,8 @@ import java.lang.reflect.InvocationTargetException; import javax.swing.Icon; +import net.sourceforge.plantuml.SvgString; + public class LatexBuilder implements ScientificEquation { private final String tex; @@ -64,14 +66,14 @@ public class LatexBuilder implements ScientificEquation { return new TeXIconBuilder(tex, foregroundColor).getIcon(); } - public String getSvg(Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, + public SvgString getSvg(double scale, Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException, IOException { final Icon icon = buildIcon(foregroundColor); final ConverterSvg converterSvg = new ConverterSvg(icon); - final String svg = converterSvg.getSvg(true, backgroundColor); + final String svg = converterSvg.getSvg(scale, true, backgroundColor); dimension = converterSvg.getDimension(); - return svg; + return new SvgString(svg, scale); } public BufferedImage getImage(double scale, Color foregroundColor, Color backgroundColor) diff --git a/src/net/sourceforge/plantuml/math/ScientificEquation.java b/src/net/sourceforge/plantuml/math/ScientificEquation.java index cf95261ef..eb1ab3034 100644 --- a/src/net/sourceforge/plantuml/math/ScientificEquation.java +++ b/src/net/sourceforge/plantuml/math/ScientificEquation.java @@ -41,17 +41,19 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import net.sourceforge.plantuml.SvgString; + public interface ScientificEquation { public Dimension2D getDimension(); - public String getSvg(Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, + public SvgString getSvg(double scale, Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException, IOException; - public BufferedImage getImage(double scale, Color foregroundColor, Color backgroundColor) throws ClassNotFoundException, - NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException; + public BufferedImage getImage(double scale, Color foregroundColor, Color backgroundColor) + throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException; public String getSource(); diff --git a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java index 318fdd425..72c243177 100644 --- a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java +++ b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java @@ -48,6 +48,7 @@ import javax.imageio.ImageIO; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.graphic.GraphicStrings; @@ -87,10 +88,10 @@ public class ScientificEquationSafe { private ImageData dimSvg; - public String getSvg(Color foregroundColor, Color backgroundColor) { + public SvgString getSvg(double scale, Color foregroundColor, Color backgroundColor) { try { - final String svg = equation.getSvg(foregroundColor, backgroundColor); + final SvgString svg = equation.getSvg(scale, foregroundColor, backgroundColor); dimSvg = new ImageDataSimple(equation.getDimension()); return svg; } catch (Exception e) { @@ -102,7 +103,7 @@ public class ScientificEquationSafe { } catch (IOException e1) { return null; } - return new String(baos.toByteArray()); + return new SvgString(new String(baos.toByteArray()), scale); } } @@ -138,15 +139,15 @@ public class ScientificEquationSafe { return imageBuilder; } - public ImageData export(OutputStream os, FileFormatOption fileFormat, float scale, Color foregroundColor, Color backgroundColor) - throws IOException { + public ImageData export(OutputStream os, FileFormatOption fileFormat, float scale, Color foregroundColor, + Color backgroundColor) throws IOException { if (fileFormat.getFileFormat() == FileFormat.PNG) { final BufferedImage image = getImage(scale, foregroundColor, backgroundColor); ImageIO.write(image, "png", os); return new ImageDataSimple(image.getWidth(), image.getHeight()); } if (fileFormat.getFileFormat() == FileFormat.SVG) { - os.write(getSvg(foregroundColor, backgroundColor).getBytes()); + os.write(getSvg(1, foregroundColor, backgroundColor).getSvg().getBytes()); return dimSvg; } return null; diff --git a/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java index e8a5f0eba..b179bf7c9 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java +++ b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java @@ -78,7 +78,7 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram } public int getNbOfHozizontalLollipop(IEntity entity) { - if (entity.getEntityType() == LeafType.LOLLIPOP) { + if (entity.getLeafType() == LeafType.LOLLIPOP) { throw new IllegalArgumentException(); } int result = 0; @@ -91,14 +91,14 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram return result; } - private final List assocations = new ArrayList(); + private final List associations = new ArrayList(); public boolean associationClass(int mode, Code clName1, Code clName2, IEntity associed, LinkType linkType, Display label) { final IEntity entity1 = getOrCreateLeaf(clName1, null, null); final IEntity entity2 = getOrCreateLeaf(clName2, null, null); final List same = new ArrayList(); - for (Association existing : assocations) { + for (Association existing : associations) { if (existing.sameCouple(entity1, entity2)) { same.add(existing); } @@ -109,14 +109,14 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram final Association association = new Association(mode, entity1, entity2, associed); association.createNew(mode, linkType, label); - this.assocations.add(association); + this.associations.add(association); return true; } assert same.size() == 1; final Association association = same.get(0).createSecondAssociation(mode, associed, label); association.createInSecond(linkType, label); - this.assocations.add(association); + this.associations.add(association); return true; } @@ -218,7 +218,7 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram // null, 2); addLink(entity1ToPoint); addLink(pointToEntity2); - if (other.pointToAssocied.getEntity1().getEntityType() == LeafType.POINT_FOR_ASSOCIATION) { + if (other.pointToAssocied.getEntity1().getLeafType() == LeafType.POINT_FOR_ASSOCIATION) { removeLink(other.pointToAssocied); other.pointToAssocied = other.pointToAssocied.getInv(); addLink(other.pointToAssocied); diff --git a/src/net/sourceforge/plantuml/openiconic/OpenIcon.java b/src/net/sourceforge/plantuml/openiconic/OpenIcon.java index 2fc5f9c90..fa57b069d 100644 --- a/src/net/sourceforge/plantuml/openiconic/OpenIcon.java +++ b/src/net/sourceforge/plantuml/openiconic/OpenIcon.java @@ -61,7 +61,7 @@ public class OpenIcon { private final String id; public static OpenIcon retrieve(String name) { - final InputStream is = getRessource(name); + final InputStream is = getResource(name); if (is == null) { return null; } @@ -74,10 +74,10 @@ public class OpenIcon { } OpenIcon(String name) throws IOException { - this(getRessource(name), name); + this(getResource(name), name); } - private static InputStream getRessource(String name) { + private static InputStream getResource(String name) { // System.err.println("OPENING " + name); return DummyIcon.class.getResourceAsStream(name + ".svg"); } diff --git a/src/net/sourceforge/plantuml/oregon/MagicTable.java b/src/net/sourceforge/plantuml/oregon/MagicTable.java index 8f74a4ef5..6a5998170 100644 --- a/src/net/sourceforge/plantuml/oregon/MagicTable.java +++ b/src/net/sourceforge/plantuml/oregon/MagicTable.java @@ -50,61 +50,61 @@ public class MagicTable { private final Oc number[] = new Oc[10000]; - private static ArrayList neighboors; + private static ArrayList neighbours; static { - neighboors = new ArrayList(); + neighbours = new ArrayList(); for (int i = 0; i < 10000; i++) { - neighboors.add(null); + neighbours.add(null); } } - public static int[] getNeighboors(final int nb) { - if (neighboors.get(nb) == null) { - neighboors.set(nb, getNeighboorsSlow(nb)); + public static int[] getNeighbours(final int nb) { + if (neighbours.get(nb) == null) { + neighbours.set(nb, getNeighboursSlow(nb)); } - return neighboors.get(nb); + return neighbours.get(nb); } - public static int[] getNeighboorsSlow(final int nb) { + public static int[] getNeighboursSlow(final int nb) { final int result[] = new int[36]; final int v1 = nb % 10; int root = nb - v1; int cpt = 0; for (int i = 0; i < 10; i++) { - final int candidat = root + i; - if (candidat == nb) { + final int candidate = root + i; + if (candidate == nb) { continue; } - result[cpt++] = candidat; + result[cpt++] = candidate; } final int v2 = (nb / 10) % 10; root = nb - v2 * 10; for (int i = 0; i < 10; i++) { - final int candidat = root + i * 10; - if (candidat == nb) { + final int candidate = root + i * 10; + if (candidate == nb) { continue; } - result[cpt++] = candidat; + result[cpt++] = candidate; } final int v3 = (nb / 100) % 10; root = nb - v3 * 100; for (int i = 0; i < 10; i++) { - final int candidat = root + i * 100; - if (candidat == nb) { + final int candidate = root + i * 100; + if (candidate == nb) { continue; } - result[cpt++] = candidat; + result[cpt++] = candidate; } final int v4 = nb / 1000; root = nb - v4 * 1000; for (int i = 0; i < 10; i++) { - final int candidat = root + i * 1000; - if (candidat == nb) { + final int candidate = root + i * 1000; + if (candidate == nb) { continue; } - result[cpt++] = candidat; + result[cpt++] = candidate; } return result; } @@ -133,7 +133,7 @@ public class MagicTable { if (number[nb] != null) { return false; } - for (int near : getNeighboors(nb)) { + for (int near : getNeighbours(nb)) { if (number[near] != null) { return false; } @@ -146,7 +146,7 @@ public class MagicTable { throw new IllegalArgumentException(); } number[nb] = Oc.USED; - for (int near : getNeighboors(nb)) { + for (int near : getNeighbours(nb)) { number[near] = Oc.NEAR; } } @@ -175,11 +175,11 @@ public class MagicTable { public static int size(Random rnd, MagicTable mt) { int i = 0; while (true) { - final int candidat = mt.getRandomFree(rnd); - if (candidat == -1) { + final int candidate = mt.getRandomFree(rnd); + if (candidate == -1) { break; } - mt.burnNumber(candidat); + mt.burnNumber(candidate); i++; } return i; diff --git a/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java b/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java index 8ad673cf6..1f19cb068 100644 --- a/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java +++ b/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java @@ -190,7 +190,7 @@ public class OregonBasicGame implements BasicGame { if (c < 11 + 2 * rnd()) { c1 = 1; } - printb("Cold weather... Brrrrrrr! ... You " + (c1 == 1 ? "dont't " : "") + printb("Cold weather... Brrrrrrr! ... You " + (c1 == 1 ? "don't " : "") + "have enough clothing to keep warm."); if (c1 == 1) { dealWithIllness2880(j); @@ -811,19 +811,19 @@ public class OregonBasicGame implements BasicGame { c = skb.inputInt(screen); if (c <= 24) { print("Your family is going to be mighty cold in."); - print("the montains."); + print("the mountains."); print("Better spend a bit more."); continue; } if (a + f + b + c > 345) { - print("That leaves nothing for medecine."); + print("That leaves nothing for medicine."); continue; } break; } while (true); do { print(); - screen.print("How much for medecine, bandage, repair parts, etc. ?"); + screen.print("How much for medicine, bandage, repair parts, etc. ?"); r = skb.inputInt(screen); if (r <= 5) { print("That's not at all wise."); diff --git a/src/net/sourceforge/plantuml/oregon/SecureCoder.java b/src/net/sourceforge/plantuml/oregon/SecureCoder.java index a2916ffa6..378388bca 100644 --- a/src/net/sourceforge/plantuml/oregon/SecureCoder.java +++ b/src/net/sourceforge/plantuml/oregon/SecureCoder.java @@ -52,7 +52,7 @@ public class SecureCoder { for (int i = 0; i < m.length; i++) { final int enc = m[i]; dec[enc] = i; - for (int n : MagicTable.getNeighboors(enc)) { + for (int n : MagicTable.getNeighbours(enc)) { if (dec[n] != -1) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/postit/Area.java b/src/net/sourceforge/plantuml/postit/Area.java index a144b8e55..644e4c1d2 100644 --- a/src/net/sourceforge/plantuml/postit/Area.java +++ b/src/net/sourceforge/plantuml/postit/Area.java @@ -50,7 +50,7 @@ public class Area implements Elastic { private final String title; private final char id; - private Dimension2D minimunDimension; + private Dimension2D minimumDimension; private final List postIts = new ArrayList(); @@ -67,12 +67,12 @@ public class Area implements Elastic { return title; } - public Dimension2D getMinimunDimension() { - return minimunDimension; + public Dimension2D getMinimumDimension() { + return minimumDimension; } - public void setMinimunDimension(Dimension2D minimunDimension) { - this.minimunDimension = minimunDimension; + public void setMinimunDimension(Dimension2D minimumDimension) { + this.minimumDimension = minimumDimension; } public Dimension2D getDimension() { diff --git a/src/net/sourceforge/plantuml/postit/PostIt.java b/src/net/sourceforge/plantuml/postit/PostIt.java index bda1f3803..19e700162 100644 --- a/src/net/sourceforge/plantuml/postit/PostIt.java +++ b/src/net/sourceforge/plantuml/postit/PostIt.java @@ -61,7 +61,7 @@ public class PostIt { private final String id; private final Display text; - private Dimension2D minimunDimension; + private Dimension2D minimumDimension; public PostIt(String id, Display text) { this.id = id; @@ -76,23 +76,23 @@ public class PostIt { return text; } - public Dimension2D getMinimunDimension() { - return minimunDimension; + public Dimension2D getMinimumDimension() { + return minimumDimension; } - public void setMinimunDimension(Dimension2D minimunDimension) { - this.minimunDimension = minimunDimension; + public void setMinimumDimension(Dimension2D minimumDimension) { + this.minimumDimension = minimumDimension; } public Dimension2D getDimension(StringBounder stringBounder) { double width = getComponent().getPreferredWidth(stringBounder); double height = getComponent().getPreferredHeight(stringBounder); - if (minimunDimension != null && width < minimunDimension.getWidth()) { - width = minimunDimension.getWidth(); + if (minimumDimension != null && width < minimumDimension.getWidth()) { + width = minimumDimension.getWidth(); } - if (minimunDimension != null && height < minimunDimension.getHeight()) { - height = minimunDimension.getHeight(); + if (minimumDimension != null && height < minimumDimension.getHeight()) { + height = minimumDimension.getHeight(); } return new Dimension2DDouble(width, height); diff --git a/src/net/sourceforge/plantuml/postit/PostItDiagram.java b/src/net/sourceforge/plantuml/postit/PostItDiagram.java index 782ad03d1..bf90b984c 100644 --- a/src/net/sourceforge/plantuml/postit/PostItDiagram.java +++ b/src/net/sourceforge/plantuml/postit/PostItDiagram.java @@ -80,7 +80,7 @@ public class PostItDiagram extends UmlDiagram { PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, this.getDpi(fileFormatOption)); } else if (ug instanceof UGraphicSvg) { final UGraphicSvg svg = (UGraphicSvg) ug; - svg.createXml(os); + svg.createXml(os, fileFormatOption.isWithMetadata() ? getMetadata() : null); } else if (ug instanceof UGraphicEps) { final UGraphicEps eps = (UGraphicEps) ug; os.write(eps.getEPSCode().getBytes()); diff --git a/src/net/sourceforge/plantuml/preproc/Defines.java b/src/net/sourceforge/plantuml/preproc/Defines.java index 3c631361a..a3d0b4686 100644 --- a/src/net/sourceforge/plantuml/preproc/Defines.java +++ b/src/net/sourceforge/plantuml/preproc/Defines.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.preproc; +import java.io.File; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; @@ -45,12 +46,49 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.api.ApiWarning; public class Defines implements Truth { + private final Map environment = new LinkedHashMap(); private final Map values = new LinkedHashMap(); private final Map savedState = new LinkedHashMap(); + @Deprecated + @ApiWarning(willBeRemoved = "in next major release") + public Defines() { + } + + @Override + public String toString() { + return values.keySet().toString(); + } + + public static Defines createEmpty() { + return new Defines(); + } + + public void importFrom(Defines other) { + this.environment.putAll(other.environment); + this.values.putAll(other.values); + } + + public Defines cloneMe() { + final Defines result = new Defines(); + result.importFrom(this); + return result; + } + + public static Defines createWithFileName(File file) { + if (file == null) { + throw new IllegalArgumentException(); + } + final Defines result = createEmpty(); + result.environment.put("filename", file.getName()); + result.environment.put("dirpath", file.getAbsoluteFile().getParentFile().getAbsolutePath().replace('\\', '/')); + return result; + } + public void define(String name, List value) { values.put(name, new Define(name, value)); } @@ -80,6 +118,7 @@ public class Defines implements Truth { public List applyDefines(String line) { line = manageDate(line); + line = manageEnvironment(line); for (Map.Entry ent : values.entrySet()) { final Define def = ent.getValue(); line = def.apply(line); @@ -87,6 +126,14 @@ public class Defines implements Truth { return Arrays.asList(line.split("\n")); } + private String manageEnvironment(String line) { + for (Map.Entry ent : environment.entrySet()) { + final String key = Pattern.quote("%" + ent.getKey() + "%"); + line = line.replaceAll(key, ent.getValue()); + } + return line; + } + private static final String DATE = "(?i)%date(\\[(.+?)\\])?%"; private final static Pattern datePattern = Pattern.compile(DATE); diff --git a/src/net/sourceforge/plantuml/preproc/Preprocessor.java b/src/net/sourceforge/plantuml/preproc/Preprocessor.java index 04d718ec8..563ed38d5 100644 --- a/src/net/sourceforge/plantuml/preproc/Preprocessor.java +++ b/src/net/sourceforge/plantuml/preproc/Preprocessor.java @@ -44,6 +44,7 @@ import java.util.Set; import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.CharSequence2Impl; +import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -65,10 +66,11 @@ public class Preprocessor implements ReadLine { private final PreprocessorInclude rawSource; private final ReadLineInsertable source; - public Preprocessor(ReadLine reader, String charset, Defines defines, File newCurrentDir) { + public Preprocessor(ReadLine reader, String charset, Defines defines, File newCurrentDir, + DefinitionsContainer definitionsContainer) { this.defines = defines; this.defines.saveState(); - this.rawSource = new PreprocessorInclude(reader, defines, charset, newCurrentDir); + this.rawSource = new PreprocessorInclude(reader, defines, charset, newCurrentDir, definitionsContainer); this.source = new ReadLineInsertable(new IfManager(rawSource, defines)); } diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java index f2c0266d0..986c1b7cc 100644 --- a/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java +++ b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java @@ -46,11 +46,13 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; @@ -60,8 +62,9 @@ import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; import net.sourceforge.plantuml.utils.StartUtils; -class PreprocessorInclude implements ReadLine { +public class PreprocessorInclude implements ReadLine { + private static final Pattern2 includeDefPattern = MyPattern.cmpile("^[%s]*!includedef[%s]+[%g]?([^%g]+)[%g]?$"); private static final Pattern2 includePattern = MyPattern.cmpile("^[%s]*!include[%s]+[%g]?([^%g]+)[%g]?$"); private static final Pattern2 includeManyPattern = MyPattern.cmpile("^[%s]*!include_many[%s]+[%g]?([^%g]+)[%g]?$"); private static final Pattern2 includeURLPattern = MyPattern.cmpile("^[%s]*!includeurl[%s]+[%g]?([^%g]+)[%g]?$"); @@ -69,6 +72,7 @@ class PreprocessorInclude implements ReadLine { private final ReadLine reader2; private final String charset; private final Defines defines; + private final DefinitionsContainer definitionsContainer; private int numLine = 0; @@ -78,8 +82,10 @@ class PreprocessorInclude implements ReadLine { private final Set filesUsedCurrent; private final Set filesUsedGlobal; - public PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir) { - this(reader, defines, charset, newCurrentDir, new HashSet(), new HashSet()); + public PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir, + DefinitionsContainer definitionsContainer) { + this(reader, defines, charset, newCurrentDir, new HashSet(), new HashSet(), + definitionsContainer); } public Set getFilesUsedGlobal() { @@ -87,10 +93,12 @@ class PreprocessorInclude implements ReadLine { } private PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir, - Set filesUsedCurrent, Set filesUsedGlobal) { + Set filesUsedCurrent, Set filesUsedGlobal, + DefinitionsContainer definitionsContainer) { this.defines = defines; this.charset = charset; this.reader2 = reader; + this.definitionsContainer = definitionsContainer; this.filesUsedCurrent = filesUsedCurrent; this.filesUsedGlobal = filesUsedGlobal; if (newCurrentDir == null) { @@ -141,6 +149,10 @@ class PreprocessorInclude implements ReadLine { if (m2.find()) { return manageFileInclude(s, m2, true); } + final Matcher2 m3 = includeDefPattern.matcher(s); + if (m3.find()) { + return manageDefinitionInclude(s, m3); + } } final Matcher2 mUrl = includeURLPattern.matcher(s); if (s.getPreprocessorError() == null && mUrl.find()) { @@ -162,13 +174,21 @@ class PreprocessorInclude implements ReadLine { try { final URL url = new URL(urlString); included = new PreprocessorInclude(getReaderInclude(s, url, suf), defines, charset, null, filesUsedCurrent, - filesUsedGlobal); + filesUsedGlobal, definitionsContainer); } catch (MalformedURLException e) { return s.withErrorPreprocessor("Cannot include url " + urlString); } return this.readLine(); } + private CharSequence2 manageDefinitionInclude(CharSequence2 s, Matcher2 matcher) throws IOException { + final String definitionName = matcher.group(1); + final List definition = definitionsContainer.getDefinition(definitionName); + included = new PreprocessorInclude(new ReadLineList(definition, s.getLocation()), defines, charset, null, + filesUsedCurrent, filesUsedGlobal, definitionsContainer); + return this.readLine(); + } + private CharSequence2 manageFileInclude(CharSequence2 s, Matcher2 matcher, boolean allowMany) throws IOException { String fileName = matcher.group(1); fileName = defines.applyDefines(fileName).get(0); @@ -189,7 +209,7 @@ class PreprocessorInclude implements ReadLine { filesUsedCurrent.add(f2); filesUsedGlobal.add(f2); included = new PreprocessorInclude(getReaderInclude(s, f, suf), defines, charset, f.getParentFile(), - filesUsedCurrent, filesUsedGlobal); + filesUsedCurrent, filesUsedGlobal, definitionsContainer); } return this.readLine(); } @@ -211,7 +231,7 @@ class PreprocessorInclude implements ReadLine { return s; } - private static String getenv(String var) { + public static String getenv(String var) { final String env = System.getProperty(var); if (StringUtils.isNotEmpty(env)) { return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(env); diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineList.java b/src/net/sourceforge/plantuml/preproc/ReadLineList.java new file mode 100644 index 000000000..d0d3cb06b --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/ReadLineList.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, 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.preproc; + +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.CharSequence2Impl; +import net.sourceforge.plantuml.LineLocation; + +public class ReadLineList implements ReadLine { + + private final Iterator iterator; + private final LineLocation location; + + public ReadLineList(List definition, LineLocation location) { + this.iterator = definition.iterator(); + this.location = location; + } + + public void close() { + } + + public CharSequence2 readLine() { + if (iterator.hasNext() == false) { + return null; + } + return new CharSequence2Impl(iterator.next(), location); + } + +} diff --git a/src/net/sourceforge/plantuml/printskin/PrintSkin.java b/src/net/sourceforge/plantuml/printskin/PrintSkin.java index 4866a0d7d..ba28671ee 100644 --- a/src/net/sourceforge/plantuml/printskin/PrintSkin.java +++ b/src/net/sourceforge/plantuml/printskin/PrintSkin.java @@ -76,7 +76,7 @@ import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; class PrintSkin extends AbstractPSystem { - private static final UFont FONT1 = new UFont("SansSerif", Font.PLAIN, 10); + private static final UFont FONT1 = UFont.sansSerif(10); final private Skin skin; final private List toPrint; diff --git a/src/net/sourceforge/plantuml/project/PSystemProject.java b/src/net/sourceforge/plantuml/project/PSystemProject.java index 4281beb38..3fde781d0 100644 --- a/src/net/sourceforge/plantuml/project/PSystemProject.java +++ b/src/net/sourceforge/plantuml/project/PSystemProject.java @@ -82,9 +82,9 @@ public class PSystemProject extends AbstractPSystem { PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96); } else if (fileFormat == FileFormat.SVG) { final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0, - fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor()); + fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor(), fileFormatOption.getRandom()); diagram.draw(svg, 0, 0); - svg.createXml(os); + svg.createXml(os, fileFormatOption.isWithMetadata() ? getMetadata() : null); } else if (fileFormat == FileFormat.EPS) { final UGraphicEps eps = new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); diagram.draw(eps, 0, 0); diff --git a/src/net/sourceforge/plantuml/project/graphic/ItemHeader.java b/src/net/sourceforge/plantuml/project/graphic/ItemHeader.java index 1caf3bb93..e5764e0f6 100644 --- a/src/net/sourceforge/plantuml/project/graphic/ItemHeader.java +++ b/src/net/sourceforge/plantuml/project/graphic/ItemHeader.java @@ -56,7 +56,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class ItemHeader { - private final UFont font = new UFont("Serif", Font.PLAIN, 9); + private final UFont font = UFont.serif(9); private final Project project; private final FontConfiguration fontConfig = FontConfiguration.blackBlueTrue(font); diff --git a/src/net/sourceforge/plantuml/project/graphic/TimeScale.java b/src/net/sourceforge/plantuml/project/graphic/TimeScale.java index 7f8ed37e3..30a84b78f 100644 --- a/src/net/sourceforge/plantuml/project/graphic/TimeScale.java +++ b/src/net/sourceforge/plantuml/project/graphic/TimeScale.java @@ -61,7 +61,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class TimeScale { - private final UFont font = new UFont("Serif", Font.PLAIN, 9); + private final UFont font = UFont.serif(9); private final Project project; private final FontConfiguration fontConfig = FontConfiguration.blackBlueTrue(font); diff --git a/src/net/sourceforge/plantuml/project2/GanttDiagram2.java b/src/net/sourceforge/plantuml/project2/GanttDiagram2.java index a2190f53d..fc0b47e50 100644 --- a/src/net/sourceforge/plantuml/project2/GanttDiagram2.java +++ b/src/net/sourceforge/plantuml/project2/GanttDiagram2.java @@ -60,7 +60,7 @@ public class GanttDiagram2 { this.project = project; } - private final UFont font = new UFont("Serif", Font.PLAIN, 9); + private final UFont font = UFont.serif(9); private final FontConfiguration fontConfig = FontConfiguration.blackBlueTrue(font); public void draw(UGraphic ug, double x, double y) { diff --git a/src/net/sourceforge/plantuml/project2/PSystemProject2.java b/src/net/sourceforge/plantuml/project2/PSystemProject2.java index 87f6a071c..f9c12ab93 100644 --- a/src/net/sourceforge/plantuml/project2/PSystemProject2.java +++ b/src/net/sourceforge/plantuml/project2/PSystemProject2.java @@ -81,9 +81,9 @@ public class PSystemProject2 extends AbstractPSystem { PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96); } else if (fileFormat == FileFormat.SVG) { final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0, - fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor()); + fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor(), fileFormatOption.getRandom()); diagram.draw(svg, 0, 0); - svg.createXml(os); + svg.createXml(os, fileFormatOption.isWithMetadata() ? getMetadata() : null); } else if (fileFormat == FileFormat.EPS) { final UGraphicEps eps = new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); diagram.draw(eps, 0, 0); diff --git a/src/net/sourceforge/plantuml/project2/TimeHeaderDay.java b/src/net/sourceforge/plantuml/project2/TimeHeaderDay.java index 582978951..7e08908c6 100644 --- a/src/net/sourceforge/plantuml/project2/TimeHeaderDay.java +++ b/src/net/sourceforge/plantuml/project2/TimeHeaderDay.java @@ -61,7 +61,7 @@ public class TimeHeaderDay extends AbstractTextBlock implements TextBlock { private final TimeLine timeline; private final double dayWidth; - private final UFont font = new UFont("Serif", Font.PLAIN, 9); + private final UFont font = UFont.serif(9); private final FontConfiguration fontConfig = FontConfiguration.blackBlueTrue(font); public TimeHeaderDay(Day start, Day end, TimeLine timeline, double dayWidth) { diff --git a/src/net/sourceforge/plantuml/project2/TimeHeaderMonth.java b/src/net/sourceforge/plantuml/project2/TimeHeaderMonth.java index a4c80bca9..79a98aa84 100644 --- a/src/net/sourceforge/plantuml/project2/TimeHeaderMonth.java +++ b/src/net/sourceforge/plantuml/project2/TimeHeaderMonth.java @@ -61,7 +61,7 @@ public class TimeHeaderMonth extends AbstractTextBlock implements TextBlock { private final TimeLine timeline; private final double dayWidth; - private final UFont font = new UFont("Serif", Font.PLAIN, 9); + private final UFont font = UFont.serif(9); private final FontConfiguration fontConfig = FontConfiguration.blackBlueTrue(font); public TimeHeaderMonth(Day start, Day end, TimeLine timeline, double dayWidth) { diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagram.java b/src/net/sourceforge/plantuml/project3/GanttDiagram.java index 0fa589d5b..33abb5c8a 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project3/GanttDiagram.java @@ -250,7 +250,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject { } private FontConfiguration getFontConfiguration() { - final UFont font = new UFont("Serif", Font.PLAIN, 10); + final UFont font = UFont.serif(10); return new FontConfiguration(font, HtmlColorUtils.LIGHT_GRAY, HtmlColorUtils.LIGHT_GRAY, false); } diff --git a/src/net/sourceforge/plantuml/project3/TaskDraw.java b/src/net/sourceforge/plantuml/project3/TaskDraw.java index d94f61501..42463526c 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDraw.java +++ b/src/net/sourceforge/plantuml/project3/TaskDraw.java @@ -35,8 +35,6 @@ */ package net.sourceforge.plantuml.project3; -import java.awt.Font; - import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -74,7 +72,7 @@ public class TaskDraw implements UDrawable { } private FontConfiguration getFontConfiguration() { - final UFont font = new UFont("Serif", Font.PLAIN, 11); + final UFont font = UFont.serif(11); return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); } diff --git a/src/net/sourceforge/plantuml/salt/DataSourceImpl.java b/src/net/sourceforge/plantuml/salt/DataSourceImpl.java index 1c2345dc2..65d43e860 100644 --- a/src/net/sourceforge/plantuml/salt/DataSourceImpl.java +++ b/src/net/sourceforge/plantuml/salt/DataSourceImpl.java @@ -50,7 +50,7 @@ public class DataSourceImpl implements DataSource { private final List> data = new ArrayList>(); public DataSourceImpl(List data) { - final Pattern2 p = MyPattern.cmpile("\\{[-+#!*/]?"); + final Pattern2 p = MyPattern.cmpile("\\{[-+^#!*/]?"); for (String s : data) { final StringTokenizer st = new StringTokenizer(s, "|}", true); while (st.hasMoreTokens()) { diff --git a/src/net/sourceforge/plantuml/salt/SaltUtils.java b/src/net/sourceforge/plantuml/salt/SaltUtils.java index 6e207a787..144793035 100644 --- a/src/net/sourceforge/plantuml/salt/SaltUtils.java +++ b/src/net/sourceforge/plantuml/salt/SaltUtils.java @@ -67,14 +67,14 @@ public class SaltUtils { final Collection cpx = new ArrayList(); - final Dictionary dictionnary = new Dictionary(); + final Dictionary dictionary = new Dictionary(); // cpx.add(new ElementFactorySimpleFrame(source, dictionnary)); - cpx.add(new ElementFactoryPyramid(source, dictionnary)); - cpx.add(new ElementFactoryBorder(source, dictionnary)); + cpx.add(new ElementFactoryPyramid(source, dictionary)); + cpx.add(new ElementFactoryBorder(source, dictionary)); for (AbstractElementFactoryComplex f : cpx) { - addSimpleFactory(f, source, dictionnary); + addSimpleFactory(f, source, dictionary); } for (AbstractElementFactoryComplex f1 : cpx) { for (AbstractElementFactoryComplex f2 : cpx) { @@ -95,21 +95,21 @@ public class SaltUtils { } private static void addSimpleFactory(final AbstractElementFactoryComplex cpxFactory, final DataSource source, - Dictionary dictionnary) { - cpxFactory.addFactory(new ElementFactoryMenu(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryTree(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryTab(source, dictionnary)); + Dictionary dictionary) { + cpxFactory.addFactory(new ElementFactoryMenu(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryTree(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryTab(source, dictionary)); cpxFactory.addFactory(new ElementFactoryLine(source)); - cpxFactory.addFactory(new ElementFactoryTextField(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryButton(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryDroplist(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryRadioOn(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryRadioOff(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryCheckboxOn(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryCheckboxOff(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryImage(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryRetrieveFromDictonnary(source, dictionnary)); - cpxFactory.addFactory(new ElementFactoryText(source, dictionnary)); + cpxFactory.addFactory(new ElementFactoryTextField(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryButton(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryDroplist(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryRadioOn(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryRadioOff(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryCheckboxOn(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryCheckboxOff(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryImage(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryRetrieveFromDictonnary(source, dictionary)); + cpxFactory.addFactory(new ElementFactoryText(source, dictionary)); } } diff --git a/src/net/sourceforge/plantuml/salt/element/ElementPyramid.java b/src/net/sourceforge/plantuml/salt/element/ElementPyramid.java index 8e2145c14..35ca94c06 100644 --- a/src/net/sourceforge/plantuml/salt/element/ElementPyramid.java +++ b/src/net/sourceforge/plantuml/salt/element/ElementPyramid.java @@ -43,9 +43,16 @@ import java.util.List; import java.util.Map; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinSimple; +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.graphic.TextBlockUtils; import net.sourceforge.plantuml.salt.Cell; import net.sourceforge.plantuml.salt.Positionner2; +import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -53,6 +60,7 @@ public class ElementPyramid extends AbstractElement { private int rows; private int cols; + private final TextBlock title; private final TableStrategy tableStrategy; private final Map positions1; private final Map positions2 = new HashMap(); @@ -60,12 +68,20 @@ public class ElementPyramid extends AbstractElement { private double rowsStart[]; private double colsStart[]; - public ElementPyramid(Positionner2 positionner, TableStrategy tableStrategy) { + public ElementPyramid(Positionner2 positionner, TableStrategy tableStrategy, String title, + ISkinSimple spriteContainer) { positions1 = positionner.getAll(); for (Map.Entry ent : positions1.entrySet()) { positions2.put(ent.getValue(), ent.getKey()); } + if (title != null) { + final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.byDefault(10)); + this.title = Display.getWithNewlines(title).create(fontConfiguration, HorizontalAlignment.LEFT, + spriteContainer); + } else { + this.title = TextBlockUtils.empty(0, 0); + } this.rows = positionner.getNbRows(); this.cols = positionner.getNbCols(); this.tableStrategy = tableStrategy; @@ -79,17 +95,20 @@ public class ElementPyramid extends AbstractElement { public Dimension2D getPreferredDimension(StringBounder stringBounder, double x, double y) { init(stringBounder); - return new Dimension2DDouble(colsStart[colsStart.length - 1], rowsStart[rowsStart.length - 1]); + return new Dimension2DDouble(colsStart[colsStart.length - 1], rowsStart[rowsStart.length - 1] + + title.calculateDimension(stringBounder).getHeight()); } public void drawU(UGraphic ug, int zIndex, Dimension2D dimToUse) { init(ug.getStringBounder()); - final Grid grid = new Grid(rowsStart, colsStart, tableStrategy); + final double titleHeight = title.calculateDimension(ug.getStringBounder()).getHeight(); + final Grid grid = new Grid(rowsStart, colsStart, tableStrategy, title); for (Map.Entry ent : positions1.entrySet()) { final Element elt = ent.getKey(); final Cell cell = ent.getValue(); final double xcell = colsStart[cell.getMinCol()]; - final double ycell = rowsStart[cell.getMinRow()]; + final double supY = cell.getMinRow() == 0 ? titleHeight / 2 : 0; + final double ycell = rowsStart[cell.getMinRow()] + supY; final double width = colsStart[cell.getMaxCol() + 1] - colsStart[cell.getMinCol()] - 1; final double height = rowsStart[cell.getMaxRow() + 1] - rowsStart[cell.getMinRow()] - 1; grid.addCell(cell); @@ -104,7 +123,12 @@ public class ElementPyramid extends AbstractElement { if (rowsStart != null) { return; } + final double titleHeight = title.calculateDimension(stringBounder).getHeight(); rowsStart = new double[rows + 1]; + rowsStart[0] = titleHeight / 2; + for (int i = 1; i < rows + 1; i++) { + rowsStart[i] = titleHeight / 2; + } colsStart = new double[cols + 1]; final List all = new ArrayList(positions1.values()); Collections.sort(all, new LeftFirst()); @@ -116,8 +140,9 @@ public class ElementPyramid extends AbstractElement { Collections.sort(all, new TopFirst()); for (Cell cell : all) { final Element elt = positions2.get(cell); + final double supY = cell.getMinRow() == 0 ? titleHeight / 2 : 0; final Dimension2D dim = elt.getPreferredDimension(stringBounder, 0, 0); - ensureRowHeight(cell.getMinRow(), cell.getMaxRow() + 1, dim.getHeight() + 2); + ensureRowHeight(cell.getMinRow(), cell.getMaxRow() + 1, dim.getHeight() + supY + 2); } } diff --git a/src/net/sourceforge/plantuml/salt/element/Grid.java b/src/net/sourceforge/plantuml/salt/element/Grid.java index 12da75f41..63490dc46 100644 --- a/src/net/sourceforge/plantuml/salt/element/Grid.java +++ b/src/net/sourceforge/plantuml/salt/element/Grid.java @@ -35,12 +35,18 @@ */ package net.sourceforge.plantuml.salt.element; +import java.awt.geom.Dimension2D; import java.util.HashSet; import java.util.Set; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.salt.Cell; +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; +import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UTranslate; public class Grid { @@ -48,15 +54,18 @@ public class Grid { private final double[] rowsStart; private final double[] colsStart; private final TableStrategy strategy; + private final TextBlock title; private final Set horizontals = new HashSet(); private final Set verticals = new HashSet(); - public Grid(double[] rowsStart, double[] colsStart, TableStrategy strategy) { + public Grid(double[] rowsStart, double[] colsStart, TableStrategy strategy, TextBlock title) { + this.title = title; this.rowsStart = rowsStart; this.colsStart = colsStart; this.strategy = strategy; - if (strategy == TableStrategy.DRAW_OUTSIDE || strategy == TableStrategy.DRAW_ALL) { + if (strategy == TableStrategy.DRAW_OUTSIDE || strategy == TableStrategy.DRAW_OUTSIDE_WITH_TITLE + || strategy == TableStrategy.DRAW_ALL) { addOutside(); } } @@ -90,14 +99,22 @@ public class Grid { final double height = rowsStart[row1 + 1] - rowsStart[row1]; ug.apply(new UTranslate(x + colsStart[col1], y + rowsStart[row1])).draw(new ULine(0, height)); } + + final Dimension2D dim = title.calculateDimension(ug.getStringBounder()); + + if (dim.getWidth() > 0 && dim.getHeight() > 0) { + final UGraphic ug2 = ug.apply(new UTranslate(x + 6, y - dim.getHeight() * 0)); + ug2.apply(new UChangeBackColor(HtmlColorUtils.WHITE)).apply(new UChangeColor(HtmlColorUtils.WHITE)) + .draw(new URectangle(dim)); + title.drawU(ug2); + } + } public void addCell(Cell cell) { - if (strategy == TableStrategy.DRAW_NONE) { - return; - } - if (strategy == TableStrategy.DRAW_OUTSIDE) { + if (strategy == TableStrategy.DRAW_NONE || strategy == TableStrategy.DRAW_OUTSIDE + || strategy == TableStrategy.DRAW_OUTSIDE_WITH_TITLE) { return; } diff --git a/src/net/sourceforge/plantuml/salt/element/Grid2.java b/src/net/sourceforge/plantuml/salt/element/Grid2.java index 9a34243c4..033c96121 100644 --- a/src/net/sourceforge/plantuml/salt/element/Grid2.java +++ b/src/net/sourceforge/plantuml/salt/element/Grid2.java @@ -58,7 +58,7 @@ public class Grid2 { final double xmax = colsStart.get(colsStart.size() - 1); final double ymin = rowsStart.get(0); final double ymax = rowsStart.get(rowsStart.size() - 1); - if (strategy == TableStrategy.DRAW_OUTSIDE) { + if (strategy == TableStrategy.DRAW_OUTSIDE || strategy == TableStrategy.DRAW_OUTSIDE_WITH_TITLE) { ug.apply(new UTranslate(xmin, ymin)).draw(new ULine(xmax - xmin, 0)); ug.apply(new UTranslate(xmin, ymax)).draw(new ULine(xmax - xmin, 0)); ug.apply(new UTranslate(xmin, ymin)).draw(new ULine(0, ymax - ymin)); diff --git a/src/net/sourceforge/plantuml/salt/element/TableStrategy.java b/src/net/sourceforge/plantuml/salt/element/TableStrategy.java index 79f316d68..ca0ed6c81 100644 --- a/src/net/sourceforge/plantuml/salt/element/TableStrategy.java +++ b/src/net/sourceforge/plantuml/salt/element/TableStrategy.java @@ -36,7 +36,7 @@ package net.sourceforge.plantuml.salt.element; public enum TableStrategy { - DRAW_NONE(' '), DRAW_OUTSIDE('+'), DRAW_HORIZONTAL('-'), DRAW_VERTICAL('!'), DRAW_ALL('#'); + DRAW_NONE(' '), DRAW_OUTSIDE('+'), DRAW_OUTSIDE_WITH_TITLE('^'), DRAW_HORIZONTAL('-'), DRAW_VERTICAL('!'), DRAW_ALL('#'); private final char c; diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryButton.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryButton.java index e9fea9bc0..777c3da27 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryButton.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryButton.java @@ -60,7 +60,7 @@ public class ElementFactoryButton implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementButton(text.substring(1, text.length() - 1), font, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java index 529694b96..e1132a284 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java @@ -63,7 +63,7 @@ public class ElementFactoryCheckboxOff implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementRadioCheckbox(extracted(text), font, false, false, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java index 3aceea9d8..544c39079 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java @@ -63,7 +63,7 @@ public class ElementFactoryCheckboxOn implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementRadioCheckbox(extracted(text), font, false, true, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryDroplist.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryDroplist.java index 9d09ca905..73f4aed37 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryDroplist.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryDroplist.java @@ -60,7 +60,7 @@ public class ElementFactoryDroplist implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementDroplist(text.substring(1, text.length() - 1), font, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryMenu.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryMenu.java index d8e1ce3ce..93b84c0e6 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryMenu.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryMenu.java @@ -58,7 +58,7 @@ public class ElementFactoryMenu extends AbstractElementFactoryComplex { final String header = getDataSource().next().getElement(); assert header.startsWith("{*"); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); final ElementMenuBar result = new ElementMenuBar(font, getDictionary()); String subentry = null; diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryPyramid.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryPyramid.java index d62f343f6..d836f6a09 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryPyramid.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryPyramid.java @@ -35,10 +35,12 @@ */ package net.sourceforge.plantuml.salt.factory; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Dictionary; import net.sourceforge.plantuml.salt.Positionner2; import net.sourceforge.plantuml.salt.Terminated; +import net.sourceforge.plantuml.salt.Terminator; import net.sourceforge.plantuml.salt.element.Element; import net.sourceforge.plantuml.salt.element.ElementPyramid; import net.sourceforge.plantuml.salt.element.ElementText; @@ -54,13 +56,18 @@ public class ElementFactoryPyramid extends AbstractElementFactoryComplex { if (ready() == false) { throw new IllegalStateException(); } - final String header = getDataSource().next().getElement(); + final Terminated tmp = getDataSource().next(); + final String header = tmp.getElement(); assert header.startsWith("{"); + String title = null; TableStrategy strategy = TableStrategy.DRAW_NONE; if (header.length() == 2) { strategy = TableStrategy.fromChar(header.charAt(1)); } + if (strategy == TableStrategy.DRAW_OUTSIDE_WITH_TITLE && tmp.getTerminator() == Terminator.NEWCOL) { + title = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(getDataSource().next().getElement(), "\""); + } final Positionner2 positionner = new Positionner2(); @@ -73,7 +80,8 @@ public class ElementFactoryPyramid extends AbstractElementFactoryComplex { } } final Terminated next = getDataSource().next(); - return new Terminated(new ElementPyramid(positionner, strategy), next.getTerminator()); + return new Terminated(new ElementPyramid(positionner, strategy, title, getDictionary()), + next.getTerminator()); } private boolean isStar(Element element) { @@ -85,7 +93,8 @@ public class ElementFactoryPyramid extends AbstractElementFactoryComplex { public boolean ready() { final String text = getDataSource().peek(0).getElement(); - if (text.equals("{") || text.equals("{+") || text.equals("{#") || text.equals("{!") || text.equals("{-")) { + if (text.equals("{") || text.equals("{+") || text.equals("{^") || text.equals("{#") || text.equals("{!") + || text.equals("{-")) { final String text1 = getDataSource().peek(1).getElement(); if (text1.matches("[NSEW]=|T")) { return false; diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java index ad1f21d07..210b35719 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java @@ -63,7 +63,7 @@ public class ElementFactoryRadioOff implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementRadioCheckbox(extracted(text), font, true, false, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java index 1a2327b2d..c75d754c9 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java @@ -63,7 +63,7 @@ public class ElementFactoryRadioOn implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementRadioCheckbox(extracted(text), font, true, true, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTab.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTab.java index e7938b5fa..f33e91843 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTab.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTab.java @@ -58,7 +58,7 @@ public class ElementFactoryTab extends AbstractElementFactoryComplex { final String header = getDataSource().next().getElement(); assert header.startsWith("{/"); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); final ElementTabBar result = new ElementTabBar(font, getDictionary()); while (getDataSource().peek(0).getElement().equals("}") == false) { diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java index a7295363f..42e5b4e6b 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java @@ -62,7 +62,7 @@ public class ElementFactoryText implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated(new ElementText(Arrays.asList(text), font, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTextField.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTextField.java index 6058efce9..7891d674d 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTextField.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTextField.java @@ -60,7 +60,7 @@ public class ElementFactoryTextField implements ElementFactory { } final Terminated next = dataSource.next(); final String text = next.getElement(); - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); return new Terminated( new ElementTextField(text.substring(1, text.length() - 1), font, spriteContainer), next.getTerminator()); } diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTree.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTree.java index 5690626cb..1f8bfb0c0 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTree.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryTree.java @@ -63,7 +63,7 @@ public class ElementFactoryTree extends AbstractElementFactoryComplex { strategy = TableStrategy.fromChar(textT.charAt(1)); } - final UFont font = new UFont("Default", Font.PLAIN, 12); + final UFont font = UFont.byDefault(12); final ElementTree result = new ElementTree(font, getDictionary(), strategy); boolean takeMe = true; diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java index 2b3ffb194..960aeea61 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.teoz; +import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.ColorMapper; @@ -99,8 +100,10 @@ public class LiveBoxFinder implements UGraphic { ((GroupingTile) shape).drawU(this); } else if (shape instanceof TileWithUpdateStairs) { ((TileWithUpdateStairs) shape).updateStairs(stringBounder, y); + } else if (shape instanceof NotesTile) { + // Nothing ? } else if (shape instanceof Tile) { - System.err.println("OtherTile " + shape); + Log.error("OtherTile " + shape); } else { throw new UnsupportedOperationException(shape.getClass().getName()); } diff --git a/src/net/sourceforge/plantuml/skin/GrayComponent.java b/src/net/sourceforge/plantuml/skin/GrayComponent.java index 977cebe24..525b788a0 100644 --- a/src/net/sourceforge/plantuml/skin/GrayComponent.java +++ b/src/net/sourceforge/plantuml/skin/GrayComponent.java @@ -54,7 +54,7 @@ import net.sourceforge.plantuml.ugraphic.URectangle; class GrayComponent extends AbstractComponent { - private static final UFont NORMAL = new UFont("SansSerif", Font.PLAIN, 7); + private static final UFont NORMAL = UFont.sansSerif(7); private final ComponentType type; diff --git a/src/net/sourceforge/plantuml/skin/VisibilityModifier.java b/src/net/sourceforge/plantuml/skin/VisibilityModifier.java index 4910a563b..7207e8bfb 100644 --- a/src/net/sourceforge/plantuml/skin/VisibilityModifier.java +++ b/src/net/sourceforge/plantuml/skin/VisibilityModifier.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; @@ -94,7 +95,7 @@ public enum VisibilityModifier { } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java index 32747e31e..b53948caa 100644 --- a/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java +++ b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java @@ -35,8 +35,6 @@ */ package net.sourceforge.plantuml.skin.bluemodern; -import java.awt.Font; - import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; @@ -58,10 +56,10 @@ import net.sourceforge.plantuml.ugraphic.UFont; public class BlueModern implements Skin { - private final UFont bigFont = new UFont("SansSerif", Font.BOLD, 20); - private final UFont participantFont = new UFont("SansSerif", Font.PLAIN, 17); - private final UFont normalFont = new UFont("SansSerif", Font.PLAIN, 13); - private final UFont smallFont = new UFont("SansSerif", Font.BOLD, 11); + private final UFont bigFont = UFont.sansSerif(20).bold(); + private final UFont participantFont = UFont.sansSerif(17); + private final UFont normalFont = UFont.sansSerif(13); + private final UFont smallFont = UFont.sansSerif(11).bold(); private final HtmlColor hyperlinkColor = HtmlColorUtils.BLUE; private final boolean useUnderlineForHyperlink = true; diff --git a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java index 15cec92cf..c514ad4eb 100644 --- a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java @@ -36,7 +36,6 @@ package net.sourceforge.plantuml.sudoku; import java.awt.Color; -import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; @@ -66,8 +65,8 @@ import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; public class GraphicsSudoku { private final ISudoku sudoku; - private final UFont numberFont = new UFont("SansSerif", Font.BOLD, 20); - private final UFont font = new UFont("SansSerif", Font.PLAIN, 11); + private final UFont numberFont = UFont.sansSerif(20).bold(); + private final UFont font = UFont.sansSerif(11); public GraphicsSudoku(ISudoku sudoku) { this.sudoku = sudoku; diff --git a/src/net/sourceforge/plantuml/svek/AbstractEntityImage.java b/src/net/sourceforge/plantuml/svek/AbstractEntityImage.java index 9db1570eb..b8e2707f0 100644 --- a/src/net/sourceforge/plantuml/svek/AbstractEntityImage.java +++ b/src/net/sourceforge/plantuml/svek/AbstractEntityImage.java @@ -40,6 +40,7 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; public abstract class AbstractEntityImage extends AbstractTextBlock implements IEntityImage { @@ -75,4 +76,8 @@ public abstract class AbstractEntityImage extends AbstractTextBlock implements I return entity.getStereotype(); } + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; + } + } diff --git a/src/net/sourceforge/plantuml/svek/ConcurrentStateImage.java b/src/net/sourceforge/plantuml/svek/ConcurrentStateImage.java index 6c00ff2ac..15232bdfe 100644 --- a/src/net/sourceforge/plantuml/svek/ConcurrentStateImage.java +++ b/src/net/sourceforge/plantuml/svek/ConcurrentStateImage.java @@ -149,8 +149,8 @@ public final class ConcurrentStateImage extends AbstractTextBlock implements IEn return false; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public ShapeType getShapeType() { diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2InternalImage.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2InternalImage.java index 6eeca3075..7c0d06cab 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2InternalImage.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2InternalImage.java @@ -144,8 +144,8 @@ public final class CucaDiagramFileMakerSvek2InternalImage extends AbstractTextBl return false; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public ShapeType getShapeType() { diff --git a/src/net/sourceforge/plantuml/svek/DotDataImageBuilder.java b/src/net/sourceforge/plantuml/svek/DotDataImageBuilder.java index 0eca11e4a..a41e0962d 100644 --- a/src/net/sourceforge/plantuml/svek/DotDataImageBuilder.java +++ b/src/net/sourceforge/plantuml/svek/DotDataImageBuilder.java @@ -155,7 +155,7 @@ public final class DotDataImageBuilder { dotStringFactory.getBibliotekon().addLine(line); - if (link.getEntity1().isGroup() == false && link.getEntity1().getEntityType() == LeafType.NOTE + if (link.getEntity1().isGroup() == false && link.getEntity1().getLeafType() == LeafType.NOTE && onlyOneLink(link.getEntity1())) { final Shape shape = dotStringFactory.getBibliotekon().getShape(link.getEntity1()); final Shape other = dotStringFactory.getBibliotekon().getShape(link.getEntity2()); @@ -163,7 +163,7 @@ public final class DotDataImageBuilder { ((EntityImageNote) shape.getImage()).setOpaleLine(line, shape, other); line.setOpale(true); } - } else if (link.getEntity2().isGroup() == false && link.getEntity2().getEntityType() == LeafType.NOTE + } else if (link.getEntity2().isGroup() == false && link.getEntity2().getLeafType() == LeafType.NOTE && onlyOneLink(link.getEntity2())) { final Shape shape = dotStringFactory.getBibliotekon().getShape(link.getEntity2()); final Shape other = dotStringFactory.getBibliotekon().getShape(link.getEntity1()); @@ -281,7 +281,7 @@ public final class DotDataImageBuilder { final IEntityImage image = printEntityInternal(dotStringFactory, ent); final Dimension2D dim = image.calculateDimension(stringBounder); final Shape shape = new Shape(image, image.getShapeType(), dim.getWidth(), dim.getHeight(), - dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(), ent.getEntityPosition()); + dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(stringBounder), ent.getEntityPosition()); dotStringFactory.addShape(shape); dotStringFactory.getBibliotekon().putShape(ent, shape); } @@ -307,7 +307,7 @@ public final class DotDataImageBuilder { private double getMaxWidth(DotStringFactory dotStringFactory) { double result = 0; for (ILeaf ent : dotData.getLeafs()) { - if (ent.getEntityType().isLikeClass() == false) { + if (ent.getLeafType().isLikeClass() == false) { continue; } final IEntityImage im = new EntityImageClass(dotStringFactory.getGraphvizVersion(), ent, @@ -326,7 +326,7 @@ public final class DotDataImageBuilder { if (leaf.isRemoved()) { throw new IllegalStateException(); } - if (leaf.getEntityType().isLikeClass()) { + if (leaf.getLeafType().isLikeClass()) { final EntityImageClass entityImageClass = new EntityImageClass(graphvizVersion, (ILeaf) leaf, skinParam, portionShower); final Neighborhood neighborhood = leaf.getNeighborhood(); @@ -335,13 +335,13 @@ public final class DotDataImageBuilder { } return entityImageClass; } - if (leaf.getEntityType() == LeafType.NOTE) { + if (leaf.getLeafType() == LeafType.NOTE) { return new EntityImageNote(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.ACTIVITY) { + if (leaf.getLeafType() == LeafType.ACTIVITY) { return new EntityImageActivity(leaf, skinParam, bibliotekon); } - if (leaf.getEntityType() == LeafType.STATE) { + if (leaf.getLeafType() == LeafType.STATE) { if (leaf.getEntityPosition() != EntityPosition.NORMAL) { final Cluster stateParent = bibliotekon.getCluster(leaf.getParentContainer()); return new EntityImageStateBorder(leaf, skinParam, stateParent, bibliotekon); @@ -355,27 +355,31 @@ public final class DotDataImageBuilder { return new EntityImageState(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.CIRCLE_START) { + if (leaf.getLeafType() == LeafType.CIRCLE_START) { ColorParam param = ColorParam.activityStart; if (umlDiagramType == UmlDiagramType.STATE) { param = ColorParam.stateStart; } return new EntityImageCircleStart(leaf, skinParam, param); } - if (leaf.getEntityType() == LeafType.CIRCLE_END) { + if (leaf.getLeafType() == LeafType.CIRCLE_END) { ColorParam param = ColorParam.activityEnd; if (umlDiagramType == UmlDiagramType.STATE) { param = ColorParam.stateEnd; } return new EntityImageCircleEnd(leaf, skinParam, param); } - if (leaf.getEntityType() == LeafType.BRANCH || leaf.getEntityType() == LeafType.STATE_CHOICE) { + if (leaf.getLeafType() == LeafType.BRANCH || leaf.getLeafType() == LeafType.STATE_CHOICE) { return new EntityImageBranch(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.LOLLIPOP) { + if (leaf.getLeafType() == LeafType.LOLLIPOP) { return new EntityImageLollipopInterface(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.DESCRIPTION) { + if (leaf.getLeafType() == LeafType.CIRCLE) { + return new EntityImageDescription(leaf, skinParam, portionShower); + } + + if (leaf.getLeafType() == LeafType.DESCRIPTION) { if (OptionFlags.USE_INTERFACE_EYE1 && leaf.getUSymbol() instanceof USymbolInterface) { return new EntityImageLollipopInterfaceEye1(leaf, skinParam, bibliotekon); } else if (OptionFlags.USE_INTERFACE_EYE2 && leaf.getUSymbol() instanceof USymbolInterface) { @@ -384,44 +388,44 @@ public final class DotDataImageBuilder { return new EntityImageDescription(leaf, skinParam, portionShower); } } - if (leaf.getEntityType() == LeafType.USECASE) { + if (leaf.getLeafType() == LeafType.USECASE) { return new EntityImageUseCase(leaf, skinParam); } // if (leaf.getEntityType() == LeafType.CIRCLE_INTERFACE) { // return new EntityImageCircleInterface(leaf, skinParam); // } - if (leaf.getEntityType() == LeafType.OBJECT) { + if (leaf.getLeafType() == LeafType.OBJECT) { return new EntityImageObject(leaf, skinParam, portionShower); } - if (leaf.getEntityType() == LeafType.SYNCHRO_BAR || leaf.getEntityType() == LeafType.STATE_FORK_JOIN) { + if (leaf.getLeafType() == LeafType.SYNCHRO_BAR || leaf.getLeafType() == LeafType.STATE_FORK_JOIN) { return new EntityImageSynchroBar(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.ARC_CIRCLE) { + if (leaf.getLeafType() == LeafType.ARC_CIRCLE) { return new EntityImageArcCircle(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.POINT_FOR_ASSOCIATION) { + if (leaf.getLeafType() == LeafType.POINT_FOR_ASSOCIATION) { return new EntityImageAssociationPoint(leaf, skinParam); } if (leaf.isGroup()) { return new EntityImageGroup(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.EMPTY_PACKAGE) { + if (leaf.getLeafType() == LeafType.EMPTY_PACKAGE) { if (leaf.getUSymbol() != null) { return new EntityImageDescription(leaf, new SkinParamForecolored(skinParam, HtmlColorUtils.BLACK), portionShower); } return new EntityImageEmptyPackage(leaf, skinParam, portionShower); } - if (leaf.getEntityType() == LeafType.ASSOCIATION) { + if (leaf.getLeafType() == LeafType.ASSOCIATION) { return new EntityImageAssociation(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.PSEUDO_STATE) { + if (leaf.getLeafType() == LeafType.PSEUDO_STATE) { return new EntityImagePseudoState(leaf, skinParam); } - if (leaf.getEntityType() == LeafType.TIPS) { + if (leaf.getLeafType() == LeafType.TIPS) { return new EntityImageTips(leaf, skinParam, bibliotekon); } - throw new UnsupportedOperationException(leaf.getEntityType().toString()); + throw new UnsupportedOperationException(leaf.getLeafType().toString()); } private Collection getUnpackagedEntities() { diff --git a/src/net/sourceforge/plantuml/svek/EntityImageProtected.java b/src/net/sourceforge/plantuml/svek/EntityImageProtected.java index 59ab1ea27..823ad05e7 100644 --- a/src/net/sourceforge/plantuml/svek/EntityImageProtected.java +++ b/src/net/sourceforge/plantuml/svek/EntityImageProtected.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.cucadiagram.dot.Neighborhood; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -53,7 +54,7 @@ public class EntityImageProtected extends AbstractTextBlock implements IEntityIm private final Bibliotekon bibliotekon; private final Neighborhood neighborhood; - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { throw new UnsupportedOperationException(); } @@ -90,8 +91,8 @@ public class EntityImageProtected extends AbstractTextBlock implements IEntityIm return orig.getShapeType(); } - public int getShield() { - return orig.getShield(); + public Margins getShield(StringBounder stringBounder) { + return orig.getShield(stringBounder); } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java index 718c6bc37..0a75e849d 100644 --- a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java +++ b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java @@ -177,8 +177,8 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } } diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java index 5a9e55621..29622e7f9 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java @@ -52,8 +52,6 @@ import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.Member; -import net.sourceforge.plantuml.cucadiagram.MethodsOrFieldsArea; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.DotData; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -63,6 +61,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockEmpty; import net.sourceforge.plantuml.graphic.TextBlockWidth; +import net.sourceforge.plantuml.graphic.TextBlockWidthAdapter; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.svek.image.EntityImageState; @@ -127,7 +126,7 @@ public final class GroupPngMakerState { final DotDataImageBuilder svek2 = new DotDataImageBuilder(dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder); - + if (group.getGroupType() == GroupType.CONCURRENT_STATE) { // return new InnerStateConcurrent(svek2.createFile()); return svek2.buildImage(null, new String[0]); @@ -144,13 +143,18 @@ public final class GroupPngMakerState { final Stereotype stereo = group.getStereotype(); final HtmlColor backColor = group.getColors(skinParam).getColor(ColorType.BACK) == null ? getColor( ColorParam.stateBackground, stereo) : group.getColors(skinParam).getColor(ColorType.BACK); - final List members = ((IEntity) group).getBodier().getFieldsToDisplay(); + final List details = ((IEntity) group).getBodier().getRawBody(); final TextBlockWidth attribute; - if (members.size() == 0) { + if (details.size() == 0) { attribute = new TextBlockEmpty(); } else { - attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, diagram.getSkinParam(), - group.getStereotype(), null); + final FontConfiguration fontConfiguration = new FontConfiguration(skinParam, FontParam.STATE_ATTRIBUTE, + null); + final TextBlock tmp = Display.create(details) + .create(fontConfiguration, HorizontalAlignment.LEFT, skinParam); + attribute = new TextBlockWidthAdapter(tmp, 0); + // attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, diagram.getSkinParam(), + // group.getStereotype(), null); } final Stereotype stereotype = group.getStereotype(); @@ -183,7 +187,7 @@ public final class GroupPngMakerState { if (leaf instanceof IGroup == false) { return false; } - if (((IGroup) leaf).getEntityType() != LeafType.STATE_CONCURRENT) { + if (((IGroup) leaf).getLeafType() != LeafType.STATE_CONCURRENT) { return false; } } diff --git a/src/net/sourceforge/plantuml/svek/IEntityImage.java b/src/net/sourceforge/plantuml/svek/IEntityImage.java index 83d0e4f7e..251de5ebd 100644 --- a/src/net/sourceforge/plantuml/svek/IEntityImage.java +++ b/src/net/sourceforge/plantuml/svek/IEntityImage.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.svek; import net.sourceforge.plantuml.Hideable; +import net.sourceforge.plantuml.graphic.StringBounder; public interface IEntityImage extends Hideable, TextBlockBackcolored { @@ -45,6 +46,6 @@ public interface IEntityImage extends Hideable, TextBlockBackcolored { ShapeType getShapeType(); - int getShield(); + Margins getShield(StringBounder stringBounder); } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/svek/InnerActivity.java b/src/net/sourceforge/plantuml/svek/InnerActivity.java index 143289e24..6b7e7e5bb 100644 --- a/src/net/sourceforge/plantuml/svek/InnerActivity.java +++ b/src/net/sourceforge/plantuml/svek/InnerActivity.java @@ -90,8 +90,8 @@ public final class InnerActivity extends AbstractTextBlock implements IEntityIma return ShapeType.ROUND_RECTANGLE; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public boolean isHidden() { diff --git a/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java b/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java index ce68d9f21..7dadf2204 100644 --- a/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java +++ b/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java @@ -139,8 +139,8 @@ public final class InnerStateAutonom extends AbstractTextBlock implements IEntit return ShapeType.ROUND_RECTANGLE; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public boolean isHidden() { diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index ba717517d..29b8f40b5 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -462,6 +462,9 @@ public class Line implements Moveable, Hideable { if (extremityFactory != null) { final List points = pointListIterator.next(); + if (points.size() == 0) { + return null; + } final Point2D p0 = points.get(0); final Point2D p1 = points.get(1); final Point2D p2 = points.get(2); diff --git a/src/net/sourceforge/plantuml/svek/Margins.java b/src/net/sourceforge/plantuml/svek/Margins.java new file mode 100644 index 000000000..a720b4bac --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/Margins.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.svek; + +public class Margins { + + private final double x1; + private final double x2; + private final double y1; + private final double y2; + + static public Margins NONE = new Margins(0, 0, 0, 0); + + public static Margins uniform(double value) { + return new Margins(value, value, value, value); + } + + public Margins(double x1, double x2, double y1, double y2) { + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + } + + public boolean isZero() { + return x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0; + } + + public final double getX1() { + return x1; + } + + public final double getX2() { + return x2; + } + + public final double getY1() { + return y1; + } + + public final double getY2() { + return y2; + } + + public double getTotalWidth() { + return x1 + x2; + } + + public double getTotalHeight() { + return y1 + y2; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/svek/Shape.java b/src/net/sourceforge/plantuml/svek/Shape.java index 703fb7dfa..8db70c7fe 100644 --- a/src/net/sourceforge/plantuml/svek/Shape.java +++ b/src/net/sourceforge/plantuml/svek/Shape.java @@ -62,7 +62,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { private double minX; private double minY; - private final int shield; + private final Margins shield; private final EntityPosition entityPosition; private final IEntityImage image; @@ -89,7 +89,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { } public Shape(IEntityImage image, ShapeType type, double width, double height, ColorSequence colorSequence, - boolean top, int shield, EntityPosition entityPosition) { + boolean top, Margins shield, EntityPosition entityPosition) { this.entityPosition = entityPosition; this.image = image; this.top = top; @@ -99,7 +99,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { this.color = colorSequence.getValue(); this.uid = String.format("sh%04d", color); this.shield = shield; - if (shield > 0 && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS) { + if (shield.isZero() == false && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS) { throw new IllegalArgumentException(); } } @@ -121,7 +121,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { appendLabelHtmlSpecialForLink(sb, stringBounder); return; } - if (type == ShapeType.RECTANGLE && shield > 0) { + if (type == ShapeType.RECTANGLE && shield.isZero() == false) { appendHtml(sb); return; } @@ -157,20 +157,20 @@ public class Shape implements Positionable, IShapePseudo, Hideable { sb.append(""); sb.append(""); appendTd(sb); - appendTd(sb, shield, shield); + appendTd(sb, 1, shield.getY1()); appendTd(sb); sb.append(""); sb.append(""); - appendTd(sb, shield, shield); + appendTd(sb, shield.getX1(), 1); sb.append(""); - appendTd(sb, shield, shield); + appendTd(sb, shield.getX2(), 1); sb.append(""); sb.append(""); appendTd(sb); - appendTd(sb, shield, shield); + appendTd(sb, 1, shield.getY2()); appendTd(sb); sb.append(""); sb.append("
"); sb.append("
"); @@ -217,7 +217,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { sb.append(""); } - private void appendTd(StringBuilder sb, int w, int h) { + private void appendTd(StringBuilder sb, double w, double h) { sb.append(""); @@ -230,7 +230,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { } private void appendShapeInternal(StringBuilder sb) { - if (type == ShapeType.RECTANGLE && shield > 0) { + if (type == ShapeType.RECTANGLE && shield.isZero() == false) { throw new UnsupportedOperationException(); } else if (type == ShapeType.RECTANGLE || type == ShapeType.FOLDER) { sb.append("shape=rect"); @@ -289,7 +289,7 @@ public class Shape implements Positionable, IShapePseudo, Hideable { } public boolean isShielded() { - return shield > 0; + return shield.isZero() == false; } public void moveSvek(double deltaX, double deltaY) { diff --git a/src/net/sourceforge/plantuml/svek/SvekResult.java b/src/net/sourceforge/plantuml/svek/SvekResult.java index fbc58e60d..524dee79a 100644 --- a/src/net/sourceforge/plantuml/svek/SvekResult.java +++ b/src/net/sourceforge/plantuml/svek/SvekResult.java @@ -121,8 +121,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage, return ShapeType.RECTANGLE; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public void moveSvek(double deltaX, double deltaY) { diff --git a/src/net/sourceforge/plantuml/svek/SvekUtils.java b/src/net/sourceforge/plantuml/svek/SvekUtils.java index cbefaa86f..051af141a 100644 --- a/src/net/sourceforge/plantuml/svek/SvekUtils.java +++ b/src/net/sourceforge/plantuml/svek/SvekUtils.java @@ -41,6 +41,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -79,9 +80,14 @@ public class SvekUtils { } public List next() { - final List result = extractPointsList(text, pos, yDelta); - pos = text.indexOf(pointsString, pos) + pointsString.length() + 1; - return result; + try { + final List result = extractPointsList(text, pos, yDelta); + pos = text.indexOf(pointsString, pos) + pointsString.length() + 1; + return result; + } catch (StringIndexOutOfBoundsException e) { + Log.error("Error " + e); + return Collections.emptyList(); + } } public void remove() { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java index fa6721d85..3524430e4 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java @@ -151,8 +151,4 @@ public class EntityImageActivity extends AbstractEntityImage { return ShapeType.ROUND_RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java b/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java index 1e023ce09..0e9dce401 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java @@ -111,8 +111,4 @@ public class EntityImageArcCircle extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageAssociation.java b/src/net/sourceforge/plantuml/svek/image/EntityImageAssociation.java index 3a6061f6a..ed629e6e7 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageAssociation.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageAssociation.java @@ -83,8 +83,4 @@ public class EntityImageAssociation extends AbstractEntityImage { return ShapeType.DIAMOND; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageAssociationPoint.java b/src/net/sourceforge/plantuml/svek/image/EntityImageAssociationPoint.java index 39510b2f9..2954d2117 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageAssociationPoint.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageAssociationPoint.java @@ -71,8 +71,4 @@ public class EntityImageAssociationPoint extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageBranch.java b/src/net/sourceforge/plantuml/svek/image/EntityImageBranch.java index a6432d26b..1990685fb 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageBranch.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageBranch.java @@ -83,8 +83,4 @@ public class EntityImageBranch extends AbstractEntityImage { return ShapeType.DIAMOND; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageCircleEnd.java b/src/net/sourceforge/plantuml/svek/image/EntityImageCircleEnd.java index 17c9feb37..8d4876a30 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageCircleEnd.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageCircleEnd.java @@ -85,8 +85,4 @@ public class EntityImageCircleEnd extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageCircleStart.java b/src/net/sourceforge/plantuml/svek/image/EntityImageCircleStart.java index 945113015..11ceb00b6 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageCircleStart.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageCircleStart.java @@ -77,8 +77,4 @@ public class EntityImageCircleStart extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java index 7841b6234..baf36739a 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java @@ -52,10 +52,12 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.PortionShower; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.Ports; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.svek.WithPorts; @@ -72,7 +74,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class EntityImageClass extends AbstractEntityImage implements Stencil, WithPorts { final private TextBlock body; - final private int shield; + final private Margins shield; final private EntityImageClassHeader2 header; final private Url url; final private double roundCorner; @@ -83,7 +85,8 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi super(entity, entity.getColors(skinParam).mute(skinParam)); this.lineConfig = entity; this.roundCorner = getSkinParam().getRoundCorner("", null); - this.shield = version != null && version.useShield() && entity.hasNearDecoration() ? 16 : 0; + this.shield = version != null && version.useShield() && entity.hasNearDecoration() ? Margins.uniform(16) + : Margins.NONE; final boolean showMethods = portionShower.showPortion(EntityPortion.METHOD, entity); final boolean showFields = portionShower.showPortion(EntityPortion.FIELD, entity); this.body = entity.getBodier().getBody(FontParam.CLASS_ATTRIBUTE, getSkinParam(), showMethods, showFields, @@ -107,8 +110,8 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi } @Override - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { - final Rectangle2D result = body.getInnerPosition(member, stringBounder); + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + final Rectangle2D result = body.getInnerPosition(member, stringBounder, strategy); if (result == null) { return result; } @@ -195,7 +198,8 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi return ShapeType.RECTANGLE; } - public int getShield() { + @Override + public Margins getShield(StringBounder stringBounder) { return shield; } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java index 4ad0b164f..034e6a4d6 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java @@ -71,8 +71,8 @@ public class EntityImageClassHeader2 extends AbstractEntityImage { public EntityImageClassHeader2(ILeaf entity, ISkinParam skinParam, PortionShower portionShower) { super(entity, skinParam); - final boolean italic = entity.getEntityType() == LeafType.ABSTRACT_CLASS - || entity.getEntityType() == LeafType.INTERFACE; + final boolean italic = entity.getLeafType() == LeafType.ABSTRACT_CLASS + || entity.getLeafType() == LeafType.INTERFACE; // final HtmlColor color = SkinParamUtils.getFontColor(getSkinParam(), FontParam.CLASS, getStereo()); final Stereotype stereotype = entity.getStereotype(); @@ -145,32 +145,32 @@ public class EntityImageClassHeader2 extends AbstractEntityImage { stereotype.getHtmlColor(), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.ANNOTATION) { + if (entity.getLeafType() == LeafType.ANNOTATION) { return new CircledCharacter('@', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeNBackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.ABSTRACT_CLASS) { + if (entity.getLeafType() == LeafType.ABSTRACT_CLASS) { return new CircledCharacter('A', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeABackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.CLASS) { + if (entity.getLeafType() == LeafType.CLASS) { return new CircledCharacter('C', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeCBackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.INTERFACE) { + if (entity.getLeafType() == LeafType.INTERFACE) { return new CircledCharacter('I', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeIBackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.ENUM) { + if (entity.getLeafType() == LeafType.ENUM) { return new CircledCharacter('E', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeEBackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); } - if (entity.getEntityType() == LeafType.ENTITY) { + if (entity.getLeafType() == LeafType.ENTITY) { return new CircledCharacter('E', getSkinParam().getCircledCharacterRadius(), font, SkinParamUtils.getColor( getSkinParam(), ColorParam.stereotypeCBackground, stereotype), classBorder, SkinParamUtils.getFontColor(getSkinParam(), FontParam.CIRCLED_CHARACTER, null)); @@ -195,8 +195,4 @@ public class EntityImageClassHeader2 extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java index 52d40333d..73d9b8453 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.svek.image; import java.awt.geom.Dimension2D; +import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.Url; @@ -58,10 +59,13 @@ import net.sourceforge.plantuml.graphic.USymbol; import net.sourceforge.plantuml.graphic.USymbolFolder; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.UComment; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UStroke; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.utils.MathUtils; public class EntityImageDescription extends AbstractEntityImage { @@ -72,19 +76,21 @@ public class EntityImageDescription extends AbstractEntityImage { private final TextBlock asSmall; private final TextBlock name; + private final TextBlock desc; + + private TextBlock stereo; + + private final boolean hideText; public EntityImageDescription(ILeaf entity, ISkinParam skinParam, PortionShower portionShower) { super(entity, entity.getColors(skinParam).mute(skinParam)); final Stereotype stereotype = entity.getStereotype(); - USymbol symbol = entity.getUSymbol() == null ? (getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 - : USymbol.COMPONENT1) : entity.getUSymbol(); - if (symbol == null) { - throw new IllegalArgumentException(); - } - shapeType = symbol == USymbol.FOLDER ? ShapeType.FOLDER : ShapeType.RECTANGLE; + USymbol symbol = getUSymbol(entity); + this.shapeType = symbol == USymbol.FOLDER ? ShapeType.FOLDER : ShapeType.RECTANGLE; + this.hideText = symbol == USymbol.INTERFACE; final Display codeDisplay = Display.getWithNewlines(entity.getCode()); - final TextBlock desc = (entity.getDisplay().equals(codeDisplay) && symbol instanceof USymbolFolder) + desc = (entity.getDisplay().equals(codeDisplay) && symbol instanceof USymbolFolder) || entity.getDisplay().isWhite() ? TextBlockUtils.empty(0, 0) : new BodyEnhanced(entity.getDisplay(), symbol.getFontParam(), getSkinParam(), HorizontalAlignment.LEFT, stereotype, symbol.manageHorizontalLine(), false, entity); @@ -95,7 +101,7 @@ public class EntityImageDescription extends AbstractEntityImage { if (backcolor == null) { backcolor = SkinParamUtils.getColor(getSkinParam(), symbol.getColorParamBack(), getStereo()); } - // backcolor = HtmlColorUtils.BLUE; + assert getStereo() == stereotype; final HtmlColor forecolor = SkinParamUtils.getColor(getSkinParam(), symbol.getColorParamBorder(), stereotype); final double roundCorner = symbol.getSkinParameter().getRoundCorner(getSkinParam(), stereotype); @@ -103,7 +109,7 @@ public class EntityImageDescription extends AbstractEntityImage { final SymbolContext ctx = new SymbolContext(backcolor, forecolor).withStroke(stroke) .withShadow(getSkinParam().shadowing2(symbol.getSkinParameter())).withRoundCorner(roundCorner); - TextBlock stereo = TextBlockUtils.empty(0, 0); + stereo = TextBlockUtils.empty(0, 0); if (stereotype != null && stereotype.getSprite() != null && getSkinParam().getSprite(stereotype.getSprite()) != null) { @@ -119,10 +125,27 @@ public class EntityImageDescription extends AbstractEntityImage { name = new BodyEnhanced(codeDisplay, symbol.getFontParam(), getSkinParam(), HorizontalAlignment.CENTER, stereotype, symbol.manageHorizontalLine(), false, entity); - asSmall = symbol.asSmall(name, desc, stereo, ctx); + if (hideText) { + asSmall = symbol.asSmall(TextBlockUtils.empty(0, 0), TextBlockUtils.empty(0, 0), + TextBlockUtils.empty(0, 0), ctx); + } else { + asSmall = symbol.asSmall(name, desc, stereo, ctx); + } + } + + private USymbol getUSymbol(ILeaf entity) { + final USymbol result = entity.getUSymbol() == null ? (getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 + : USymbol.COMPONENT1) : entity.getUSymbol(); + if (result == null) { + throw new IllegalArgumentException(); + } + return result; } public Dimension2D getNameDimension(StringBounder stringBounder) { + if (hideText) { + return new Dimension2DDouble(0, 0); + } return name.calculateDimension(stringBounder); } @@ -130,12 +153,40 @@ public class EntityImageDescription extends AbstractEntityImage { return asSmall.calculateDimension(stringBounder); } + @Override + public Margins getShield(StringBounder stringBounder) { + if (hideText) { + final Dimension2D dimStereo = stereo.calculateDimension(stringBounder); + final Dimension2D dimDesc = desc.calculateDimension(stringBounder); + final Dimension2D dimSmall = asSmall.calculateDimension(stringBounder); + final double x = Math.max(dimStereo.getWidth(), dimDesc.getWidth()); + double suppX = x - dimSmall.getWidth(); + if (suppX < 1) { + suppX = 1; + } + final double y = MathUtils.max(1, dimDesc.getHeight(), dimStereo.getHeight()); + return new Margins(suppX / 2, suppX / 2, y, y); + + } + return Margins.NONE; + } + final public void drawU(UGraphic ug) { ug.draw(new UComment("entity " + getEntity().getCode().getFullName())); if (url != null) { ug.startUrl(url); } asSmall.drawU(ug); + if (hideText) { + final double space = 8; + final Dimension2D dimSmall = asSmall.calculateDimension(ug.getStringBounder()); + final Dimension2D dimDesc = desc.calculateDimension(ug.getStringBounder()); + desc.drawU(ug.apply(new UTranslate((dimSmall.getWidth() - dimDesc.getWidth()) / 2, space + + dimSmall.getHeight()))); + final Dimension2D dimStereo = stereo.calculateDimension(ug.getStringBounder()); + stereo.drawU(ug.apply(new UTranslate((dimSmall.getWidth() - dimStereo.getWidth()) / 2, -space + - dimStereo.getHeight()))); + } if (url != null) { ug.closeAction(); @@ -146,8 +197,4 @@ public class EntityImageDescription extends AbstractEntityImage { return shapeType; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java index 316b2a2d2..88faab7bc 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java @@ -140,8 +140,4 @@ public class EntityImageEmptyPackage extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageGroup.java b/src/net/sourceforge/plantuml/svek/image/EntityImageGroup.java index 3b36ec452..eb40977ec 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageGroup.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageGroup.java @@ -67,8 +67,4 @@ public class EntityImageGroup extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java index 835aedeee..bfef7abb6 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java @@ -106,8 +106,4 @@ public class EntityImageLollipopInterface extends AbstractEntityImage { return ShapeType.CIRCLE_IN_RECT; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java index 39866c091..750410155 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java @@ -130,8 +130,4 @@ public class EntityImageLollipopInterfaceEye1 extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java index eaddc891e..8274ebd5e 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java @@ -139,8 +139,4 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index a918a3ad1..50eb9cb7c 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -283,10 +283,6 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - private Line opaleLine; private Shape shape; private Shape other; diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java index e87c6d040..4c0945970 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.SimpleContext2D; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.svek.IEntityImage; +import net.sourceforge.plantuml.svek.Margins; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -72,7 +73,6 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma comp.drawU(ug, new Area(calculateDimension(ug.getStringBounder())), new SimpleContext2D(false)); } - public ShapeType getShapeType() { return ShapeType.RECTANGLE; } @@ -81,8 +81,8 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma return null; } - public int getShield() { - return 0; + public Margins getShield(StringBounder stringBounder) { + return Margins.NONE; } public boolean isHidden() { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java index 7d788ed29..2c642328a 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java @@ -202,10 +202,6 @@ public class EntityImageObject extends AbstractEntityImage implements Stencil { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - public double getStartingX(StringBounder stringBounder, double y) { return 0; } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImagePseudoState.java b/src/net/sourceforge/plantuml/svek/image/EntityImagePseudoState.java index fbe0c310b..775fa2313 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImagePseudoState.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImagePseudoState.java @@ -100,8 +100,4 @@ public class EntityImagePseudoState extends AbstractEntityImage { return ShapeType.CIRCLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState.java index 3cdb652b5..2a583170d 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState.java @@ -189,8 +189,4 @@ public class EntityImageState extends AbstractEntityImage { return ShapeType.ROUND_RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java index 35487f240..147cde9b5 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java @@ -103,10 +103,6 @@ public class EntityImageState2 extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - public Dimension2D calculateDimension(StringBounder stringBounder) { return asSmall.calculateDimension(stringBounder); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java index 72f3c465a..fca40b1a3 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java @@ -130,8 +130,4 @@ public class EntityImageStateBorder extends AbstractEntityImage { return entityPosition.getShapeType(); } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java index c2e0126ad..8963dec74 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java @@ -129,8 +129,4 @@ public class EntityImageStateEmptyDescription extends AbstractEntityImage { return ShapeType.ROUND_RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageSynchroBar.java b/src/net/sourceforge/plantuml/svek/image/EntityImageSynchroBar.java index fbdf69432..d9a51927e 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageSynchroBar.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageSynchroBar.java @@ -80,8 +80,4 @@ public class EntityImageSynchroBar extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java index 6178abfed..db11eca07 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java @@ -53,6 +53,7 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.color.ColorType; @@ -100,10 +101,6 @@ public class EntityImageTips extends AbstractEntityImage { return ShapeType.RECTANGLE; } - public int getShield() { - return 0; - } - public Dimension2D calculateDimension(StringBounder stringBounder) { double width = 0; double height = 0; @@ -132,7 +129,7 @@ public class EntityImageTips extends AbstractEntityImage { double height = 0; for (Map.Entry ent : getEntity().getTips().entrySet()) { final Display display = ent.getValue(); - final Rectangle2D memberPosition = shapeOther.getImage().getInnerPosition(ent.getKey(), stringBounder); + final Rectangle2D memberPosition = shapeOther.getImage().getInnerPosition(ent.getKey(), stringBounder, InnerStrategy.STRICT); if (memberPosition == null) { return; } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java index 9368e5348..2f7e48ad0 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java @@ -132,10 +132,6 @@ public class EntityImageUseCase extends AbstractEntityImage { return ShapeType.OVAL; } - public int getShield() { - return 0; - } - static class MyUGraphicEllipse extends AbstractUGraphicHorizontalLine { private final double startingX; diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index 0a53cbc4a..4bc95d684 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -59,6 +59,7 @@ import javax.xml.transform.stream.StreamResult; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.code.Base64Coder; import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.graphic.HtmlColorGradient; @@ -115,11 +116,11 @@ public class SvgGraphics { } } - public SvgGraphics(double scale, String hover) { - this(null, scale, hover); + public SvgGraphics(double scale, String hover, Random rnd) { + this(null, scale, hover, rnd); } - public SvgGraphics(String backcolor, double scale, String hover) { + public SvgGraphics(String backcolor, double scale, String hover, Random rnd) { try { this.scale = scale; this.document = getDocument(); @@ -132,7 +133,7 @@ public class SvgGraphics { defs = simpleElement("defs"); gRoot = simpleElement("g"); strokeWidth = "" + scale; - final Random rnd = new Random(); + // final Random rnd = new Random(); this.filterUid = "b" + getRandomString(rnd); this.shadowId = "f" + getRandomString(rnd); this.gradientId = "g" + getRandomString(rnd); @@ -707,22 +708,28 @@ public class SvgGraphics { private final Map images = new HashMap(); - public void svgImage(String svg, double x, double y) { - if (svg.startsWith("") == false) { - throw new IllegalArgumentException(); - } + public void svgImage(SvgString image, double x, double y) { if (hidden == false) { + String svg = manageScale(image); final String pos = ""; svg = pos + svg.substring(5); - // System.err.println("svg=" + svg); - // System.err.println("x=" + x); - // System.err.println("y=" + y); final String key = "imagesvginlined" + images.size(); final Element elt = (Element) document.createElement(key); getG().appendChild(elt); images.put(key, svg); } ensureVisible(x, y); + ensureVisible(x + image.getData("width"), y + image.getData("height")); + } + + private String manageScale(SvgString svg) { + final double svgScale = svg.getScale(); + if (svgScale * scale == 1) { + return svg.getSvg(); + } + final String s1 = "\\ emptyList()); final List blocks = sourceStringReader.getBlocks(); @@ -111,7 +111,7 @@ public class SyntaxChecker { public static SyntaxResult checkSyntaxFair(String source) { final SyntaxResult result = new SyntaxResult(); - final SourceStringReader sourceStringReader = new SourceStringReader(new Defines(), source, + final SourceStringReader sourceStringReader = new SourceStringReader(Defines.createEmpty(), source, Collections. emptyList()); final List blocks = sourceStringReader.getBlocks(); diff --git a/src/net/sourceforge/plantuml/timingdiagram/ChangeState.java b/src/net/sourceforge/plantuml/timingdiagram/ChangeState.java index 87d2d9097..1c9eb5b82 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/ChangeState.java +++ b/src/net/sourceforge/plantuml/timingdiagram/ChangeState.java @@ -90,8 +90,12 @@ public class ChangeState implements Comparable { return new SymbolContext(getBackColor(), getLineColor()).withStroke(new UStroke(1.5)); } - public final boolean isHidden() { - return state.length() == 0; + public final boolean isBlank() { + return state.equals("{...}"); + } + + public final boolean isCompletelyHidden() { + return state.equals("{hidden}"); } } diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeState1.java b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java similarity index 88% rename from src/net/sourceforge/plantuml/timingdiagram/CommandChangeState1.java rename to src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java index d749da51e..cb03bdc13 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeState1.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java @@ -46,11 +46,11 @@ import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; -public class CommandChangeState1 extends SingleLineCommand2 { +public class CommandChangeStateByPlayerCode extends SingleLineCommand2 { private static final String STATE_CODE = "([\\p{L}0-9_][\\p{L}0-9_.]*)"; - public CommandChangeState1() { + public CommandChangeStateByPlayerCode() { super(getRegexConcat()); } @@ -68,9 +68,10 @@ public class CommandChangeState1 extends SingleLineCommand2 { static IRegex getStateOrHidden() { return new RegexOr(// - new RegexLeaf("STATE", STATE_CODE), // - new RegexLeaf("\\{[^\\}]*?\\}"), // - new RegexLeaf("[^:\\w]*?") // + new RegexLeaf("STATE1", "[%g]([^%g]+)[%g]"), // + new RegexLeaf("STATE2", STATE_CODE), // + new RegexLeaf("STATE3", "(\\{hidden\\})"), // + new RegexLeaf("STATE4", "(\\{\\.\\.\\.\\})") // ); } @@ -88,7 +89,7 @@ public class CommandChangeState1 extends SingleLineCommand2 { final String comment = arg.get("COMMENT", 0); final TimeTick now = diagram.getNow(); final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet()); - player.setState(now, arg.get("STATE", 0), comment, colors); + player.setState(now, arg.getLazzy("STATE", 0), comment, colors); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeState2.java b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java similarity index 92% rename from src/net/sourceforge/plantuml/timingdiagram/CommandChangeState2.java rename to src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java index 361316554..b47df7c96 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeState2.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java @@ -44,9 +44,9 @@ import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; -public class CommandChangeState2 extends SingleLineCommand2 { +public class CommandChangeStateByTime extends SingleLineCommand2 { - public CommandChangeState2() { + public CommandChangeStateByTime() { super(getRegexConcat()); } @@ -55,7 +55,7 @@ public class CommandChangeState2 extends SingleLineCommand2 { new RegexLeaf("[%s]*"), // TimeTickBuilder.expressionAtWithoutArobase("TIME"), // new RegexLeaf("[%s]*is[%s]*"), // - CommandChangeState1.getStateOrHidden(), // + CommandChangeStateByPlayerCode.getStateOrHidden(), // new RegexLeaf("[%s]*"), // color().getRegex(), // new RegexLeaf("[%s]*"), // @@ -76,7 +76,7 @@ public class CommandChangeState2 extends SingleLineCommand2 { final TimeTick tick = TimeTickBuilder.parseTimeTick("TIME", arg, diagram); final String comment = arg.get("COMMENT", 0); final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet()); - player.setState(tick, arg.get("STATE", 0), comment, colors); + player.setState(tick, arg.getLazzy("STATE", 0), comment, colors); diagram.addTime(tick); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/Histogram.java b/src/net/sourceforge/plantuml/timingdiagram/Histogram.java index 5d2b54ca8..e459f4c59 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/Histogram.java +++ b/src/net/sourceforge/plantuml/timingdiagram/Histogram.java @@ -50,9 +50,11 @@ import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.SymbolContext; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UStroke; @@ -242,14 +244,14 @@ public class Histogram implements TimeDrawing { return new Dimension2DDouble(width, getFullDeltaY()); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } }; } - public void setInitialState(String initialState) { + public void setInitialState(String initialState, Colors initialColors) { this.initialState = initialState; if (initialState != null) { allStates.add(initialState); diff --git a/src/net/sourceforge/plantuml/timingdiagram/Player.java b/src/net/sourceforge/plantuml/timingdiagram/Player.java index d57a1853e..0816c1849 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/Player.java +++ b/src/net/sourceforge/plantuml/timingdiagram/Player.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.color.Colors; @@ -125,6 +126,7 @@ public class Player implements TextBlock, TimeProjected { } private TimeDrawing cached; + private Colors initialColors; private TimeDrawing getTimeDrawing() { if (cached == null) { @@ -142,7 +144,7 @@ public class Player implements TextBlock, TimeProjected { } else { throw new IllegalStateException(); } - result.setInitialState(initialState); + result.setInitialState(initialState, initialColors); for (ChangeState change : changes) { result.addChange(change); } @@ -163,16 +165,17 @@ public class Player implements TextBlock, TimeProjected { return getTimeDrawing().getHeight(); } - public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) { + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { return null; } public void setState(TimeTick now, String state, String comment, Colors color) { if (now == null) { this.initialState = state; + this.initialColors = color; } else { if (state == null) { - state = ""; + throw new IllegalArgumentException(); } this.changes.add(new ChangeState(now, state, comment, color)); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/Ribbon.java b/src/net/sourceforge/plantuml/timingdiagram/Ribbon.java index 3a4a1ed72..147a5b835 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/Ribbon.java +++ b/src/net/sourceforge/plantuml/timingdiagram/Ribbon.java @@ -44,9 +44,13 @@ 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.HtmlColor; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.SymbolContext; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.color.ColorType; +import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -59,6 +63,7 @@ public class Ribbon implements TimeDrawing { private final ISkinParam skinParam; private final TimingRuler ruler; private String initialState; + private Colors initialColors; public Ribbon(TimingRuler ruler, ISkinParam skinParam) { this.ruler = ruler; @@ -103,18 +108,26 @@ public class Ribbon implements TimeDrawing { inital = null; } else { inital = getTextBlock(initialState); + final double a = getPosInPixel(changes.get(0)); drawPentaA(ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -delta / 2)), - getInitialWidth(stringBounder), changes.get(0)); + getInitialWidth(stringBounder) + a, changes.get(0)); } for (int i = 0; i < changes.size() - 1; i++) { final double a = getPosInPixel(changes.get(i)); final double b = getPosInPixel(changes.get(i + 1)); assert b > a; - drawHexa(ugDown.apply(new UTranslate(a, -delta / 2)), b - a, changes.get(i)); + if (changes.get(i).isCompletelyHidden() == false) { + drawHexa(ugDown.apply(new UTranslate(a, -delta / 2)), b - a, changes.get(i)); + } + } + if (changes.size() >= 1) { + final ChangeState last = changes.get(changes.size() - 1); + final double a = getPosInPixel(last); + if (last.isCompletelyHidden() == false) { + drawPentaB(ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a, last); + } } - final double a = getPosInPixel(changes.get(changes.size() - 1)); - drawPentaB(ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a, changes.get(changes.size() - 1)); ugDown = ugDown.apply(new UTranslate(0, delta / 2)); @@ -125,7 +138,7 @@ public class Ribbon implements TimeDrawing { for (int i = 0; i < changes.size(); i++) { final ChangeState change = changes.get(i); final double x = ruler.getPosInPixel(change.getWhen()); - if (change.isHidden() == false) { + if (change.isBlank() == false && change.isCompletelyHidden() == false) { final TextBlock state = getTextBlock(change.getState()); final Dimension2D dim = state.calculateDimension(stringBounder); final double xtext; @@ -166,7 +179,12 @@ public class Ribbon implements TimeDrawing { } private void drawPentaA(UGraphic ug, double len, ChangeState change) { - final PentaAShape shape = PentaAShape.create(len, 2 * delta, change.getContext()); + SymbolContext context = change.getContext(); + final HtmlColor back = initialColors.getColor(ColorType.BACK); + if (back != null) { + context = context.withBackColor(back); + } + final PentaAShape shape = PentaAShape.create(len, 2 * delta, context); shape.drawU(ug); } @@ -192,8 +210,9 @@ public class Ribbon implements TimeDrawing { return TextBlockUtils.empty(0, 0); } - public void setInitialState(String initialState) { + public void setInitialState(String initialState, Colors initialColors) { this.initialState = initialState; + this.initialColors = initialColors; } public void addConstraint(TimeConstraint constraint) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java b/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java index a612b4c33..5d561b69c 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java @@ -107,7 +107,7 @@ public class TimeArrow implements UDrawable { } private FontConfiguration getFontConfiguration() { - final UFont font = new UFont("Serif", Font.PLAIN, 14); + final UFont font = UFont.serif(14); return new FontConfiguration(font, HtmlColorUtils.BLUE, HtmlColorUtils.BLUE, false); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java b/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java index afa5b8b98..0b410f932 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java @@ -81,7 +81,7 @@ public class TimeConstraint { } private FontConfiguration getFontConfiguration() { - final UFont font = new UFont("Serif", Font.PLAIN, 14); + final UFont font = UFont.serif(14); return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLUE, false); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimeDrawing.java b/src/net/sourceforge/plantuml/timingdiagram/TimeDrawing.java index 885fbb03d..58230f788 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimeDrawing.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimeDrawing.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.timingdiagram; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.graphic.color.Colors; public interface TimeDrawing extends TimeProjected, UDrawable { @@ -46,7 +47,7 @@ public interface TimeDrawing extends TimeProjected, UDrawable { public TextBlock getWidthHeader(StringBounder stringBounder); - public void setInitialState(String initialState); + public void setInitialState(String initialState, Colors initialColors); public void addConstraint(TimeConstraint constraint); diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java index b920d86c3..8b84a6fba 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java @@ -56,8 +56,8 @@ public class TimingDiagramFactory extends UmlDiagramFactory { addCommonCommands(cmds); cmds.add(new CommandLifeLine()); - cmds.add(new CommandChangeState1()); - cmds.add(new CommandChangeState2()); + cmds.add(new CommandChangeStateByPlayerCode()); + cmds.add(new CommandChangeStateByTime()); cmds.add(new CommandAtTime()); cmds.add(new CommandAtPlayer()); cmds.add(new CommandTimeMessage()); diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java b/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java index 02dcd1660..625a8b7e6 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java @@ -35,8 +35,8 @@ package net.sourceforge.plantuml.timingdiagram; import java.awt.geom.Dimension2D; -import java.util.ArrayList; -import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; @@ -51,7 +51,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class TimingRuler { - private final List times = new ArrayList(); + private final SortedSet times = new TreeSet(); private int highestCommonFactor = -1; private final ISkinParam skinParam; @@ -62,16 +62,17 @@ public class TimingRuler { } public void addTime(TimeTick time) { - times.add(time); - int tick = time.getTime(); - if (tick > 0) { - if (highestCommonFactor == -1) { - highestCommonFactor = time.getTime(); - } else { - highestCommonFactor = computeHighestCommonFactor(highestCommonFactor, time.getTime()); + final boolean added = times.add(time); + if (added) { + int tick = time.getTime(); + if (tick > 0) { + if (highestCommonFactor == -1) { + highestCommonFactor = time.getTime(); + } else { + highestCommonFactor = computeHighestCommonFactor(highestCommonFactor, time.getTime()); + } } } - // System.err.println("highestCommonFactor=" + highestCommonFactor); } private FontConfiguration getFontConfiguration() { @@ -114,7 +115,7 @@ public class TimingRuler { if (times.size() == 0) { throw new IllegalStateException("Empty list!"); } - return times.get(times.size() - 1); + return times.last(); } private static int computeHighestCommonFactor(int a, int b) { diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java index f06afe9c5..cf905d8ad 100644 --- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java +++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java @@ -48,6 +48,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; +import java.util.Random; import java.util.Set; import javax.imageio.ImageIO; @@ -156,7 +157,7 @@ public class FontChecker { } private String getSvgImage(char c) throws IOException, TransformerException { - final SvgGraphics svg = new SvgGraphics(1.0, null); + final SvgGraphics svg = new SvgGraphics(1.0, null, new Random()); svg.setStrokeColor("black"); svg.svgImage(getBufferedImage(c), 0, 0); final ByteArrayOutputStream os = new ByteArrayOutputStream(); diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 1e803e842..c5f2909a8 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -46,6 +46,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.util.Random; import java.util.Set; import java.util.concurrent.Semaphore; @@ -365,7 +366,7 @@ public class ImageBuilder { return createUGraphicPNG(colorMapper, dpiFactor, dim, mybackcolor, animationArg, dx, dy); case SVG: return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor, fileFormatOption.getSvgLinkTarget(), - fileFormatOption.getHoverColor()); + fileFormatOption.getHoverColor(), fileFormatOption.getRandom()); case EPS: return new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); case EPS_TEXT: @@ -386,18 +387,20 @@ public class ImageBuilder { } private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, HtmlColor mybackcolor, - String svgLinkTarget, String hover) { + String svgLinkTarget, String hover, Random random) { Color backColor = Color.WHITE; if (mybackcolor instanceof HtmlColorSimple) { backColor = colorMapper.getMappedColor(mybackcolor); } final UGraphicSvg ug; if (mybackcolor instanceof HtmlColorGradient) { - ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, svgLinkTarget, hover); + ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, svgLinkTarget, hover, + random); } else if (backColor == null || backColor.equals(Color.WHITE)) { - ug = new UGraphicSvg(colorMapper, false, scale, svgLinkTarget, hover); + ug = new UGraphicSvg(colorMapper, false, scale, svgLinkTarget, hover, random); } else { - ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, svgLinkTarget, hover); + ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, svgLinkTarget, hover, + random); } return ug; diff --git a/src/net/sourceforge/plantuml/ugraphic/UFont.java b/src/net/sourceforge/plantuml/ugraphic/UFont.java index 8e00597bf..9852a707b 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UFont.java +++ b/src/net/sourceforge/plantuml/ugraphic/UFont.java @@ -54,6 +54,26 @@ public class UFont { this(new Font(fontFamily, fontStyle, fontSize), fontFamily); } + public static UFont serif(int size) { + return new UFont("Serif", Font.PLAIN, size); + } + + public static UFont sansSerif(int size) { + return new UFont("SansSerif", Font.PLAIN, size); + } + + public static UFont courier(int size) { + return new UFont("Courier", Font.PLAIN, size); + } + + public static UFont byDefault(int size) { + return sansSerif(12); + } + + public static UFont monospaced(int size) { + return new UFont("Monospaced", Font.PLAIN, size); + } + private UFont(Font font, String family) { this.font = font; this.family = family; @@ -73,17 +93,25 @@ public class UFont { return this; } final float current = font.getSize2D(); - return deriveSize((float) (current * scale)); + return withSize((float) (current * scale)); } - public UFont deriveSize(float size) { + public UFont withSize(float size) { return new UFont(font.deriveFont(size), family); } - public UFont deriveStyle(int style) { + public UFont withStyle(int style) { return new UFont(font.deriveFont(style), family); } + public UFont bold() { + return withStyle(Font.BOLD); + } + + public UFont italic() { + return withStyle(Font.ITALIC); + } + public int getStyle() { return font.getStyle(); } diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java index fd5651a25..d9ec5d366 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java @@ -73,9 +73,9 @@ public abstract class UGraphicUtils { } else if (fileFormat == FileFormat.SVG) { final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(colorMapper .getMappedColor(background)), false, 1.0, fileFormatOption.getSvgLinkTarget(), - fileFormatOption.getHoverColor()); + fileFormatOption.getHoverColor(), fileFormatOption.getRandom()); image.drawU(svg); - svg.createXml(os); + svg.createXml(os, fileFormatOption.isWithMetadata() ? metadata : null); } else if (fileFormat == FileFormat.EPS) { final UGraphicEps ug = new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); image.drawU(ug); diff --git a/src/net/sourceforge/plantuml/ugraphic/UImageSvg.java b/src/net/sourceforge/plantuml/ugraphic/UImageSvg.java index a973038fe..cd596df38 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UImageSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/UImageSvg.java @@ -35,45 +35,26 @@ */ package net.sourceforge.plantuml.ugraphic; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import net.sourceforge.plantuml.SvgString; public class UImageSvg implements UShape { - private final String svg; + private final SvgString svg; - public UImageSvg(String svg) { - if (svg.startsWith(""); - return "" + svg.substring(idx + 1); - } + public final SvgString getSvg() { return svg; } - private int getData(String name) { - final Pattern p = Pattern.compile("(?i)" + name + "\\W+(\\d+)"); - final Matcher m = p.matcher(svg); - if (m.find()) { - final String s = m.group(1); - return Integer.parseInt(s); - } - throw new IllegalStateException("Cannot find " + name); - } - public int getHeight() { - return getData("height"); + return svg.getData("height"); } public int getWidth() { - return getData("width"); + return svg.getData("width"); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/ULayoutGroup.java b/src/net/sourceforge/plantuml/ugraphic/ULayoutGroup.java index ba6db10df..da6e736ca 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ULayoutGroup.java +++ b/src/net/sourceforge/plantuml/ugraphic/ULayoutGroup.java @@ -38,7 +38,10 @@ package net.sourceforge.plantuml.ugraphic; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; @@ -64,9 +67,19 @@ public class ULayoutGroup { } public Rectangle2D getInnerPosition(String member, double width, double height, StringBounder stringBounder) { - for (Map.Entry ent : placementStrategy.getPositions(width, height).entrySet()) { + final Set> all = placementStrategy.getPositions(width, height).entrySet(); + Rectangle2D result = tryOne(all, member, stringBounder, InnerStrategy.STRICT); + if (result == null) { + result = tryOne(all, member, stringBounder, InnerStrategy.LAZZY); + } + return result; + } + + private Rectangle2D tryOne(final Set> all, String member, StringBounder stringBounder, + InnerStrategy mode) { + for (Map.Entry ent : all) { final TextBlock block = ent.getKey(); - final Rectangle2D result = block.getInnerPosition(member, stringBounder); + final Rectangle2D result = block.getInnerPosition(member, stringBounder, mode); if (result != null) { final UTranslate translate = new UTranslate(ent.getValue()); return translate.apply(result); diff --git a/src/net/sourceforge/plantuml/ugraphic/arc/ExtendedGeneralPath.java b/src/net/sourceforge/plantuml/ugraphic/arc/ExtendedGeneralPath.java index 7dcfa53ea..14055802b 100644 --- a/src/net/sourceforge/plantuml/ugraphic/arc/ExtendedGeneralPath.java +++ b/src/net/sourceforge/plantuml/ugraphic/arc/ExtendedGeneralPath.java @@ -70,7 +70,7 @@ import java.util.Arrays; * GeneralPath. Elliptical arc is implemented using an Arc2D in double precision. * *

- * Warning : An elliptical arc may be composed of several path segments. For futher details, see the SVG + * Warning : An elliptical arc may be composed of several path segments. For further details, see the SVG * Appendix F.6 * * @author Thierry Kormann @@ -417,7 +417,7 @@ public class ExtendedGeneralPath implements Shape, Cloneable { // Change MOVETO to LINETO. type = PathIterator.SEG_LINETO; } else { - // Redundent segment (move to current loc) drop it... + // Redundant segment (move to current loc) drop it... if (pi.isDone()) { break; // Nothing interesting } diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteSvg.java b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteSvg.java index 68f3d7e25..497687186 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteSvg.java @@ -42,6 +42,7 @@ import java.io.InputStream; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.StringBounder; @@ -54,7 +55,7 @@ public class SpriteSvg implements Sprite { private final UImageSvg img; public SpriteSvg(String svg) { - this.img = new UImageSvg(svg); + this.img = new UImageSvg(new SvgString(svg, 1)); } public SpriteSvg(File svgFile) throws IOException { diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index 3f8c0361a..2ff63acf4 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.ugraphic.svg; import java.io.IOException; import java.io.OutputStream; +import java.util.Random; import javax.xml.transform.TransformerException; @@ -81,16 +82,19 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo register(); } - public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget, String hover) { - this(colorMapper, new SvgGraphics(backcolor, scale, hover), textAsPath, linkTarget); + public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget, + String hover, Random rnd) { + this(colorMapper, new SvgGraphics(backcolor, scale, hover, rnd), textAsPath, linkTarget); } - public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget, String hover) { - this(colorMapper, new SvgGraphics(scale, hover), textAsPath, linkTarget); + public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget, String hover, + Random rnd) { + this(colorMapper, new SvgGraphics(scale, hover, rnd), textAsPath, linkTarget); } - public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale, String linkTarget, String hover) { - this(mapper, new SvgGraphics(scale, hover), textAsPath, linkTarget); + public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale, String linkTarget, + String hover, Random rnd) { + this(mapper, new SvgGraphics(scale, hover, rnd), textAsPath, linkTarget); final SvgGraphics svg = getGraphicObject(); svg.paintBackcolorGradient(mapper, gr); @@ -144,8 +148,11 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo return stringBounder; } - public void createXml(OutputStream os) throws IOException { + public void createXml(OutputStream os, String metadata) throws IOException { try { + if (metadata != null) { + getGraphicObject().addComment("\n" + metadata); + } getGraphicObject().createXml(os); } catch (TransformerException e) { throw new IOException(e.toString()); @@ -161,7 +168,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo } public void writeImageTOBEMOVED(OutputStream os, String metadata, int dpi) throws IOException { - createXml(os); + createXml(os, metadata); } @Override diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index 487f4380f..0e7f5e32f 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -52,13 +52,18 @@ import javax.imageio.ImageIO; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.OptionPrint; +import net.sourceforge.plantuml.Run; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.graphic.GraphicPosition; import net.sourceforge.plantuml.graphic.GraphicStrings; +import net.sourceforge.plantuml.preproc.Preprocessor; +import net.sourceforge.plantuml.preproc.PreprocessorInclude; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ImageBuilder; @@ -161,6 +166,12 @@ public class PSystemVersion extends AbstractPSystem { strings.add("PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")"); strings.add("(" + License.getCurrent() + " source distribution)"); strings.add("Loaded from " + Version.getJarPath()); + if (OptionFlags.getInstance().isWord()) { + strings.add("Word Mode"); + strings.add("Command Line: " + Run.getCommandLine()); + strings.add("Current Dir: " + FileSystem.getInstance().getCurrentDir().getAbsolutePath()); + strings.add("plantuml.include.path: " + PreprocessorInclude.getenv("plantuml.include.path")); + } strings.add(" "); strings.addAll(GraphvizUtils.getTestDotStrings(true)); diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 4754f5b9c..4d2d8cc6b 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -41,7 +41,7 @@ import java.util.Date; public class Version { public static int version() { - return 201708; + return 201709; } public static String versionString() { @@ -78,7 +78,7 @@ public class Version { } public static long compileTime() { - return 1490118065248L; + return 1491408431708L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/xmi/XmiClassDiagramAbstract.java b/src/net/sourceforge/plantuml/xmi/XmiClassDiagramAbstract.java index dd314ebec..7318fc9a2 100644 --- a/src/net/sourceforge/plantuml/xmi/XmiClassDiagramAbstract.java +++ b/src/net/sourceforge/plantuml/xmi/XmiClassDiagramAbstract.java @@ -145,7 +145,7 @@ abstract class XmiClassDiagramAbstract implements IXmiClassDiagram { // isAbstract="false" participant="UMLAssociationEnd.11" // isActive="false"> final Element cla = document.createElement("UML:Class"); - if (entity.getEntityType() == LeafType.NOTE) { + if (entity.getLeafType() == LeafType.NOTE) { return null; } @@ -158,7 +158,7 @@ abstract class XmiClassDiagramAbstract implements IXmiClassDiagram { cla.setAttribute("namespace", parentCode.getFullName()); } - final LeafType type = entity.getEntityType(); + final LeafType type = entity.getLeafType(); if (type == LeafType.ABSTRACT_CLASS) { cla.setAttribute("isAbstract", "true"); } else if (type == LeafType.INTERFACE) { diff --git a/src/net/sourceforge/plantuml/xmlsc/ScxmlStateDiagramStandard.java b/src/net/sourceforge/plantuml/xmlsc/ScxmlStateDiagramStandard.java index e70d3a84a..1d52208a6 100644 --- a/src/net/sourceforge/plantuml/xmlsc/ScxmlStateDiagramStandard.java +++ b/src/net/sourceforge/plantuml/xmlsc/ScxmlStateDiagramStandard.java @@ -89,7 +89,7 @@ public class ScxmlStateDiagramStandard { private String getInitial() { for (final IEntity ent : diagram.getLeafsvalues()) { - if (ent.getEntityType() == LeafType.CIRCLE_START) { + if (ent.getLeafType() == LeafType.CIRCLE_START) { return getId(ent); } } diff --git a/src/overview.html b/src/overview.html index dd3a418e5..c6a131b2a 100644 --- a/src/overview.html +++ b/src/overview.html @@ -41,7 +41,7 @@ Please refer to PlantUML site for th Here, some information about how PlantUML is implemented will be provided to help the integration of PlantUML with other programs.

-Unfortunatly, here, we have to raise a warning: +Unfortunately, here, we have to raise a warning:
While PlantUML language description remains stable over version and follow ascending compatibility, the implementation of PlantUML changes very often over time.