From f9dab4abce6df0e9b5121895cc6e94823c2dece3 Mon Sep 17 00:00:00 2001 From: Andrew Shadura Date: Thu, 21 Apr 2016 11:16:15 +0200 Subject: Imported Upstream version 8038 --- src/net/sourceforge/plantuml/FileFormat.java | 6 +- src/net/sourceforge/plantuml/FileFormatOption.java | 4 +- src/net/sourceforge/plantuml/ISkinParam.java | 4 +- src/net/sourceforge/plantuml/Option.java | 6 +- src/net/sourceforge/plantuml/OptionFlags.java | 14 +- src/net/sourceforge/plantuml/OptionPrint.java | 8 +- src/net/sourceforge/plantuml/PSystemBuilder.java | 4 +- src/net/sourceforge/plantuml/PSystemError.java | 2 +- src/net/sourceforge/plantuml/Pragma.java | 5 - src/net/sourceforge/plantuml/Run.java | 11 +- src/net/sourceforge/plantuml/SkinParam.java | 41 +- .../sourceforge/plantuml/SkinParamBackcolored.java | 13 + .../sourceforge/plantuml/SkinParamDelegator.java | 5 +- src/net/sourceforge/plantuml/SourceFileReader.java | 2 +- .../sourceforge/plantuml/SourceStringReader.java | 2 +- src/net/sourceforge/plantuml/StringUtils.java | 2 +- src/net/sourceforge/plantuml/UmlDiagram.java | 26 +- src/net/sourceforge/plantuml/UrlBuilder.java | 42 +- .../command/CommandLinkActivity.java | 4 +- .../command/CommandLinkLongActivity.java | 4 +- .../activitydiagram3/ActivityDiagram3.java | 2 +- .../activitydiagram3/InstructionRepeat.java | 17 +- .../activitydiagram3/InstructionWhile.java | 11 + .../plantuml/activitydiagram3/ftile/Swimlanes.java | 5 +- src/net/sourceforge/plantuml/ant/PlantUmlTask.java | 6 +- .../plantuml/classdiagram/ClassDiagram.java | 2 +- .../plantuml/classdiagram/ClassDiagramFactory.java | 2 + .../command/CommandHideShowSpecificStereotype.java | 67 +++ .../classdiagram/command/CommandLinkClass.java | 6 +- .../plantuml/command/CommandPragma.java | 10 +- src/net/sourceforge/plantuml/creole/AtomImg.java | 22 +- .../plantuml/creole/CommandCreoleImg.java | 15 +- .../plantuml/creole/CommandCreoleSprite.java | 3 +- .../sourceforge/plantuml/creole/PSystemCreole.java | 2 +- .../sourceforge/plantuml/creole/StripeSimple.java | 8 +- .../sourceforge/plantuml/cucadiagram/Bodier.java | 8 +- .../plantuml/cucadiagram/BodyEnhanced.java | 13 +- .../plantuml/cucadiagram/CucaDiagram.java | 18 +- .../plantuml/cucadiagram/EntityPosition.java | 119 ++++- .../plantuml/cucadiagram/GroupRoot.java | 10 - .../sourceforge/plantuml/cucadiagram/IGroup.java | 4 - .../plantuml/cucadiagram/MemberImpl.java | 4 +- .../plantuml/cucadiagram/MethodsOrFieldsArea.java | 12 +- .../plantuml/cucadiagram/Stereotype.java | 16 +- .../plantuml/cucadiagram/dot/AbstractGraphviz.java | 11 +- .../cucadiagram/dot/GraphvizLayoutStrategy.java | 61 --- .../plantuml/cucadiagram/dot/GraphvizLinux.java | 6 +- .../plantuml/cucadiagram/dot/GraphvizUtils.java | 35 +- .../plantuml/cucadiagram/dot/GraphvizWindows.java | 5 +- .../sourceforge/plantuml/cucadiagram/dot/OS.java | 51 -- .../plantuml/cucadiagram/dot/OSLinux.java | 69 --- .../plantuml/cucadiagram/dot/OSWindows.java | 97 ---- .../plantuml/cucadiagram/entity/EntityFactory.java | 17 +- .../plantuml/cucadiagram/entity/EntityImpl.java | 23 +- src/net/sourceforge/plantuml/cute/PSystemCute.java | 2 +- .../descdiagram/command/CommandLinkElement.java | 4 +- .../sourceforge/plantuml/directdot/PSystemDot.java | 2 +- .../plantuml/directdot/PSystemDotFactory.java | 2 +- .../sourceforge/plantuml/donors/PSystemDonors.java | 4 +- .../sourceforge/plantuml/eggs/PSystemAppleTwo.java | 2 +- .../sourceforge/plantuml/eggs/PSystemCharlie.java | 4 +- src/net/sourceforge/plantuml/eggs/PSystemEgg.java | 2 +- src/net/sourceforge/plantuml/eggs/PSystemLost.java | 2 +- .../sourceforge/plantuml/eggs/PSystemMemorial.java | 108 ++++ .../plantuml/eggs/PSystemMemorialFactory.java | 53 ++ src/net/sourceforge/plantuml/eggs/PSystemRIP.java | 2 +- .../plantuml/font/PSystemListFonts.java | 2 +- src/net/sourceforge/plantuml/graph/Elastane.java | 4 +- .../plantuml/graph/EntityImageActivity.java | 2 +- .../plantuml/graph/EntityImageDefault.java | 2 +- .../plantuml/graph/EntityImageNote.java | 2 +- .../plantuml/graph/EntityImageUsecase.java | 2 +- src/net/sourceforge/plantuml/graph/Graph2.java | 11 +- src/net/sourceforge/plantuml/graph/Graph3.java | 21 +- src/net/sourceforge/plantuml/graph/Graph4.java | 13 +- src/net/sourceforge/plantuml/graph/Graph5.java | 15 +- .../plantuml/graphic/DateEventUtils.java | 34 +- .../sourceforge/plantuml/graphic/QuoteUtils.java | 6 + .../sourceforge/plantuml/graphic/SingleLine.java | 2 +- src/net/sourceforge/plantuml/graphic/Splitter.java | 8 +- .../plantuml/graphic/StringBounderUtils.java | 12 +- .../plantuml/graphic/TextBlockUtils.java | 2 +- .../plantuml/graphic/USymbolComponent2.java | 11 +- .../plantuml/jdot/CucaDiagramFileMakerJDot.java | 581 +++++++++++++++++++++ src/net/sourceforge/plantuml/jdot/DebugUtils.java | 132 +++++ src/net/sourceforge/plantuml/jdot/JDotPath.java | 215 ++++++++ src/net/sourceforge/plantuml/jdot/YMirror.java | 78 +++ .../sourceforge/plantuml/jungle/PSystemTree.java | 4 +- .../plantuml/openiconic/PSystemListOpenIconic.java | 2 +- .../plantuml/openiconic/PSystemOpenIconic.java | 2 +- .../sourceforge/plantuml/oregon/PSystemOregon.java | 2 +- src/net/sourceforge/plantuml/png/MetadataTag.java | 14 +- src/net/sourceforge/plantuml/png/PngIO.java | 2 +- .../sourceforge/plantuml/png/PngIOMetadata.java | 40 +- src/net/sourceforge/plantuml/posimo/DotPath.java | 25 +- .../plantuml/posimo/GraphvizSolverB.java | 4 +- src/net/sourceforge/plantuml/salt/PSystemSalt.java | 2 +- .../plantuml/sequencediagram/Participant.java | 9 +- .../sequencediagram/command/CommandArrow.java | 2 +- .../graphic/SequenceDiagramFileMakerPuma2.java | 2 +- .../plantuml/statediagram/StateDiagram.java | 47 -- .../statediagram/command/CommandLinkState.java | 4 +- src/net/sourceforge/plantuml/svek/Bibliotekon.java | 9 + src/net/sourceforge/plantuml/svek/Cluster.java | 70 +-- .../plantuml/svek/CucaDiagramFileMakerSvek.java | 5 +- .../plantuml/svek/CucaDiagramFileMakerSvek2.java | 15 +- .../plantuml/svek/DotStringFactory.java | 74 ++- .../plantuml/svek/FrontierCalculator.java | 4 +- .../plantuml/svek/GroupPngMakerState.java | 2 +- src/net/sourceforge/plantuml/svek/Line.java | 153 +++--- src/net/sourceforge/plantuml/svek/SvekResult.java | 2 +- .../plantuml/svek/extremity/Extremity.java | 6 +- .../plantuml/svek/extremity/ExtremityArrow.java | 7 + .../svek/extremity/ExtremityArrowAndCircle.java | 7 +- .../plantuml/svek/extremity/ExtremityCircle.java | 5 + .../svek/extremity/ExtremityCircleConnect.java | 5 + .../svek/extremity/ExtremityCircleCross.java | 5 + .../plantuml/svek/extremity/ExtremityDiamond.java | 8 + .../svek/extremity/ExtremityFactorySquarre.java | 4 + .../svek/extremity/ExtremityParenthesis.java | 6 + .../svek/extremity/ExtremityParenthesis2.java | 6 + .../plantuml/svek/extremity/ExtremityPlus.java | 6 + .../plantuml/svek/extremity/ExtremitySquarre.java | 5 + .../svek/extremity/ExtremityStateLine1.java | 6 + .../svek/extremity/ExtremityStateLine2.java | 6 + .../plantuml/svek/extremity/ExtremityTriangle.java | 8 + .../plantuml/svek/extremity/MiddleCircle.java | 8 + .../svek/extremity/MiddleCircleCircled.java | 8 + .../plantuml/svek/image/EntityImageClass.java | 2 +- .../svek/image/EntityImageClassHeader2.java | 2 +- .../svek/image/EntityImageDescription.java | 2 +- .../plantuml/svek/image/EntityImageObject.java | 2 +- .../svek/image/EntityImageStateBorder.java | 44 +- .../sourceforge/plantuml/swing/ImageWindow2.java | 2 +- .../sourceforge/plantuml/tikz/TikzGraphics.java | 28 +- .../sourceforge/plantuml/ugraphic/FontChecker.java | 2 +- .../plantuml/ugraphic/ImageBuilder.java | 51 +- src/net/sourceforge/plantuml/ugraphic/UImage.java | 21 + .../plantuml/ugraphic/g2d/DriverTextAsPathG2d.java | 8 +- .../plantuml/ugraphic/g2d/DriverTextG2d.java | 8 +- .../plantuml/ugraphic/g2d/UGraphicG2d.java | 2 +- .../sprite/PSystemListInternalSprites.java | 2 +- .../plantuml/ugraphic/sprite/Sprite.java | 2 +- .../plantuml/ugraphic/sprite/SpriteImage.java | 6 +- .../plantuml/ugraphic/sprite/SpriteMonochrome.java | 7 +- .../plantuml/ugraphic/tikz/UGraphicTikz.java | 4 +- .../plantuml/version/PSystemLicense.java | 2 +- .../plantuml/version/PSystemVersion.java | 4 +- src/net/sourceforge/plantuml/version/Version.java | 6 +- src/net/sourceforge/plantuml/version/out.png | Bin 1761 -> 211538 bytes src/net/sourceforge/plantuml/webp/Portrait.java | 8 +- src/net/sourceforge/plantuml/webp/Portraits.java | 80 ++- .../plantuml/xmi/CucaDiagramXmiMaker.java | 7 +- .../plantuml/xmi/XmiClassDiagramStar.java | 18 +- .../sourceforge/plantuml/xmi/XmiStateDiagram.java | 256 +++++++++ 155 files changed, 2543 insertions(+), 938 deletions(-) create mode 100644 src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificStereotype.java delete mode 100644 src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLayoutStrategy.java delete mode 100644 src/net/sourceforge/plantuml/cucadiagram/dot/OS.java delete mode 100644 src/net/sourceforge/plantuml/cucadiagram/dot/OSLinux.java delete mode 100644 src/net/sourceforge/plantuml/cucadiagram/dot/OSWindows.java create mode 100644 src/net/sourceforge/plantuml/eggs/PSystemMemorial.java create mode 100644 src/net/sourceforge/plantuml/eggs/PSystemMemorialFactory.java create mode 100644 src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java create mode 100644 src/net/sourceforge/plantuml/jdot/DebugUtils.java create mode 100644 src/net/sourceforge/plantuml/jdot/JDotPath.java create mode 100644 src/net/sourceforge/plantuml/jdot/YMirror.java create mode 100644 src/net/sourceforge/plantuml/xmi/XmiStateDiagram.java diff --git a/src/net/sourceforge/plantuml/FileFormat.java b/src/net/sourceforge/plantuml/FileFormat.java index 7b9db72..fe8df51 100644 --- a/src/net/sourceforge/plantuml/FileFormat.java +++ b/src/net/sourceforge/plantuml/FileFormat.java @@ -43,7 +43,8 @@ import java.io.File; * */ public enum FileFormat { - PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, BASE64; + PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, + PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, LATEX_NO_PREAMBLE, BASE64; /** * Returns the file format to be used for that format. @@ -57,6 +58,9 @@ public enum FileFormat { if (this == MJPEG) { return ".avi"; } + if (this == LATEX_NO_PREAMBLE) { + return ".latex"; + } if (this == ANIMATED_GIF) { return ".gif"; } diff --git a/src/net/sourceforge/plantuml/FileFormatOption.java b/src/net/sourceforge/plantuml/FileFormatOption.java index 0527fff..8abec4f 100644 --- a/src/net/sourceforge/plantuml/FileFormatOption.java +++ b/src/net/sourceforge/plantuml/FileFormatOption.java @@ -147,7 +147,9 @@ public class FileFormatOption implements Serializable { case VDX: return new UGraphicVdx(colorMapper); case LATEX: - return new UGraphicTikz(colorMapper); + return new UGraphicTikz(colorMapper, true); + case LATEX_NO_PREAMBLE: + return new UGraphicTikz(colorMapper, false); default: throw new UnsupportedOperationException(fileFormat.toString()); } diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index 79f2c5b..c490aea 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -37,10 +37,8 @@ package net.sourceforge.plantuml; import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizLayoutStrategy; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; -import net.sourceforge.plantuml.graphic.IHtmlColorSet; import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.svek.ConditionStyle; @@ -81,7 +79,7 @@ public interface ISkinParam extends ISkinSimple { public DotSplines getDotSplines(); - public GraphvizLayoutStrategy getStrategy(); + public String getDotExecutable(); public boolean shadowing(); diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index 6cf1953..8b0d2af 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -48,6 +48,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.command.regex.MyPattern; +import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.preproc.Defines; public class Option { @@ -116,6 +117,8 @@ public class Option { setFileFormat(FileFormat.VDX); } else if (s.equalsIgnoreCase("-latex") || s.equalsIgnoreCase("-tlatex")) { setFileFormat(FileFormat.LATEX); + } else if (s.equalsIgnoreCase("-latex:nopreamble") || s.equalsIgnoreCase("-tlatex:nopreamble")) { + setFileFormat(FileFormat.LATEX_NO_PREAMBLE); } else if (s.equalsIgnoreCase("-base64") || s.equalsIgnoreCase("-tbase64")) { setFileFormat(FileFormat.BASE64); } else if (s.equalsIgnoreCase("-pdf") || s.equalsIgnoreCase("-tpdf")) { @@ -139,8 +142,7 @@ public class Option { if (i == arg.length) { continue; } - OptionFlags.getInstance().setDotExecutable( - StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); + GraphvizUtils.setDotExecutable(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); } else if (s.equalsIgnoreCase("-charset")) { i++; if (i == arg.length) { diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java index 40c80af..dd9ea78 100644 --- a/src/net/sourceforge/plantuml/OptionFlags.java +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -60,8 +60,9 @@ public class OptionFlags { static public final boolean USE_INTERFACE_EYE1 = false; static public final boolean USE_INTERFACE_EYE2 = false; static public final boolean SWI2 = false; - static public final boolean USE_COMPOUND = false; + // static public final boolean USE_COMPOUND = false; static public final boolean OMEGA_CROSSING = false; + // static public final boolean USE_JDOT = false; public void reset() { reset(false); @@ -73,7 +74,7 @@ public class OptionFlags { metadata = false; word = false; systemExit = exit; - dotExecutable = null; + GraphvizUtils.setDotExecutable(null); gui = false; quiet = false; checkDotError = false; @@ -95,7 +96,6 @@ public class OptionFlags { private boolean metadata; private boolean word; private boolean systemExit; - private String dotExecutable; private boolean gui; private boolean quiet; private boolean checkDotError; @@ -154,14 +154,6 @@ public class OptionFlags { this.systemExit = systemExit; } - public final String getDotExecutable() { - return dotExecutable; - } - - public final void setDotExecutable(String dotExecutable) { - this.dotExecutable = dotExecutable; - } - public final boolean isGui() { return gui; } diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java index 1d77cfd..1165c81 100644 --- a/src/net/sourceforge/plantuml/OptionPrint.java +++ b/src/net/sourceforge/plantuml/OptionPrint.java @@ -79,6 +79,8 @@ public class OptionPrint { System.out.println(" -thtml\t\tTo generate HTML files for class diagram"); System.out.println(" -ttxt\t\tTo generate images with ASCII art"); System.out.println(" -tutxt\t\tTo generate images with ASCII art using Unicode characters"); + System.out.println(" -tlatex\t\tTo generate images using LaTeX/Tikz format"); + System.out.println(" -tlatex:nopreamble\tTo generate images using LaTeX/Tikz format without preamble"); System.out.println(" -o[utput] \"dir\"\tTo generate images in the specified directory"); System.out.println(" -DVAR1=value\tTo set a preprocessing variable as if '!define VAR1 value' were used"); System.out.println(" -Sparam1=value\tTo set a skin parameter as if 'skinparam param1 value' were used"); @@ -91,8 +93,6 @@ public class OptionPrint { System.out.println(" -checkversion\tTo check if a newer version is available for download"); System.out.println(" -v[erbose]\t\tTo have log information"); System.out.println(" -quiet\t\tTo NOT print error message into the console"); - // Log.println(" -forcegd\t\tTo force dot to use GD PNG library"); - // Log.println(" -forcecairo\t\tTo force dot to use Cairo PNG library"); System.out.println(" -keepfiles\t\tTo NOT delete temporary files after process"); System.out.println(" -h[elp]\t\tTo display this help message"); System.out.println(" -testdot\t\tTo test the installation of graphviz"); @@ -156,11 +156,11 @@ public class OptionPrint { final int lastversion = PSystemVersion.extractDownloadableVersion(null, null); if (lastversion == -1) { System.out.println("Error"); - System.out.println("Cannot connect to http://plantuml.sourceforge.net/"); + System.out.println("Cannot connect to http://plantuml.com/"); System.out.println("Maybe you should set your proxy ?"); } else if (lastversion == 0) { System.out.println("Error"); - System.out.println("Cannot retrieve last version from http://plantuml.sourceforge.net/"); + System.out.println("Cannot retrieve last version from http://plantuml.com/"); } else { System.out.println("Last available version for download : " + lastversion); System.out.println(); diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 997f1a9..c63214f 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -35,7 +35,6 @@ package net.sourceforge.plantuml; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import net.sourceforge.plantuml.activitydiagram.ActivityDiagramFactory; @@ -55,12 +54,12 @@ import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory; import net.sourceforge.plantuml.eggs.PSystemCharlieFactory; import net.sourceforge.plantuml.eggs.PSystemEggFactory; import net.sourceforge.plantuml.eggs.PSystemLostFactory; +import net.sourceforge.plantuml.eggs.PSystemMemorialFactory; import net.sourceforge.plantuml.eggs.PSystemPathFactory; import net.sourceforge.plantuml.eggs.PSystemRIPFactory; import net.sourceforge.plantuml.flowdiagram.FlowDiagramFactory; import net.sourceforge.plantuml.font.PSystemListFontsFactory; import net.sourceforge.plantuml.jungle.PSystemTreeFactory; -import net.sourceforge.plantuml.objectdiagram.ObjectDiagramFactory; import net.sourceforge.plantuml.openiconic.PSystemListOpenIconicFactory; import net.sourceforge.plantuml.openiconic.PSystemOpenIconicFactory; import net.sourceforge.plantuml.oregon.PSystemOregonFactory; @@ -138,6 +137,7 @@ public class PSystemBuilder { factories.add(new PSystemPathFactory()); factories.add(new PSystemOregonFactory()); factories.add(new PSystemCharlieFactory()); + factories.add(new PSystemMemorialFactory()); factories.add(new PSystemProjectFactory2()); factories.add(new FlowDiagramFactory()); factories.add(new PSystemTreeFactory(DiagramType.JUNGLE)); diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java index 7c1c20f..189d7ac 100644 --- a/src/net/sourceforge/plantuml/PSystemError.java +++ b/src/net/sourceforge/plantuml/PSystemError.java @@ -116,7 +116,7 @@ public class PSystemError extends AbstractPSystem { final GraphicStrings result = GraphicStrings.createDefault(getHtmlStrings(useRed), useRed); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/Pragma.java b/src/net/sourceforge/plantuml/Pragma.java index 8bdadde..a6b3a2e 100644 --- a/src/net/sourceforge/plantuml/Pragma.java +++ b/src/net/sourceforge/plantuml/Pragma.java @@ -37,17 +37,12 @@ package net.sourceforge.plantuml; import java.util.LinkedHashMap; import java.util.Map; -import net.sourceforge.plantuml.StringUtils; - public class Pragma { private final Map values = new LinkedHashMap(); public void define(String name, String value) { values.put(name, value); - if (name.equalsIgnoreCase("graphviz_dot")) { - OptionFlags.getInstance().setDotExecutable(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value)); - } } public boolean isDefine(String name) { diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java index 1db0519..548d5fe 100644 --- a/src/net/sourceforge/plantuml/Run.java +++ b/src/net/sourceforge/plantuml/Run.java @@ -275,7 +275,16 @@ public class Run { ps.println(system.getDescription()); } } else if (option.isPipe()) { - sourceStringReader.generateImage(ps, 0, option.getFileFormatOption()); + final String result = sourceStringReader.generateImage(ps, 0, option.getFileFormatOption()); + if ("(error)".equalsIgnoreCase(result)) { + 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()); + } + } } } diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 1825de0..a25e28e 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -50,7 +50,6 @@ import net.sourceforge.plantuml.creole.CommandCreoleMonospaced; import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizLayoutStrategy; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorSetSimple; @@ -70,16 +69,25 @@ import net.sourceforge.plantuml.ugraphic.sprite.SpriteImage; public class SkinParam implements ISkinParam { + private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>"; + private static final Pattern stereoPattern = MyPattern.cmpile(stereoPatternString); + private final Map params = new HashMap(); private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM; + private String dotExecutable; + + public String getDotExecutable() { + return dotExecutable; + } + + public void setDotExecutable(String dotExecutable) { + this.dotExecutable = dotExecutable; + } public void setParam(String key, String value) { params.put(cleanForKey(key), StringUtils.trin(value)); } - private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>"; - private static final Pattern stereoPattern = MyPattern.cmpile(stereoPatternString); - public static SkinParam noShadowing() { final SkinParam result = new SkinParam(); result.setParam("shadowing", "false"); @@ -156,9 +164,11 @@ public class SkinParam implements ISkinParam { public HtmlColor getHtmlColor(ColorParam param, Stereotype stereotype, boolean clickable) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue(param.name() + "color" + stereotype.getLabel(false)); - if (value2 != null && getIHtmlColorSet().getColorIfValid(value2) != null) { - return getIHtmlColorSet().getColorIfValid(value2); + for (String s : stereotype.getMultipleLabels()) { + final String value2 = getValue(param.name() + "color" + "<<" + s + ">>"); + if (value2 != null && getIHtmlColorSet().getColorIfValid(value2) != null) { + return getIHtmlColorSet().getColorIfValid(value2); + } } } final String value = getValue(getParamName(param, clickable)); @@ -377,23 +387,6 @@ public class SkinParam implements ISkinParam { return DotSplines.SPLINES; } - public GraphvizLayoutStrategy getStrategy() { - final String value = getValue("layout"); - if ("neato".equalsIgnoreCase(value)) { - return GraphvizLayoutStrategy.NEATO; - } - if ("circo".equalsIgnoreCase(value)) { - return GraphvizLayoutStrategy.CIRCO; - } - if ("fdp".equalsIgnoreCase(value)) { - return GraphvizLayoutStrategy.FDP; - } - if ("twopi".equalsIgnoreCase(value)) { - return GraphvizLayoutStrategy.TWOPI; - } - return GraphvizLayoutStrategy.DOT; - } - public HorizontalAlignment getHorizontalAlignment(AlignParam param) { final String value; switch (param) { diff --git a/src/net/sourceforge/plantuml/SkinParamBackcolored.java b/src/net/sourceforge/plantuml/SkinParamBackcolored.java index f402327..1a31e3c 100644 --- a/src/net/sourceforge/plantuml/SkinParamBackcolored.java +++ b/src/net/sourceforge/plantuml/SkinParamBackcolored.java @@ -34,6 +34,9 @@ */ package net.sourceforge.plantuml; +import java.util.EnumMap; +import java.util.Map; + import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -83,7 +86,17 @@ public class SkinParamBackcolored extends SkinParamDelegator { } // clickable = true; } + final HtmlColor forcedColor = forced.get(param); + if (forcedColor != null) { + return forcedColor; + } return super.getHtmlColor(param, stereotype, clickable); } + private final Map forced = new EnumMap(ColorParam.class); + + public void forceColor(ColorParam param, HtmlColor color) { + forced.put(param, color); + } + } diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index 9d5c8c8..794ea2d 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml; import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; -import net.sourceforge.plantuml.cucadiagram.dot.GraphvizLayoutStrategy; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.IHtmlColorSet; @@ -98,8 +97,8 @@ public class SkinParamDelegator implements ISkinParam { return skinParam.getDotSplines(); } - public GraphvizLayoutStrategy getStrategy() { - return skinParam.getStrategy(); + public String getDotExecutable() { + return skinParam.getDotExecutable(); } public HorizontalAlignment getHorizontalAlignment(AlignParam param) { diff --git a/src/net/sourceforge/plantuml/SourceFileReader.java b/src/net/sourceforge/plantuml/SourceFileReader.java index 3b9353d..b19d3c4 100644 --- a/src/net/sourceforge/plantuml/SourceFileReader.java +++ b/src/net/sourceforge/plantuml/SourceFileReader.java @@ -197,7 +197,7 @@ public class SourceFileReader implements ISourceFileReader { OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(suggested)); - UmlDiagram.exportDiagramError2(os, t, fileFormatOption, null, blockUml.getFlashData(), + UmlDiagram.exportDiagramError(os, t, fileFormatOption, null, blockUml.getFlashData(), UmlDiagram.getFailureText2(t)); } finally { if (os != null) { diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java index 5053492..b7ee29b 100644 --- a/src/net/sourceforge/plantuml/SourceStringReader.java +++ b/src/net/sourceforge/plantuml/SourceStringReader.java @@ -129,7 +129,7 @@ public class SourceStringReader { fileFormatOption.isUseRedForError()); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, error.getBackcolor(), null, null, 0, 0, null, false); - imageBuilder.addUDrawable(error); + imageBuilder.setUDrawable(error); imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java index e43255e..ff4b425 100644 --- a/src/net/sourceforge/plantuml/StringUtils.java +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -416,7 +416,7 @@ public class StringUtils { } public static String manageGuillemet(String st) { - return st.replaceAll("\\<\\<([^<>]+)\\>\\>", "\u00AB$1\u00BB"); + return st.replaceAll("\\<\\<\\s?([^<>]+?)\\s?\\>\\>", "\u00AB$1\u00BB"); } public static String manageUnicodeNotationUplus(String s) { diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java index ed1b500..dd1adbb 100644 --- a/src/net/sourceforge/plantuml/UmlDiagram.java +++ b/src/net/sourceforge/plantuml/UmlDiagram.java @@ -240,13 +240,13 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann return new ImageDataSimple(); } - private void exportDiagramError(OutputStream os, Throwable exception, FileFormatOption fileFormat, + public void exportDiagramError(OutputStream os, Throwable exception, FileFormatOption fileFormat, String graphvizVersion) throws IOException { - exportDiagramError2(os, exception, fileFormat, getMetadata(), getFlashData(), + exportDiagramError(os, exception, fileFormat, getMetadata(), getFlashData(), getFailureText1(exception, graphvizVersion)); } - public static void exportDiagramError2(OutputStream os, Throwable exception, FileFormatOption fileFormat, + public static void exportDiagramError(OutputStream os, Throwable exception, FileFormatOption fileFormat, String metadata, String flash, List strings) throws IOException { final UFont font = new UFont("SansSerif", Font.PLAIN, 12); strings.addAll(CommandExecutionResult.getStackTrace(exception)); @@ -265,9 +265,9 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann GraphicPosition.BACKGROUND_CORNER_TOP_RIGHT); if (im == null) { - imageBuilder.addUDrawable(graphicStrings); + imageBuilder.setUDrawable(graphicStrings); } else { - imageBuilder.addUDrawable(new UDrawable() { + imageBuilder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { graphicStrings.drawU(ug); final double height = graphicStrings.calculateDimension(ug.getStringBounder()).getHeight(); @@ -279,7 +279,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann imageBuilder.writeImageTOBEMOVED(fileFormat, os); } - private String getFlashData() { + public String getFlashData() { final StringBuilder result = new StringBuilder(); final UmlSource source = getSource(); result.append(source.getPlainString()); @@ -419,4 +419,18 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann public final void setLegend(DisplayPositionned legend) { this.legend = legend; } + + private boolean useJDot; + + public void setUseJDot(boolean useJDot) { + this.useJDot = useJDot; + } + + public boolean isUseJDot() { + return useJDot; + } + + public void setDotExecutable(String dotExecutable) { + skinParam.setDotExecutable(dotExecutable); + } } diff --git a/src/net/sourceforge/plantuml/UrlBuilder.java b/src/net/sourceforge/plantuml/UrlBuilder.java index 6cf6252..f5adf0d 100644 --- a/src/net/sourceforge/plantuml/UrlBuilder.java +++ b/src/net/sourceforge/plantuml/UrlBuilder.java @@ -57,8 +57,9 @@ public class UrlBuilder { } private static final String URL_PATTERN_OLD = "\\[\\[([%g][^%g]+[%g]|[^{}%s\\]\\[]*)(?:[%s]*\\{((?:[^{}]|\\{[^{}]*\\})+)\\})?(?:[%s]*([^\\]\\[]+))?\\]\\]"; + private static final String URL_PATTERN = "\\[\\[([%g][^%g]+[%g])?([\\w\\W]*)\\]\\]"; - private static final String URL_PATTERN = "\\[\\[([%g][^%g]+[%g]|[^{}%s\\]\\[]*)(?:[%s]*\\{" + "(" + levelN(3) + private static final String URL_PATTERN_BAD = "\\[\\[([%g][^%g]+[%g]|[^{}%s\\]\\[]*)(?:[%s]*\\{" + "(" + levelN(3) + ")" + "\\})?(?:[%s]*([^\\]\\[]+))?\\]\\]"; private final String topurl; @@ -101,14 +102,41 @@ public class UrlBuilder { if (m.matches() == false) { return null; } - String url = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(m.group(1)); - if (url.startsWith("http:") == false && url.startsWith("https:") == false) { - // final String top = getSystem().getSkinParam().getValue("topurl"); - if (topurl != null) { - url = topurl + url; + // String url = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(m.group(1)); + // if (url.startsWith("http:") == false && url.startsWith("https:") == false) { + // // final String top = getSystem().getSkinParam().getValue("topurl"); + // if (topurl != null) { + // url = topurl + url; + // } + // } + + final String quotedPart = m.group(1); + final String full = m.group(2); + final int openBracket = full.indexOf('{'); + final int closeBracket = full.lastIndexOf('}'); + if (quotedPart == null) { + if (openBracket != -1 && closeBracket != -1) { + return new Url(withTopUrl(full.substring(0, openBracket)), + full.substring(openBracket + 1, closeBracket), full.substring(closeBracket + 1).trim()); + } + final int firstSpace = full.indexOf(' '); + if (firstSpace == -1) { + return new Url(full, null, null); } + return new Url(withTopUrl(full.substring(0, firstSpace)), null, full.substring(firstSpace + 1).trim()); + } + if (openBracket != -1 && closeBracket != -1) { + return new Url(withTopUrl(quotedPart), full.substring(openBracket + 1, closeBracket), full.substring( + closeBracket + 1).trim()); + } + return new Url(withTopUrl(quotedPart), null, null); + } + + private String withTopUrl(String url) { + if (url.startsWith("http:") == false && url.startsWith("https:") == false && topurl != null) { + return topurl + url; } - return new Url(url, m.group(2), m.group(3)); + return url; } public static String getRegexp() { diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java index c3072eb..2326ec9 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java @@ -84,10 +84,10 @@ public class CommandLinkActivity extends SingleLineCommand2 { new RegexLeaf("ARROW_BODY1", "([-.]+)"), // new RegexLeaf("ARROW_STYLE1", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), // new RegexLeaf("ARROW_STYLE2", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_BODY2", "([-.]*)\\>"), // new RegexLeaf("[%s]*"), // diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index f26004c..6643757 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -92,10 +92,10 @@ public class CommandLinkLongActivity extends CommandMultilines2 new RegexLeaf("ARROW_BODY1", "([-.]+)"), // new RegexLeaf("ARROW_STYLE1", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), // new RegexLeaf("ARROW_STYLE2", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_BODY2", "([-.]*)\\>"), // new RegexLeaf("[%s]*"), // diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index bbfbfdf..09d5665 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -171,7 +171,7 @@ public class ActivityDiagram3 extends UmlDiagram { final ImageBuilder imageBuilder = new ImageBuilder(skinParam.getColorMapper(), dpiFactor, getSkinParam() .getBackgroundColor(), fileFormatOption.isWithMetadata() ? getMetadata() : null, getWarningOrError(), margin, margin, getAnimation(), getSkinParam().handwritten()); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java index 9b77ad2..dd715d7 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java @@ -38,6 +38,7 @@ import java.util.Set; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileKilled; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -50,10 +51,12 @@ public class InstructionRepeat implements Instruction { private final LinkRendering nextLinkRenderer; private final Swimlane swimlane; private final HtmlColor color; + private boolean killed = false; private Display test = Display.NULL; private Display yes = Display.NULL; private Display out = Display.NULL; + private boolean testCalled = false; private LinkRendering endRepeatLinkRendering; private LinkRendering backRepeatLinkRendering; @@ -69,8 +72,13 @@ public class InstructionRepeat implements Instruction { } public Ftile createFtile(FtileFactory factory) { - return factory.repeat(swimlane, factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering), - test, yes, out, color, backRepeatLinkRendering); + final Ftile result = factory.repeat(swimlane, + factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering), test, yes, out, color, + backRepeatLinkRendering); + if (killed) { + return new FtileKilled(result); + } + return result; } public Instruction getParent() { @@ -93,9 +101,14 @@ public class InstructionRepeat implements Instruction { } this.endRepeatLinkRendering = endRepeatLinkRendering; this.backRepeatLinkRendering = backRepeatLinkRendering; + this.testCalled = true; } final public boolean kill() { + if (testCalled) { + this.killed = true; + return true; + } return repeatList.kill(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java index 69e3948..ccffa28 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java @@ -39,6 +39,7 @@ import java.util.Set; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileKilled; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileWithNoteOpale; import net.sourceforge.plantuml.cucadiagram.Display; @@ -51,10 +52,12 @@ public class InstructionWhile implements Instruction, InstructionCollection { private final Instruction parent; private final LinkRendering nextLinkRenderer; private final HtmlColor color; + private boolean killed = false; private final Display test; private Display yes; private Display out = Display.NULL; + private boolean testCalled = false; private LinkRendering endInlinkRendering; private LinkRendering afterEndwhile; private final Swimlane swimlane; @@ -94,6 +97,9 @@ public class InstructionWhile implements Instruction, InstructionCollection { if (note != null) { tmp = new FtileWithNoteOpale(tmp, note, position, skinParam, false); } + if (killed) { + return new FtileKilled(tmp); + } return tmp; } @@ -102,6 +108,10 @@ public class InstructionWhile implements Instruction, InstructionCollection { } final public boolean kill() { + if (testCalled) { + this.killed = true; + return true; + } return repeatList.kill(); } @@ -115,6 +125,7 @@ public class InstructionWhile implements Instruction, InstructionCollection { if (out == null) { throw new IllegalArgumentException(); } + this.testCalled = true; } public void afterEndwhile(LinkRendering linkRenderer) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java index 67afd0f..0b19091 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java @@ -335,7 +335,10 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock { } private void drawSeparation(UGraphic ug, double height) { - final HtmlColor color = skinParam.getHtmlColor(ColorParam.swimlaneBorder, null, false); + HtmlColor color = skinParam.getHtmlColor(ColorParam.swimlaneBorder, null, false); + if (color == null) { + color = ColorParam.swimlaneBorder.getDefaultValue(); + } final UStroke thickness = Rose.getStroke(skinParam, LineParam.swimlaneBorder, 2); ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height)); } diff --git a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java index 4c0afad..62e0536 100644 --- a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java +++ b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.GeneratedImage; import net.sourceforge.plantuml.Option; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.SourceFileReader; +import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.preproc.Defines; import org.apache.tools.ant.BuildException; @@ -300,6 +301,9 @@ public class PlantUmlTask extends Task { if ("latex".equalsIgnoreCase(s)) { option.setFileFormat(FileFormat.LATEX); } + if ("latex:nopreamble".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.LATEX_NO_PREAMBLE); + } if ("eps:text".equalsIgnoreCase(s)) { option.setFileFormat(FileFormat.EPS_TEXT); } @@ -315,7 +319,7 @@ public class PlantUmlTask extends Task { } public void setGraphvizDot(String s) { - OptionFlags.getInstance().setDotExecutable(s); + GraphvizUtils.setDotExecutable(s); } public void setNbThread(String s) { diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java index 6665202..9db21b3 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -215,7 +215,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { } final ImageBuilder imageBuilder = new ImageBuilder(getSkinParam().getColorMapper(), 1, HtmlColorUtils.WHITE, null, null, 0, 10, null, getSkinParam().handwritten()); - imageBuilder.addUDrawable(fullLayout); + imageBuilder.setUDrawable(fullLayout); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index 197ae67..7a22415 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.classdiagram.command.CommandCreateElementFull2; import net.sourceforge.plantuml.classdiagram.command.CommandCreateElementFull2.Mode; import net.sourceforge.plantuml.classdiagram.command.CommandDiamondAssociation; import net.sourceforge.plantuml.classdiagram.command.CommandHideShowSpecificClass; +import net.sourceforge.plantuml.classdiagram.command.CommandHideShowSpecificStereotype; import net.sourceforge.plantuml.classdiagram.command.CommandImport; import net.sourceforge.plantuml.classdiagram.command.CommandLayoutNewLine; import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass; @@ -91,6 +92,7 @@ public class ClassDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandRankDir()); cmds.add(new CommandNewpage(this)); + cmds.add(new CommandHideShowSpecificStereotype()); cmds.add(new CommandPage()); cmds.add(new CommandAddMethod()); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificStereotype.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificStereotype.java new file mode 100644 index 0000000..8f02c8c --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificStereotype.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.classdiagram.command; + +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.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandHideShowSpecificStereotype extends SingleLineCommand2 { + + public CommandHideShowSpecificStereotype() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("COMMAND", "(hide|show)"), // + new RegexLeaf("[%s]+"), // + new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(CucaDiagram diagram, RegexResult arg) { + + final String stereotype = arg.get("STEREOTYPE", 0); + diagram.hideOrShow(new Stereotype(stereotype), arg.get("COMMAND", 0).equalsIgnoreCase("show")); + + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index 6fe820f..48ccea2 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -86,11 +86,11 @@ final public class CommandLinkClass extends SingleLineCommand2*+^]|\\|[>\\]])?")), // @@ -525,6 +525,8 @@ final public class CommandLinkClass extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(UmlDiagram system, List arg) { - system.getPragma().define(StringUtils.goLowerCase(arg.get(0)), arg.get(1)); + final String name = StringUtils.goLowerCase(arg.get(0)); + final String value = arg.get(1); + system.getPragma().define(name, value); + if (name.equalsIgnoreCase("graphviz_dot") && value.equalsIgnoreCase("jdot")) { + system.setUseJDot(true); + } else if (name.equalsIgnoreCase("graphviz_dot")) { + system.setDotExecutable(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value)); + } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/creole/AtomImg.java b/src/net/sourceforge/plantuml/creole/AtomImg.java index 7ab4d2c..ad17211 100644 --- a/src/net/sourceforge/plantuml/creole/AtomImg.java +++ b/src/net/sourceforge/plantuml/creole/AtomImg.java @@ -61,12 +61,14 @@ public class AtomImg implements Atom { private static final String DATA_IMAGE_PNG_BASE64 = "data:image/png;base64,"; private final BufferedImage image; + private final double scale; - private AtomImg(BufferedImage image) { + private AtomImg(BufferedImage image, double scale) { this.image = image; + this.scale = scale; } - public static Atom create(String src, final ImgValign valign, final int vspace) { + 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 FontConfiguration fc = FontConfiguration.blackBlueTrue(font); @@ -74,7 +76,7 @@ public class AtomImg implements Atom { final String data = src.substring(DATA_IMAGE_PNG_BASE64.length(), src.length()); try { final byte bytes[] = Base64Coder.decode(data); - return build(src, fc, bytes); + return build(src, fc, bytes, scale); } catch (Exception e) { return AtomText.create("ERROR " + e.toString(), fc); } @@ -86,7 +88,7 @@ public class AtomImg implements Atom { // Check if valid URL if (src.startsWith("http:") || src.startsWith("https:")) { final byte image[] = getFile(src); - return build(src, fc, image); + return build(src, fc, image, scale); } return AtomText.create("(File not found: " + f + ")", fc); } @@ -98,18 +100,19 @@ public class AtomImg implements Atom { if (read == null) { return AtomText.create("(Cannot decode: " + f + ")", fc); } - return new AtomImg(ImageIO.read(f)); + return new AtomImg(ImageIO.read(f), scale); } catch (IOException e) { return AtomText.create("ERROR " + e.toString(), fc); } } - private static Atom build(String source, final FontConfiguration fc, final byte[] data) throws IOException { + private static Atom build(String source, final FontConfiguration fc, final byte[] data, double scale) + throws IOException { final BufferedImage read = ImageIO.read(new ByteArrayInputStream(data)); if (read == null) { return AtomText.create("(Cannot decode: " + source + ")", fc); } - return new AtomImg(read); + return new AtomImg(read, scale); } // Added by Alain Corbiere @@ -137,7 +140,7 @@ public class AtomImg implements Atom { // End public Dimension2D calculateDimension(StringBounder stringBounder) { - return new Dimension2DDouble(image.getWidth(), image.getHeight()); + return new Dimension2DDouble(image.getWidth() * scale, image.getHeight() * scale); } public double getStartingAltitude(StringBounder stringBounder) { @@ -146,9 +149,8 @@ public class AtomImg implements Atom { public void drawU(UGraphic ug) { // final double h = calculateDimension(ug.getStringBounder()).getHeight(); - ug.draw(new UImage(image)); + ug.draw(new UImage(image, scale)); // tileImage.drawU(ug.apply(new UTranslate(0, -h))); } - } diff --git a/src/net/sourceforge/plantuml/creole/CommandCreoleImg.java b/src/net/sourceforge/plantuml/creole/CommandCreoleImg.java index 71b1317..9a7955c 100644 --- a/src/net/sourceforge/plantuml/creole/CommandCreoleImg.java +++ b/src/net/sourceforge/plantuml/creole/CommandCreoleImg.java @@ -67,12 +67,25 @@ public class CommandCreoleImg implements Command { throw new IllegalStateException(); } String src = m.group(2); + final double scale = getScale(m.group(3)); if (src.toLowerCase().startsWith("src=")) { src = src.substring(4); } src = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(src, "\""); - stripe.addImage(src); + stripe.addImage(src, scale); return line.substring(m.group(1).length()); } + public static double getScale(String s) { + if (s == null) { + return 1; + } + final Pattern p = Pattern.compile("scale=([0-9.]+)"); + final Matcher m = p.matcher(s); + if (m.find()) { + return Double.parseDouble(m.group(1)); + } + return 1; + } + } diff --git a/src/net/sourceforge/plantuml/creole/CommandCreoleSprite.java b/src/net/sourceforge/plantuml/creole/CommandCreoleSprite.java index c3f043c..ae2e76f 100644 --- a/src/net/sourceforge/plantuml/creole/CommandCreoleSprite.java +++ b/src/net/sourceforge/plantuml/creole/CommandCreoleSprite.java @@ -66,7 +66,8 @@ public class CommandCreoleSprite implements Command { throw new IllegalStateException(); } final String src = m.group(2); - stripe.addSprite(src); + final double scale = CommandCreoleImg.getScale(m.group(3)); + stripe.addSprite(src, scale); return line.substring(m.group(1).length()); } diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreole.java b/src/net/sourceforge/plantuml/creole/PSystemCreole.java index 1ccaffe..c791cf2 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreole.java +++ b/src/net/sourceforge/plantuml/creole/PSystemCreole.java @@ -77,7 +77,7 @@ public class PSystemCreole extends AbstractPSystem { final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 0, 0, null, false); - builder.addUDrawable(sheetBlock); + builder.setUDrawable(sheetBlock); return builder.writeImageTOBEMOVED(fileFormat, os); // final Dimension2D dim = TextBlockUtils.getDimension(sheetBlock); diff --git a/src/net/sourceforge/plantuml/creole/StripeSimple.java b/src/net/sourceforge/plantuml/creole/StripeSimple.java index 96db6b3..e9207f9 100644 --- a/src/net/sourceforge/plantuml/creole/StripeSimple.java +++ b/src/net/sourceforge/plantuml/creole/StripeSimple.java @@ -138,8 +138,8 @@ public class StripeSimple implements Stripe { } } - public void addImage(String src) { - atoms.add(AtomImg.create(src, ImgValign.TOP, 0)); + public void addImage(String src, double scale) { + atoms.add(AtomImg.create(src, ImgValign.TOP, 0, scale)); } public void addSpace(int size) { @@ -150,10 +150,10 @@ public class StripeSimple implements Stripe { atoms.add(AtomText.createUrl(url, fontConfiguration)); } - public void addSprite(String src) { + public void addSprite(String src, double scale) { final Sprite sprite = skinParam.getSprite(src); if (sprite != null) { - atoms.add(new AtomSprite(sprite.asTextBlock(fontConfiguration.getColor()), fontConfiguration)); + atoms.add(new AtomSprite(sprite.asTextBlock(fontConfiguration.getColor(), scale), fontConfiguration)); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java index 54eb3cb..bc7e92c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java @@ -163,21 +163,21 @@ public class Bodier { } public TextBlock getBody(final FontParam fontParam, final ISkinParam skinParam, final boolean showMethods, - final boolean showFields) { + final boolean showFields, Stereotype stereotype) { if (type.isLikeClass() && isBodyEnhanced()) { if (showMethods || showFields) { - return new BodyEnhanced(rawBody, fontParam, skinParam, manageModifier); + return new BodyEnhanced(rawBody, fontParam, skinParam, manageModifier, stereotype); } return null; } - final MethodsOrFieldsArea fields = new MethodsOrFieldsArea(getFieldsToDisplay(), fontParam, skinParam); + final MethodsOrFieldsArea fields = new MethodsOrFieldsArea(getFieldsToDisplay(), fontParam, skinParam, stereotype); if (type == LeafType.OBJECT) { return fields.asBlockMemberImpl(); } if (type.isLikeClass() == false) { throw new UnsupportedOperationException(); } - final MethodsOrFieldsArea methods = new MethodsOrFieldsArea(getMethodsToDisplay(), fontParam, skinParam); + final MethodsOrFieldsArea methods = new MethodsOrFieldsArea(getMethodsToDisplay(), fontParam, skinParam, stereotype); if (showFields && showMethods == false) { return fields.asBlockMemberImpl(); } else if (showMethods && showFields == false) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java index 8678467..36edb69 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java @@ -71,14 +71,16 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock { private final boolean manageModifier; private final List urls = new ArrayList(); private final boolean manageUrl; + private final Stereotype stereotype; - public BodyEnhanced(List rawBody, FontParam fontParam, ISkinParam skinParam, boolean manageModifier) { + public BodyEnhanced(List rawBody, FontParam fontParam, ISkinParam skinParam, boolean manageModifier, Stereotype stereotype) { this.rawBody = new ArrayList(rawBody); + this.stereotype = stereotype; this.fontParam = fontParam; this.skinParam = skinParam; this.manageUrl = true; - this.titleConfig = new FontConfiguration(skinParam, fontParam, null); + this.titleConfig = new FontConfiguration(skinParam, fontParam, stereotype); this.lineFirst = true; this.align = HorizontalAlignment.LEFT; this.manageHorizontalLine = true; @@ -88,6 +90,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock { public BodyEnhanced(Display display, FontParam fontParam, ISkinParam skinParam, HorizontalAlignment align, Stereotype stereotype, boolean manageHorizontalLine, boolean manageModifier, boolean manageUrl) { this.manageUrl = manageUrl; + this.stereotype = stereotype; this.rawBody = new ArrayList(); for (CharSequence s : display) { this.rawBody.add(s.toString()); @@ -133,14 +136,14 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock { for (ListIterator it = rawBody.listIterator(); it.hasNext();) { final String s = it.next(); if (manageHorizontalLine && isBlockSeparator(s)) { - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align), + blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype), separator, title)); separator = s.charAt(0); title = getTitle(s, skinParam); members = new ArrayList(); } else if (CreoleParser.isTreeStart(s)) { if (members.size() > 0) { - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align), + blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype), separator, title)); } members = new ArrayList(); @@ -156,7 +159,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock { } } } - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align), separator, + blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype), separator, title)); if (blocks.size() == 1) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index de3eed1..e693b9c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -48,7 +48,6 @@ import java.util.Set; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.api.ImageDataSimple; @@ -56,7 +55,7 @@ import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.graphic.USymbol; -import net.sourceforge.plantuml.hector2.CucaDiagramFileMakerHectorC1; +import net.sourceforge.plantuml.jdot.CucaDiagramFileMakerJDot; import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.svek.CucaDiagramFileMaker; import net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek; @@ -68,8 +67,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, private int horizontalPages = 1; private int verticalPages = 1; private final Set hiddenType = new HashSet(); + private final Set hiddenStereotype = new HashSet(); - protected final EntityFactory entityFactory = new EntityFactory(hiddenType); + protected final EntityFactory entityFactory = new EntityFactory(hiddenType, hiddenStereotype); protected IGroup currentGroup = entityFactory.getRootGroup(); private boolean visibilityModifierPresent; @@ -312,7 +312,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, throw new UnsupportedOperationException(); } - final CucaDiagramFileMaker maker = OptionFlags.USE_HECTOR ? new CucaDiagramFileMakerHectorC1(this) + // final CucaDiagramFileMaker maker = OptionFlags.USE_HECTOR ? new CucaDiagramFileMakerHectorC1(this) + // : new CucaDiagramFileMakerSvek(this); + final CucaDiagramFileMaker maker = this.isUseJDot() ? new CucaDiagramFileMakerJDot(this) : new CucaDiagramFileMakerSvek(this); final ImageData result = maker.createFile(os, getDotStrings(), fileFormatOption); @@ -473,6 +475,14 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, leaf.setRemoved(!show); } + public void hideOrShow(Stereotype stereotype, boolean show) { + if (show) { + hiddenStereotype.remove(stereotype.getLabel(false)); + } else { + hiddenStereotype.add(stereotype.getLabel(false)); + } + } + public void hideOrShow(LeafType leafType, boolean show) { if (show) { hiddenType.remove(leafType); diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityPosition.java b/src/net/sourceforge/plantuml/cucadiagram/EntityPosition.java index a3728e6..dc41e86 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/EntityPosition.java +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityPosition.java @@ -34,7 +34,124 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.EnumSet; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.svek.ShapeType; +import net.sourceforge.plantuml.ugraphic.Shadowable; +import net.sourceforge.plantuml.ugraphic.UEllipse; +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 enum EntityPosition { - NORMAL, ENTRY_POINT, EXIT_POINT + NORMAL, ENTRY_POINT, EXIT_POINT, INPUT_PIN, OUTPUT_PIN, EXPANSION_INPUT, EXPANSION_OUTPUT; + + public static final double RADIUS = 6; + + public void drawSymbol(UGraphic ug, Rankdir rankdir) { + if (this == NORMAL) { + throw new IllegalStateException(); + } else if (this == ENTRY_POINT || this == EXIT_POINT) { + final Shadowable circle = new UEllipse(RADIUS * 2, RADIUS * 2); + ug.draw(circle); + if (this == EntityPosition.EXIT_POINT) { + final double xc = 0 + RADIUS + .5; + final double yc = 0 + RADIUS + .5; + final double radius = RADIUS - .5; + drawLine(ug, getPointOnCircle(xc, yc, Math.PI / 4, radius), + getPointOnCircle(xc, yc, Math.PI + Math.PI / 4, radius)); + drawLine(ug, getPointOnCircle(xc, yc, -Math.PI / 4, radius), + getPointOnCircle(xc, yc, Math.PI - Math.PI / 4, radius)); + } + } else if (this == INPUT_PIN || this == OUTPUT_PIN) { + final Shadowable rectangle = new URectangle(RADIUS * 2, RADIUS * 2); + ug.draw(rectangle); + } else if (this == EXPANSION_INPUT || this == EXPANSION_OUTPUT) { + if (rankdir == Rankdir.TOP_TO_BOTTOM) { + final Shadowable rectangle = new URectangle(RADIUS * 2 * 4, RADIUS * 2); + ug.draw(rectangle); + final ULine vline = new ULine(0, RADIUS * 2); + ug.apply(new UTranslate(RADIUS * 2, 0)).draw(vline); + ug.apply(new UTranslate(RADIUS * 2 * 2, 0)).draw(vline); + ug.apply(new UTranslate(RADIUS * 2 * 3, 0)).draw(vline); + } else { + final Shadowable rectangle = new URectangle(RADIUS * 2, RADIUS * 2 * 4); + ug.apply(new UTranslate(0, 0)).draw(rectangle); + final ULine hline = new ULine(RADIUS * 2, 0); + ug.apply(new UTranslate(0, RADIUS * 2)).draw(hline); + ug.apply(new UTranslate(0, RADIUS * 2 * 2)).draw(hline); + ug.apply(new UTranslate(0, RADIUS * 2 * 3)).draw(hline); + } + } + + } + + public Dimension2D getDimension(Rankdir rankdir) { + if (this == EXPANSION_INPUT || this == EXPANSION_OUTPUT) { + if (rankdir == Rankdir.TOP_TO_BOTTOM) { + return new Dimension2DDouble(EntityPosition.RADIUS * 2 * 4, EntityPosition.RADIUS * 2); + } + return new Dimension2DDouble(EntityPosition.RADIUS * 2, EntityPosition.RADIUS * 2 * 4); + } + return new Dimension2DDouble(EntityPosition.RADIUS * 2, EntityPosition.RADIUS * 2); + } + + private Point2D getPointOnCircle(double xc, double yc, double angle, double radius) { + final double x = xc + radius * Math.cos(angle); + final double y = yc + radius * Math.sin(angle); + return new Point2D.Double(x, y); + } + + static private void drawLine(UGraphic ug, Point2D p1, Point2D p2) { + final double dx = p2.getX() - p1.getX(); + final double dy = p2.getY() - p1.getY(); + ug.apply(new UTranslate(p1.getX(), p1.getY())).draw(new ULine(dx, dy)); + + } + + public ShapeType getShapeType() { + if (this == NORMAL) { + throw new IllegalStateException(); + } + if (this == ENTRY_POINT || this == EXIT_POINT) { + return ShapeType.CIRCLE; + } + return ShapeType.RECTANGLE; + } + + public static EntityPosition fromStereotype(String label) { + if ("<>".equalsIgnoreCase(label)) { + return ENTRY_POINT; + } + if ("<>".equalsIgnoreCase(label)) { + return EXIT_POINT; + } + if ("<>".equalsIgnoreCase(label)) { + return INPUT_PIN; + } + if ("<>".equalsIgnoreCase(label)) { + return OUTPUT_PIN; + } + if ("<>".equalsIgnoreCase(label)) { + return EXPANSION_INPUT; + } + if ("<>".equalsIgnoreCase(label)) { + return EXPANSION_OUTPUT; + } + return EntityPosition.NORMAL; + } + + public static EnumSet getInputs() { + return EnumSet.of(ENTRY_POINT, INPUT_PIN, EXPANSION_INPUT); + } + + public static EnumSet getOutputs() { + return EnumSet.of(EXIT_POINT, OUTPUT_PIN, EXPANSION_OUTPUT); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java index 71418c7..891b2d4 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java @@ -166,16 +166,6 @@ public class GroupRoot implements IGroup { } - public boolean isAutonom() { - throw new UnsupportedOperationException(); - - } - - public void setAutonom(boolean autonom) { - throw new UnsupportedOperationException(); - - } - public PackageStyle getPackageStyle() { throw new UnsupportedOperationException(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/IGroup.java b/src/net/sourceforge/plantuml/cucadiagram/IGroup.java index fc7ddb1..6287404 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/IGroup.java +++ b/src/net/sourceforge/plantuml/cucadiagram/IGroup.java @@ -58,10 +58,6 @@ public interface IGroup extends IEntity { public Code getNamespace2(); - public boolean isAutonom(); - - public void setAutonom(boolean autonom); - public PackageStyle getPackageStyle(); public void overideImage(IEntityImage img, LeafType state); diff --git a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java index 539d19b..65c74ff 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java @@ -62,7 +62,7 @@ public class MemberImpl implements Member { final Matcher mstart = pstart.matcher(tmpDisplay); if (mstart.matches()) { - if (mstart.groupCount() != 5) { + if (mstart.groupCount() != 4) { throw new IllegalStateException(); } final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); @@ -75,7 +75,7 @@ public class MemberImpl implements Member { final Matcher mend = pend.matcher(tmpDisplay); if (mend.matches()) { - if (mend.groupCount() != 5) { + if (mend.groupCount() != 4) { throw new IllegalStateException(); } final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_END); diff --git a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java index 3254e1a..4ee4b4c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java @@ -48,6 +48,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.HtmlColorUtils; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockLineBefore; @@ -59,7 +60,6 @@ import net.sourceforge.plantuml.ugraphic.PlacementStrategy; import net.sourceforge.plantuml.ugraphic.PlacementStrategyVisibility; import net.sourceforge.plantuml.ugraphic.PlacementStrategyY1Y2Center; import net.sourceforge.plantuml.ugraphic.PlacementStrategyY1Y2Left; -import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULayoutGroup; import net.sourceforge.plantuml.utils.CharHidder; @@ -78,13 +78,15 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW private final Rose rose = new Rose(); private final List members = new ArrayList(); private final HorizontalAlignment align; + private final Stereotype stereotype; - public MethodsOrFieldsArea(List members, FontParam fontParam, ISkinParam skinParam) { - this(members, fontParam, skinParam, HorizontalAlignment.LEFT); + public MethodsOrFieldsArea(List members, FontParam fontParam, ISkinParam skinParam, Stereotype stereotype) { + this(members, fontParam, skinParam, HorizontalAlignment.LEFT, stereotype); } public MethodsOrFieldsArea(List members, FontParam fontParam, ISkinParam skinParam, - HorizontalAlignment align) { + HorizontalAlignment align, Stereotype stereotype) { + this.stereotype = stereotype; this.align = align; this.skinParam = skinParam; this.fontParam = fontParam; @@ -129,7 +131,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW if (withVisibilityChar && s.startsWith("#")) { s = CharHidder.addTileAtBegin(s); } - FontConfiguration config = new FontConfiguration(skinParam, fontParam, null); + FontConfiguration config = new FontConfiguration(skinParam, fontParam, stereotype); if (m.isAbstract()) { config = config.italic(); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index db945eb..011cb27 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -123,7 +123,7 @@ public class Stereotype implements CharSequence, Hideable { this.radius = 0; this.circledFont = null; if (label.startsWith("<<$") && label.endsWith(">>")) { - this.sprite = label.substring(3, label.length() - 2); + this.sprite = label.substring(3, label.length() - 2).trim(); } else { this.sprite = null; } @@ -151,11 +151,23 @@ public class Stereotype implements CharSequence, Hideable { return null; } if (withGuillement) { - return StringUtils.manageGuillemetStrict(label); + return StringUtils.manageGuillemet(label); } return label; } + public List getMultipleLabels() { + final List result = new ArrayList(); + if (label != null) { + final Pattern p = Pattern.compile("\\<\\<\\s?([^<>]+?)\\s?\\>\\>"); + final Matcher m = p.matcher(label); + while (m.find()) { + result.add(m.group(1)); + } + } + return Collections.unmodifiableList(result); + } + public boolean isSpotted() { return character != 0; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java index b16a05e..5d4cb3f 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java @@ -39,6 +39,7 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.List; +import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; @@ -48,31 +49,31 @@ abstract class AbstractGraphviz implements Graphviz { private final File dotExe; private final String dotString; private final String[] type; + private final ISkinParam skinParam; static boolean isWindows() { return File.separatorChar == '\\'; } - AbstractGraphviz(String dotString, String... type) { + AbstractGraphviz(ISkinParam skinParam, String dotString, String... type) { if (type == null) { throw new IllegalArgumentException(); } + this.skinParam = skinParam; this.dotExe = searchDotExe(); this.dotString = dotString; this.type = type; } private File searchDotExe() { - if (OptionFlags.getInstance().getDotExecutable() == null) { + if (skinParam == null || skinParam.getDotExecutable() == null) { final String getenv = GraphvizUtils.getenvGraphvizDot(); if (getenv == null) { return specificDotExe(); } return new File(getenv); } - - return new File(OptionFlags.getInstance().getDotExecutable()); - + return new File(skinParam.getDotExecutable()); } abstract protected File specificDotExe(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLayoutStrategy.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLayoutStrategy.java deleted file mode 100644 index 8bd9c1d..0000000 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLayoutStrategy.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2017, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * This file is part of PlantUML. - * - * Licensed under The MIT License (Massachusetts Institute of Technology License) - * - * See http://opensource.org/licenses/MIT - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * Original Author: Arnaud Roques - */ -package net.sourceforge.plantuml.cucadiagram.dot; - -import java.io.File; - -import net.sourceforge.plantuml.OptionFlags; - -public enum GraphvizLayoutStrategy { - DOT, NEATO, FDP, TWOPI, CIRCO; - - public File getSystemForcedExecutable() { - return getSystemForcedDot(); - } - - private File getSystemForcedDot() { - if (OptionFlags.getInstance().getDotExecutable() == null) { - final String getenv = GraphvizUtils.getenvGraphvizDot(); - if (getenv == null) { - return null; - } - return new File(getenv); - } - - return new File(OptionFlags.getInstance().getDotExecutable()); - - } - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java index 2a17684..760d8be 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java @@ -36,10 +36,12 @@ package net.sourceforge.plantuml.cucadiagram.dot; import java.io.File; +import net.sourceforge.plantuml.ISkinParam; + class GraphvizLinux extends AbstractGraphviz { - GraphvizLinux(String dotString, String... type) { - super(dotString, type); + GraphvizLinux(ISkinParam skinParam, String dotString, String... type) { + super(skinParam, dotString, type); } @Override diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java index 9cc8e84..d43b6e0 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.StringUtils; public class GraphvizUtils { @@ -53,13 +54,22 @@ public class GraphvizUtils { return File.separatorChar == '\\'; } - @Deprecated - public static Graphviz create(String dotString, String... type) { + private static String dotExecutable; + + public static final String getDotExecutableForTest() { + return dotExecutable; + } + + public static final void setDotExecutable(String value) { + dotExecutable = value; + } + + public static Graphviz create(ISkinParam skinParam, String dotString, String... type) { final AbstractGraphviz result; if (isWindows()) { - result = new GraphvizWindows(dotString, type); + result = new GraphvizWindows(skinParam, dotString, type); } else { - result = new GraphvizLinux(dotString, type); + result = new GraphvizLinux(skinParam, dotString, type); } // if (OptionFlags.GRAPHVIZCACHE) { // return new GraphvizCached(result); @@ -67,16 +77,14 @@ public class GraphvizUtils { return result; } - // public static Graphviz create2(GraphvizLayoutStrategy strategy, String - // dotString, String... type) { - // return new AbstractGraphviz2(getOS(), strategy, dotString, type); - // } - static public File getDotExe() { return create(null, "png").getDotExe(); } public static String getenvGraphvizDot() { + if (StringUtils.isNotEmpty(dotExecutable)) { + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(dotExecutable); + } final String env = System.getProperty("GRAPHVIZ_DOT"); if (StringUtils.isNotEmpty(env)) { return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(env); @@ -205,7 +213,7 @@ public class GraphvizUtils { } static String getTestCreateSimpleFile() throws IOException { - final Graphviz graphviz2 = GraphvizUtils.create("digraph foo { test; }", "svg"); + final Graphviz graphviz2 = GraphvizUtils.create(null, "digraph foo { test; }", "svg"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ProcessState state = graphviz2.createFile3(baos); if (state.differs(ProcessState.TERMINATED_OK())) { @@ -224,11 +232,4 @@ public class GraphvizUtils { return null; } - // public static OS getOS() { - // if (isWindows()) { - // return new OSWindows(); - // } - // return new OSLinux(); - // } - } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java index 1802b32..cf22707 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.StringUtils; class GraphvizWindows extends AbstractGraphviz { @@ -87,8 +88,8 @@ class GraphvizWindows extends AbstractGraphviz { return dots.get(0); } - GraphvizWindows(String dotString, String... type) { - super(dotString, type); + GraphvizWindows(ISkinParam skinParam, String dotString, String... type) { + super(skinParam, dotString, type); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/OS.java b/src/net/sourceforge/plantuml/cucadiagram/dot/OS.java deleted file mode 100644 index a5ca99f..0000000 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/OS.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2017, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * This file is part of PlantUML. - * - * Licensed under The MIT License (Massachusetts Institute of Technology License) - * - * See http://opensource.org/licenses/MIT - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * Original Author: Arnaud Roques - */ -package net.sourceforge.plantuml.cucadiagram.dot; - -import java.io.File; - -abstract class OS { - - static boolean isWindows() { - return File.separatorChar == '\\'; - } - - abstract String getFileName(GraphvizLayoutStrategy strategy); - - abstract File getExecutable(GraphvizLayoutStrategy strategy); - - public abstract String getCommand(GraphvizLayoutStrategy strategy); - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/OSLinux.java b/src/net/sourceforge/plantuml/cucadiagram/dot/OSLinux.java deleted file mode 100644 index 05518b4..0000000 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/OSLinux.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2017, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * This file is part of PlantUML. - * - * Licensed under The MIT License (Massachusetts Institute of Technology License) - * - * See http://opensource.org/licenses/MIT - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * Original Author: Arnaud Roques - */ -package net.sourceforge.plantuml.cucadiagram.dot; - -import java.io.File; - -import net.sourceforge.plantuml.StringUtils; - -class OSLinux extends OS { - - @Override - File getExecutable(GraphvizLayoutStrategy strategy) { - final File result = strategy.getSystemForcedExecutable(); - if (result != null) { - return result; - } - final String fileName = getFileName(strategy); - final File usrLocalBin = new File("/usr/local/bin/" + fileName); - - if (usrLocalBin.exists()) { - return usrLocalBin; - } - final File usrBin = new File("/usr/bin/" + fileName); - return usrBin; - } - - @Override - String getFileName(GraphvizLayoutStrategy strategy) { - return StringUtils.goLowerCase(strategy.name()); - } - - @Override - public String getCommand(GraphvizLayoutStrategy strategy) { - return getExecutable(strategy).getAbsolutePath(); - } - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/OSWindows.java b/src/net/sourceforge/plantuml/cucadiagram/dot/OSWindows.java deleted file mode 100644 index d68ff16..0000000 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/OSWindows.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2017, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * This file is part of PlantUML. - * - * Licensed under The MIT License (Massachusetts Institute of Technology License) - * - * See http://opensource.org/licenses/MIT - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * Original Author: Arnaud Roques - */ -package net.sourceforge.plantuml.cucadiagram.dot; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import net.sourceforge.plantuml.StringUtils; - -class OSWindows extends OS { - - @Override - File getExecutable(GraphvizLayoutStrategy strategy) { - File result = strategy.getSystemForcedExecutable(); - if (result != null) { - return result; - } - result = searchInDir(new File("c:/Program Files"), strategy); - if (result != null) { - return result; - } - result = searchInDir(new File("c:/Program Files (x86)"), strategy); - return result; - } - - private File searchInDir(final File programFile, GraphvizLayoutStrategy strategy) { - if (programFile.exists() == false || programFile.isDirectory() == false) { - return null; - } - final List dots = new ArrayList(); - for (File f : programFile.listFiles(new FileFilter() { - public boolean accept(File pathname) { - return pathname.isDirectory() && pathname.getName().startsWith("Graphviz"); - } - })) { - final File result = new File(new File(f, "bin"), getFileName(strategy)); - if (result.exists() && result.canRead()) { - dots.add(result.getAbsoluteFile()); - } - } - return higherVersion(dots); - } - - static File higherVersion(List dots) { - if (dots.size() == 0) { - return null; - } - Collections.sort(dots, Collections.reverseOrder()); - return dots.get(0); - } - - @Override - String getFileName(GraphvizLayoutStrategy strategy) { - return StringUtils.goLowerCase(strategy.name()) + ".exe"; - } - - @Override - public String getCommand(GraphvizLayoutStrategy strategy) { - return "\"" + getExecutable(strategy).getAbsolutePath() + "\""; - } - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java index 3c52348..757e5ca 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java @@ -53,6 +53,7 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LongCode; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.skin.VisibilityModifier; public class EntityFactory { @@ -64,13 +65,23 @@ public class EntityFactory { private final IGroup rootGroup = new GroupRoot(this); private final Set hiddenTypes; + private final Set hiddenStereotype; - public EntityFactory(Set hiddenTypes) { + public EntityFactory(Set hiddenTypes, Set hiddenStereotype) { this.hiddenTypes = hiddenTypes; + this.hiddenStereotype = hiddenStereotype; } - public boolean isHidden(LeafType leafType) { - return hiddenTypes.contains(leafType); + public boolean isHidden(ILeaf leaf) { + if (hiddenTypes.contains(leaf.getEntityType())) { + return true; + } + final Stereotype stereotype = leaf.getStereotype(); + if (stereotype != null && hiddenStereotype.contains(stereotype.getLabel(false))) { + return true; + } + return false; + } public ILeaf createLeaf(Code code, Display display, LeafType entityType, IGroup parentContainer, diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index db33daf..8c3ff1e 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -97,8 +97,6 @@ final class EntityImpl implements ILeaf, IGroup { private GroupType groupType; - private boolean autonom = true; - // Other private boolean nearDecoration = false; private int xposition; @@ -290,14 +288,7 @@ final class EntityImpl implements ILeaf, IGroup { if (stereotype == null) { return EntityPosition.NORMAL; } - final String label = stereotype.getLabel(false); - if ("<>".equalsIgnoreCase(label)) { - return EntityPosition.ENTRY_POINT; - } - if ("<>".equalsIgnoreCase(label)) { - return EntityPosition.EXIT_POINT; - } - return EntityPosition.NORMAL; + return EntityPosition.fromStereotype(stereotype.getLabel(false)); } @@ -396,16 +387,6 @@ final class EntityImpl implements ILeaf, IGroup { return namespace2; } - public boolean isAutonom() { - checkGroup(); - return autonom; - } - - public void setAutonom(boolean autonom) { - this.autonom = autonom; - - } - public PackageStyle getPackageStyle() { checkGroup(); if (stereotype == null) { @@ -464,7 +445,7 @@ final class EntityImpl implements ILeaf, IGroup { } public boolean isHidden() { - if (entityFactory.isHidden(leafType)) { + if (entityFactory.isHidden(this)) { return true; } if (stereotype != null) { diff --git a/src/net/sourceforge/plantuml/cute/PSystemCute.java b/src/net/sourceforge/plantuml/cute/PSystemCute.java index 6de75d3..50042f5 100644 --- a/src/net/sourceforge/plantuml/cute/PSystemCute.java +++ b/src/net/sourceforge/plantuml/cute/PSystemCute.java @@ -85,7 +85,7 @@ public class PSystemCute extends AbstractPSystem { public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 10, 10, null, false); - builder.addUDrawable(root); + builder.setUDrawable(root); return builder.writeImageTOBEMOVED(fileFormat, os); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java index 2436e5f..64eb7a2 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java @@ -78,11 +78,11 @@ public class CommandLinkElement extends SingleLineCommand2 { new RegexLeaf("HEAD2", "(0\\)|<<|[<^*+#0)]|<\\||[%s]+o)?"), // new RegexLeaf("BODY1", "([-=.~]+)"), // new RegexLeaf("ARROW_STYLE1", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,bold|,hidden|,norank)*)\\])?"), + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden|,norank)*)\\])?"), new RegexLeaf("DIRECTION", "(?:(left|right|up|down|le?|ri?|up?|do?)(?=[-=.~0()]))?"), // new RegexLeaf("INSIDE", "(?:(0|\\(0\\)|\\(0|0\\))(?=[-=.~]))?"), // new RegexLeaf("ARROW_STYLE2", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,bold|,hidden|,norank)*)\\])?"), + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden|,norank)*)\\])?"), new RegexLeaf("BODY2", "([-=.~]*)"), // new RegexLeaf("HEAD1", "(\\(0|>>|[>^*+#0(]|\\|>|o[%s]+)?"), // new RegexLeaf("[%s]*"), // diff --git a/src/net/sourceforge/plantuml/directdot/PSystemDot.java b/src/net/sourceforge/plantuml/directdot/PSystemDot.java index bf60f9d..f249498 100644 --- a/src/net/sourceforge/plantuml/directdot/PSystemDot.java +++ b/src/net/sourceforge/plantuml/directdot/PSystemDot.java @@ -69,7 +69,7 @@ public class PSystemDot extends AbstractPSystem { public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final Graphviz graphviz = GraphvizUtils - .create(data, StringUtils.goLowerCase(fileFormat.getFileFormat().name())); + .create(null, data, StringUtils.goLowerCase(fileFormat.getFileFormat().name())); if (graphviz.illegalDotExe()) { final TextBlock result = GraphicStrings.createDefault(Arrays.asList("There is an issue with your Dot/Graphviz installation"), false); UGraphicUtils.writeImage(os, null, fileFormat, new ColorMapperIdentity(), HtmlColorUtils.WHITE, result); diff --git a/src/net/sourceforge/plantuml/directdot/PSystemDotFactory.java b/src/net/sourceforge/plantuml/directdot/PSystemDotFactory.java index 8177a46..8ed2a47 100644 --- a/src/net/sourceforge/plantuml/directdot/PSystemDotFactory.java +++ b/src/net/sourceforge/plantuml/directdot/PSystemDotFactory.java @@ -53,7 +53,7 @@ public class PSystemDotFactory extends PSystemBasicFactory { @Override public PSystemDot executeLine(PSystemDot system, String line) { - if (system == null && line.matches("(di)?graph\\s+\\w+\\s+\\{")) { + if (system == null && line.matches("(strict\\s+)?(di)?graph\\s+\\w+\\s+\\{")) { data = new StringBuilder(line); data.append("\n"); return new PSystemDot(data.toString()); diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index c0f6d4b..772be0b 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -59,13 +59,13 @@ import net.sourceforge.plantuml.version.PSystemVersion; public class PSystemDonors extends AbstractPSystem { - public static final String DONORS = "UDfTKa6MsZ0CtUiKNkTD3v4XBNq1PlgWxM9sWcY8m5YfxT26itNNYrMX3JPePJtfI__BlxJ5_o0FNoYIDwMBuXXty9MA57A2fQJK1oWdA6vXxbE91jZG5aDaTEP5MWUbQyIRkL2yqFXyVzUEgHqTB35Rv29KF2LieKoZvGoRFb4OOCx5VJY1UcBP1zX4wbfoPYRIgRvgsaC15gS7g7YOYMLdrj87Whf_g1S7KI5JqZ6iCjPuobDTLLhwXQxHSyvQrgbxz8CgNTzakpsyvEpZ1LujdnLGyUwep6yLTl0nt4QxZ4H1PwWk9uv-C4jifK6enwE_jQZZixw2RFekZUEWPt8OjK_vAQ_w7tawtgbopLrwHR8EiWfxzP4ly3cL6u4LxrgovXdP3ha2Uyd9XF18hIPq7shS_UWfcAhVUjIljKd-Tpb4shLcuJ5WehGdTMpsWJz7escBMSYPSzzSdVCjwMU4TURbSSMTpeEYkynbSXmFzImU7ThkoRnHHEa2h5Kl-iOiUFnf-6J5Z-TV_VbjxTK3oHysywgwwo_hGETg"; + public static final String DONORS = "UDfTKakMqp0GtFSfjFQ3GtXY2Cz9PkOvm69s7RidLgAeZIG7xBEnusAq0uxaz4hz-bTLgjna_uCSl58Wft8Rs6giuIjbCVW2Muwfyv3FetY0jOib6c1F1_H1erNFt5h8RSDEhPd2IDFp_LqwvdQqiCNaa0rGw3dH1lAucg-mxoE40TOwMuPbA6UKlOTzeAubgrRCdV0hvZlaONDv66K7ApRQgefxJr3s3_Nin49aJZeDkmGrNj9KJkM6Vg5jHCvLgsNh4TqWJAixRNk4vnHz6E75wAiC5Be-2_9xHLluvE-hRG8YeoiKuqK7DwWjjjmWb9FeRotA-gGl8nE_I-8yY4mMW_G9Fi5L_WDFvmKhsopIswIMHKR6NbpG8to9vOPXf-kMZ7f2ROQKWHbJCDu_GYi9xSSIwnyzULNq1uVojIRI_ywdG7MhDWuzHaX74iSc7_XpCfgqg0rVTUgRctE-HVuQeKgyF9rOy3p9T9UuZC-JK4_iqABfFgWt2iYTXqhueclKHay_3PyDkqd-tP_Vnjmy4FrX4g-AkxPtTpcSnPzCq2uP-SGmar2lE7kdqWluVm4JoFai"; public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java b/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java index 3aaf5f3..e8f131e 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java @@ -76,7 +76,7 @@ public class PSystemAppleTwo extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java b/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java index 16eb63c..5b5b7c7 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java @@ -62,7 +62,7 @@ public class PSystemCharlie extends AbstractPSystem { public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.BLACK, getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(new UDrawable() { + imageBuilder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { final UImage im = new UImage(image); @@ -73,7 +73,7 @@ public class PSystemCharlie extends AbstractPSystem { } public DiagramDescription getDescription() { - return new DiagramDescriptionImpl("(Version)", getClass()); + return new DiagramDescriptionImpl("(Je Suis Charlie)", getClass()); } } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java index 0090073..8dbcc7d 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java @@ -68,7 +68,7 @@ public class PSystemEgg extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemLost.java b/src/net/sourceforge/plantuml/eggs/PSystemLost.java index 974cd32..28898f7 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemLost.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemLost.java @@ -64,7 +64,7 @@ public class PSystemLost extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemMemorial.java b/src/net/sourceforge/plantuml/eggs/PSystemMemorial.java new file mode 100644 index 0000000..dece8b5 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemMemorial.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.eggs; + +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; + +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.DiagramDescriptionImpl; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.DateEventUtils; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +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; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.webp.Portrait; + +public class PSystemMemorial extends AbstractPSystem { + + private Portrait portrait; + + PSystemMemorial(Portrait portrait) { + this.portrait = portrait; + } + + public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { + final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, + getMetadata(), null, 0, 0, null, false); + imageBuilder.setUDrawable(new UDrawable() { + + public void drawU(UGraphic ug) { + final String name = portrait.getName(); + final String quote = portrait.getQuote(); + final String age = "" + portrait.getAge() + " years old"; + final UFont font = new UFont("SansSerif", Font.BOLD, 14); + final BufferedImage im = portrait.getBufferedImage(); + final FontConfiguration fc = new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, + true); + + final TextBlock top = DateEventUtils.getComment( + Arrays.asList("A thought for those who died in Paris the 13th November 2015."), + HtmlColorUtils.BLACK); + + final TextBlock tb = Display.create(name, age, quote).create(fc, HorizontalAlignment.LEFT, + new SpriteContainerEmpty()); + + top.drawU(ug); + ug = ug.apply(new UTranslate(0, top.calculateDimension(ug.getStringBounder()).getHeight() + 10)); + + ug.draw(new UImage(im)); + ug = ug.apply(new UTranslate(im.getWidth() + 10, 0)); + tb.drawU(ug); + } + }); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); + } + + public DiagramDescription getDescription() { + return new DiagramDescriptionImpl("(Memorial)", getClass()); + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemMemorialFactory.java b/src/net/sourceforge/plantuml/eggs/PSystemMemorialFactory.java new file mode 100644 index 0000000..81f5032 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemMemorialFactory.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.eggs; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.command.PSystemSingleLineFactory; +import net.sourceforge.plantuml.webp.Portrait; +import net.sourceforge.plantuml.webp.Portraits; + +public class PSystemMemorialFactory extends PSystemSingleLineFactory { + + @Override + protected AbstractPSystem executeLine(String line) { + final Portrait portrait = Portraits.getOne(line); + if (portrait != null) { + return new PSystemMemorial(portrait); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java index 45be171..0fce9a8 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java @@ -85,7 +85,7 @@ public class PSystemRIP extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/font/PSystemListFonts.java b/src/net/sourceforge/plantuml/font/PSystemListFonts.java index 656b74a..fdfe311 100644 --- a/src/net/sourceforge/plantuml/font/PSystemListFonts.java +++ b/src/net/sourceforge/plantuml/font/PSystemListFonts.java @@ -76,7 +76,7 @@ public class PSystemListFonts extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/graph/Elastane.java b/src/net/sourceforge/plantuml/graph/Elastane.java index 5d1e554..38afd95 100644 --- a/src/net/sourceforge/plantuml/graph/Elastane.java +++ b/src/net/sourceforge/plantuml/graph/Elastane.java @@ -273,9 +273,7 @@ public class Elastane { final TextBlock textBlock = Display.create(label).create( FontConfiguration.blackBlueTrue(UFont.getCurrentFont(g2d)), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - textBlock.calculateDimension(StringBounderUtils.asStringBounder(g2d)); - // textBlock.drawTOBEREMOVED(new ColorMapperIdentity(), g2d, center.getXint() - dim.getWidth() / 2, - // center.getYint() - dim.getHeight() / 2); + textBlock.calculateDimension(StringBounderUtils.asStringBounder()); } g2d.setColor(red); diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActivity.java b/src/net/sourceforge/plantuml/graph/EntityImageActivity.java index d9079c7..9381ce6 100644 --- a/src/net/sourceforge/plantuml/graph/EntityImageActivity.java +++ b/src/net/sourceforge/plantuml/graph/EntityImageActivity.java @@ -72,7 +72,7 @@ class EntityImageActivity extends AbstractEntityImage { @Override public void draw(ColorMapper colorMapper, Graphics2D g2d) { - final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder()); final int width = (int) dimTotal.getWidth(); final int height = (int) dimTotal.getHeight(); diff --git a/src/net/sourceforge/plantuml/graph/EntityImageDefault.java b/src/net/sourceforge/plantuml/graph/EntityImageDefault.java index fc30628..22e8f07 100644 --- a/src/net/sourceforge/plantuml/graph/EntityImageDefault.java +++ b/src/net/sourceforge/plantuml/graph/EntityImageDefault.java @@ -66,7 +66,7 @@ class EntityImageDefault extends AbstractEntityImage { @Override public void draw(ColorMapper colorMapper, Graphics2D g2d) { - final Dimension2D dim = textBlock.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dim = textBlock.calculateDimension(StringBounderUtils.asStringBounder()); final int width = (int) dim.getWidth(); final int height = (int) dim.getHeight(); g2d.setColor(Color.BLACK); diff --git a/src/net/sourceforge/plantuml/graph/EntityImageNote.java b/src/net/sourceforge/plantuml/graph/EntityImageNote.java index af96f55..abad386 100644 --- a/src/net/sourceforge/plantuml/graph/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/graph/EntityImageNote.java @@ -70,7 +70,7 @@ class EntityImageNote extends AbstractEntityImage { @Override public void draw(ColorMapper colorMapper, Graphics2D g2d) { - final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder()); final int width = (int) dimTotal.getWidth(); final int height = (int) dimTotal.getHeight(); diff --git a/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java b/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java index 9de8034..5edad0b 100644 --- a/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java +++ b/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java @@ -77,7 +77,7 @@ class EntityImageUsecase extends AbstractEntityImage { @Override public void draw(ColorMapper colorMapper, Graphics2D g2d) { - final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder()); // Shape ellipse = new Ellipse2D.Double(0, 0, dimTotal.getWidth(), // dimTotal.getHeight()); diff --git a/src/net/sourceforge/plantuml/graph/Graph2.java b/src/net/sourceforge/plantuml/graph/Graph2.java index 8694ad9..37425b2 100644 --- a/src/net/sourceforge/plantuml/graph/Graph2.java +++ b/src/net/sourceforge/plantuml/graph/Graph2.java @@ -47,22 +47,15 @@ import net.sourceforge.plantuml.graphic.StringBounderUtils; public class Graph2 { - final private static Graphics2D dummyGraphics2D; - private final Elastane elastane; private int widthCell; private int heightCell; - static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - dummyGraphics2D = builder.getGraphics2D(); - } - public Graph2(Board board) { board.normalize(); for (ANode n : board.getNodes()) { - final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)); + final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder()); widthCell = Math.max(widthCell, (int) dim.getWidth()); heightCell = Math.max(heightCell, (int) dim.getHeight()); } @@ -70,7 +63,7 @@ public class Graph2 { elastane = new Elastane(galaxy); for (ANode n : board.getNodes()) { - final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)); + final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder()); elastane.addBox(n, (int) dim.getWidth(), (int) dim.getHeight()); } diff --git a/src/net/sourceforge/plantuml/graph/Graph3.java b/src/net/sourceforge/plantuml/graph/Graph3.java index e254688..42ac022 100644 --- a/src/net/sourceforge/plantuml/graph/Graph3.java +++ b/src/net/sourceforge/plantuml/graph/Graph3.java @@ -68,8 +68,6 @@ import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; public class Graph3 { - final private static Graphics2D dummyGraphics2D; - private final int spaceWidth = 40; private final int spaceHeight = 40; private final int minDistBetweenPoint = 20; @@ -85,11 +83,6 @@ public class Graph3 { private int maxRow; private int maxCol; - static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - dummyGraphics2D = builder.getGraphics2D(); - } - class ANodePoint implements Pointable, XMoveable { final private ANode node; private int deltaX = 0; @@ -155,8 +148,8 @@ public class Graph3 { final Point2DInt p = nodePoint.getPosition(); final AbstractEntityImage image = getImage(nodePoint.getNode()); - int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getWidth(); - int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getHeight(); + int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder()).getWidth(); + int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder()).getHeight(); if (widthCell % 2 == 1) { widthCell++; } @@ -186,7 +179,7 @@ public class Graph3 { final double x = point.getPosition().getX(); final double y = point.getPosition().getY(); final Dimension2D dim = getImage(point.getNode()).getDimension( - StringBounderUtils.asStringBounder(dummyGraphics2D)); + StringBounderUtils.asStringBounder()); final Frame frame = new Frame(x, y, (int) dim.getWidth(), (int) dim.getHeight()); frames.put(point, frame); world.addFrame(frame); @@ -434,8 +427,8 @@ public class Graph3 { for (ANodePoint nodePoint : nodePoints.values()) { final Frame frame = frames.get(nodePoint); final AbstractEntityImage image = getImage(nodePoint.getNode()); - final double width = image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth(); - final double height = image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight(); + final double width = image.getDimension(StringBounderUtils.asStringBounder()).getWidth(); + final double height = image.getDimension(StringBounderUtils.asStringBounder()).getHeight(); g2d.translate(frame.getX() - width / 2, frame.getY() - height / 2); image.draw(new ColorMapperIdentity(), g2d); g2d.translate(-frame.getX() + width / 2, -frame.getY() + height / 2); @@ -462,8 +455,8 @@ public class Graph3 { final Point2DInt p = nodePoint.getPosition(); // Log.println("p=" + p); final AbstractEntityImage image = getImage(nodePoint.getNode()); - final int width = (int) (image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth()); - final int height = (int) (image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight()); + final int width = (int) (image.getDimension(StringBounderUtils.asStringBounder()).getWidth()); + final int height = (int) (image.getDimension(StringBounderUtils.asStringBounder()).getHeight()); g2d.translate(p.getXint() - width / 2, p.getYint() - height / 2); image.draw(new ColorMapperIdentity(), g2d); g2d.translate(-p.getXint() + width / 2, -p.getYint() + height / 2); diff --git a/src/net/sourceforge/plantuml/graph/Graph4.java b/src/net/sourceforge/plantuml/graph/Graph4.java index 82796ec..c5c97dd 100644 --- a/src/net/sourceforge/plantuml/graph/Graph4.java +++ b/src/net/sourceforge/plantuml/graph/Graph4.java @@ -64,8 +64,6 @@ import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; public class Graph4 { - final private static Graphics2D dummyGraphics2D; - private final int spaceWidth = 40; private final int spaceHeight = 40; @@ -81,11 +79,6 @@ public class Graph4 { private int addedWidth = 0; private int addedHeight = 0; - static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - dummyGraphics2D = builder.getGraphics2D(); - } - class ANodePoint implements Pointable, XMoveable { final private ANode node; private int deltaX = 0; @@ -129,8 +122,8 @@ public class Graph4 { final Point2DInt p = nodePoint.getPosition(); final AbstractEntityImage image = getImage(nodePoint.getNode()); - int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getWidth(); - int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getHeight(); + int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder()).getWidth(); + int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder()).getHeight(); if (widthCell % 2 == 1) { widthCell++; } @@ -156,7 +149,7 @@ public class Graph4 { final double x = point.getPosition().getX(); final double y = point.getPosition().getY(); final Dimension2D dim = getImage(point.getNode()).getDimension( - StringBounderUtils.asStringBounder(dummyGraphics2D)); + StringBounderUtils.asStringBounder()); final int width = (int) dim.getWidth(); final int height = (int) dim.getHeight(); final Frame frame = new Frame(x - width / 2, y - height / 2, width, height); diff --git a/src/net/sourceforge/plantuml/graph/Graph5.java b/src/net/sourceforge/plantuml/graph/Graph5.java index b691eb0..f521ce4 100644 --- a/src/net/sourceforge/plantuml/graph/Graph5.java +++ b/src/net/sourceforge/plantuml/graph/Graph5.java @@ -58,8 +58,6 @@ import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; public class Graph5 { - final private static Graphics2D dummyGraphics2D; - private final int spaceWidth = 40; private final int spaceHeight = 40; @@ -74,11 +72,6 @@ public class Graph5 { // private final IInflationTransform inflationTransform = new // IdentityInflationTransform(); - static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - dummyGraphics2D = builder.getGraphics2D(); - } - private AbstractEntityImage getImage(ANode n) { return new EntityImageFactory().createEntityImage((IEntity) n.getUserData()); } @@ -96,9 +89,9 @@ public class Graph5 { for (ANode n : board.getNodes()) { final AbstractEntityImage image = getImage(n); final Point2D.Double pos = getPosition(n); - final int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)) + final int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder()) .getWidth() + 20; - final int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)) + final int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder()) .getHeight() + 20; inflationTransform.addInflationX(pos.getX(), widthCell); inflationTransform.addInflationY(pos.getY(), heightCell); @@ -137,8 +130,8 @@ public class Graph5 { final AbstractEntityImage image = getImage(n); Point2D pos = getPosition(n); pos = inflationTransform.inflatePoint2D(pos); - final double x = pos.getX() - image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth() / 2; - final double y = pos.getY() - image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight() / 2; + final double x = pos.getX() - image.getDimension(StringBounderUtils.asStringBounder()).getWidth() / 2; + final double y = pos.getY() - image.getDimension(StringBounderUtils.asStringBounder()).getHeight() / 2; g2d.translate(x, y); image.draw(new ColorMapperIdentity(), g2d); g2d.translate(-x, -y); diff --git a/src/net/sourceforge/plantuml/graphic/DateEventUtils.java b/src/net/sourceforge/plantuml/graphic/DateEventUtils.java index a29b1a1..cbecc95 100644 --- a/src/net/sourceforge/plantuml/graphic/DateEventUtils.java +++ b/src/net/sourceforge/plantuml/graphic/DateEventUtils.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.graphic; import java.awt.Font; import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; @@ -46,6 +45,7 @@ import java.util.List; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.ugraphic.LimitFinder; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; @@ -57,8 +57,8 @@ import net.sourceforge.plantuml.webp.Portraits; public class DateEventUtils { public static TextBlock addEvent(TextBlock textBlock, HtmlColor color) { - final DateFormat dateFormat = new SimpleDateFormat("MM-dd"); - final String today = dateFormat.format(new Date()); + final String today = new SimpleDateFormat("MM-dd").format(new Date()); + final String todayDayOfWeek = new SimpleDateFormat("MM-dd-u").format(new Date()); if ("11-05".equals(today)) { final List asList = Arrays.asList("November 5th, 1955", @@ -74,16 +74,16 @@ public class DateEventUtils { "a character on a keyboard and seen it show up on their", "own computer's screen right in front of them.\"", "\t\t\t\t\t\t\t\t\t\tSteve Wozniak"); return TextBlockUtils.mergeTB(textBlock, getComment(asList, color), HorizontalAlignment.LEFT); - } else if ("01-07".equals(today)) { + } else if ("01-07".equals(today) || "01-08-1".equals(todayDayOfWeek)) { return addCharlie(textBlock); + } else if ("11-13".equals(today) || "11-14-1".equals(todayDayOfWeek)) { + return addMemorial(textBlock, color); } - - // return addMemorial(textBlock, color); return textBlock; } private static TextBlock addMemorial(TextBlock textBlock, HtmlColor color) { - final Portrait portrait = new Portraits().getOne(); + final Portrait portrait = Portraits.getOne(); if (portrait == null) { return textBlock; } @@ -92,21 +92,27 @@ public class DateEventUtils { return textBlock; } - final List asList = Arrays.asList("A thought for those who died in Paris the 13th November 2015."); - final String name = portrait.getName(); + final String quote = portrait.getQuote(); + final String age = "" + portrait.getAge() + " years old"; final UFont font = new UFont("SansSerif", Font.BOLD, 12); - TextBlock comment = Display.create(name).create(new FontConfiguration(font, color, HtmlColorUtils.BLUE, true), - HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - comment = TextBlockUtils.withMargin(comment, 4, 4); + TextBlock comment = Display.create(name, age, quote).create( + new FontConfiguration(font, color, HtmlColorUtils.BLUE, true), HorizontalAlignment.LEFT, + new SpriteContainerEmpty()); + comment = TextBlockUtils.withMinWidth(TextBlockUtils.withMargin(comment, 4, 4), 800, HorizontalAlignment.LEFT); - final TextBlock bottom0 = getComment(asList, color); + final TextBlock bottom0 = getComment( + Arrays.asList("A thought for those who died in Paris the 13th November 2015."), color); final TextBlock bottom1 = new AbstractTextBlock() { private double margin = 10; public void drawU(UGraphic ug) { ug = ug.apply(new UTranslate(0, margin)); ug.draw(new UImage(im)); + if (ug instanceof LimitFinder) { + return; + } + Portraits.nextOne(); } public Dimension2D calculateDimension(StringBounder stringBounder) { @@ -134,7 +140,7 @@ public class DateEventUtils { } - private static TextBlock getComment(final List asList, HtmlColor color) { + public static TextBlock getComment(final List asList, HtmlColor color) { final UFont font = new UFont("SansSerif", Font.BOLD, 14); TextBlock comment = Display.create(asList).create( new FontConfiguration(font, color, HtmlColorUtils.BLUE, true), HorizontalAlignment.LEFT, diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index 65a5655..c1960f2 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -169,6 +169,12 @@ public class QuoteUtils { "We shall never surrender", // "Absolute honesty isn't always the most diplomatic nor the safest form of communication with emotional beings.", // "Humor: seventy-five percent. [Confirmed] Self destruct sequence in T minus 10, 9... " // + // It's... complicated. + // Do not open until 1985 + // I still mess up but I'll just start again + // I won't give up, no I won't give in; Till I reach the end; And then I'll start again + // I wanna try even though I could fail + // Sometimes we come last but we did our best ); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/graphic/SingleLine.java b/src/net/sourceforge/plantuml/graphic/SingleLine.java index 0b904c2..f9b829d 100644 --- a/src/net/sourceforge/plantuml/graphic/SingleLine.java +++ b/src/net/sourceforge/plantuml/graphic/SingleLine.java @@ -72,7 +72,7 @@ class SingleLine extends AbstractTextBlock implements Line { } else if (cmd instanceof SpriteCommand) { final Sprite sprite = spriteContainer.getSprite(((SpriteCommand) cmd).getSprite()); if (sprite != null) { - blocs.add(sprite.asTextBlock(fontConfiguration.getColor())); + blocs.add(sprite.asTextBlock(fontConfiguration.getColor(), 1)); } } else if (cmd instanceof FontChange) { fontConfiguration = ((FontChange) cmd).apply(fontConfiguration); diff --git a/src/net/sourceforge/plantuml/graphic/Splitter.java b/src/net/sourceforge/plantuml/graphic/Splitter.java index ea1c2f7..649b1cf 100644 --- a/src/net/sourceforge/plantuml/graphic/Splitter.java +++ b/src/net/sourceforge/plantuml/graphic/Splitter.java @@ -56,12 +56,14 @@ public class Splitter { static final String fontSup = "\\"; static final String fontSub = "\\"; static final String imgPattern = "\\]+[%q%g]?[%s]*|vspace\\s*=\\s*[%q%g]?\\d+[%q%g]?\\s*|valign[%s]*=[%s]*[%q%g]?(top|middle|bottom)[%q%g]?[%s]*)+\\>"; - public static final String imgPatternNoSrcColon = "\\]+)/?\\>"; + public static final String imgPatternNoSrcColon = "\\{}]+)" + "(\\{scale=(?:[0-9.]+)\\})?" + "\\>"; public static final String fontFamilyPattern = "\\]+)/?\\>"; public static final String svgAttributePattern = "\\]+)/?\\>"; public static final String openiconPattern = "\\<&([-\\w]+)\\>"; - public static final String spritePattern = "\\<\\$" + SpriteUtils.SPRITE_NAME + "\\>"; - public static final String spritePattern2 = "\\<\\$(" + SpriteUtils.SPRITE_NAME + ")\\>"; + public static final String spritePattern = "\\<\\$" + SpriteUtils.SPRITE_NAME + "(?:\\{scale=(?:[0-9.]+)\\})?" + + "\\>"; + public static final String spritePattern2 = "\\<\\$(" + SpriteUtils.SPRITE_NAME + ")" + + "(\\{scale=(?:[0-9.]+)\\})?" + "\\>"; static final String htmlTag; static final String linkPattern = "\\[\\[([^\\[\\]]+)\\]\\]"; diff --git a/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java b/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java index 66244dc..5486a4e 100644 --- a/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java +++ b/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java @@ -38,18 +38,22 @@ import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ugraphic.UFont; public class StringBounderUtils { - public static StringBounder asStringBounder(final Graphics2D g2d) { - + final static BufferedImage imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); + final static Graphics2D gg = imDummy.createGraphics(); + + public static StringBounder asStringBounder() { + return new StringBounder() { public Dimension2D calculateDimension(UFont font, String text) { - final FontMetrics fm = g2d.getFontMetrics(font.getFont()); - final Rectangle2D rect = fm.getStringBounds(text, g2d); + final FontMetrics fm = gg.getFontMetrics(font.getFont()); + final Rectangle2D rect = fm.getStringBounds(text, gg); return new Dimension2DDouble(rect.getWidth(), rect.getHeight()); } }; diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java index a4983a8..8dd7361 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -102,7 +102,7 @@ public class TextBlockUtils { static { final BufferedImage imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); gg = imDummy.createGraphics(); - dummyStringBounder = StringBounderUtils.asStringBounder(gg); + dummyStringBounder = StringBounderUtils.asStringBounder(); } public static boolean isEmpty(TextBlock text) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java b/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java index 398febc..3174ba8 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java @@ -82,7 +82,7 @@ class USymbolComponent2 extends USymbol { ug = symbolContext.apply(ug); drawNode(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing()); final Margin margin = getMargin(); - + final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, HorizontalAlignment.CENTER); tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1()))); // label.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1()))); @@ -96,7 +96,7 @@ class USymbolComponent2 extends USymbol { }; } - public TextBlock asBig(final TextBlock title, TextBlock stereotype, final double width, final double height, + public TextBlock asBig(final TextBlock title, final TextBlock stereotype, final double width, final double height, final SymbolContext symbolContext) { return new AbstractTextBlock() { @@ -104,7 +104,12 @@ class USymbolComponent2 extends USymbol { final Dimension2D dim = calculateDimension(ug.getStringBounder()); ug = symbolContext.apply(ug); drawNode(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing()); - title.drawU(ug.apply(new UTranslate(3, 13))); + final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder()); + final double posStereo = (width - dimStereo.getWidth()) / 2; + stereotype.drawU(ug.apply(new UTranslate(posStereo, 13))); + final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); + final double posTitle = (width - dimTitle.getWidth()) / 2; + title.drawU(ug.apply(new UTranslate(posTitle, 13 + dimStereo.getHeight()))); } public Dimension2D calculateDimension(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java new file mode 100644 index 0000000..554a1d3 --- /dev/null +++ b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java @@ -0,0 +1,581 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.jdot; + +import static gen.lib.cgraph.attr__c.agsafeset; +import static gen.lib.cgraph.edge__c.agedge; +import static gen.lib.cgraph.graph__c.agopen; +import static gen.lib.cgraph.node__c.agnode; +import static gen.lib.cgraph.subg__c.agsubg; +import static gen.lib.gvc.gvc__c.gvContext; +import static gen.lib.gvc.gvlayout__c.gvLayoutJobs; +import h.Agedge_s; +import h.Agnode_s; +import h.Agnodeinfo_t; +import h.Agraph_s; +import h.Agraphinfo_t; +import h.GVC_s; +import h.boxf; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.api.ImageDataSimple; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.EntityPortion; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +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.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.QuoteUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockEmpty; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.TextBlockWidth; +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.graphic.USymbol; +import net.sourceforge.plantuml.graphic.color.ColorType; +import net.sourceforge.plantuml.svek.Bibliotekon; +import net.sourceforge.plantuml.svek.Cluster; +import net.sourceforge.plantuml.svek.ColorSequence; +import net.sourceforge.plantuml.svek.CucaDiagramFileMaker; +import net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek2; +import net.sourceforge.plantuml.svek.DotStringFactory; +import net.sourceforge.plantuml.svek.GraphvizCrash; +import net.sourceforge.plantuml.svek.IEntityImage; +import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UStroke; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.ugraphic.sprite.Sprite; +import smetana.core.CString; +import smetana.core.JUtils; +import smetana.core.Macro; +import smetana.core.Z; +import smetana.core.__ptr__; +import smetana.core.__struct__; + +public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker { + + private final CucaDiagram diagram; + + private final StringBounder stringBounder = TextBlockUtils.getDummyStringBounder(); + private final Map nodes = new LinkedHashMap(); + private final Map edges = new LinkedHashMap(); + private final Map clusters = new LinkedHashMap(); + private Map emptyGroups = new HashMap(); + + private final DotStringFactory dotStringFactory; + + class Drawing implements UDrawable { + + private final YMirror ymirror; + + public Drawing(YMirror ymirror) { + this.ymirror = ymirror; + } + + public void drawU(UGraphic ug) { + + for (Map.Entry ent : clusters.entrySet()) { + drawGroup(ug, ymirror, ent.getKey(), ent.getValue()); + } + + for (Map.Entry ent : nodes.entrySet()) { + final ILeaf leaf = ent.getKey(); + final Agnode_s node = ent.getValue(); + final Point2D corner = getCorner(node); + + final Shape shape = dotStringFactory.getBibliotekon().getShape(leaf); + final IEntityImage image = shape.getImage(); + image.drawU(ug.apply(new UTranslate(corner))); + } + + for (Map.Entry ent : edges.entrySet()) { + final Link link = ent.getKey(); + final Agedge_s edge = ent.getValue(); + new JDotPath(link, edge, ymirror, diagram, getLabel(link)).drawU(ug); + } + } + + private Point2D getCorner(Agnode_s n) { + final Agnodeinfo_t data = (Agnodeinfo_t) Macro.AGDATA(n).castTo(Agnodeinfo_t.class); + final double width = data.getDouble("width") * 72; + final double height = data.getDouble("height") * 72; + final double x = data.getStruct("coord").getDouble("x"); + final double y = data.getStruct("coord").getDouble("y"); + + if (ymirror == null) { + return new Point2D.Double(x - width / 2, y - height / 2); + } + return ymirror.getMirrored(new Point2D.Double(x - width / 2, y + height / 2)); + } + + } + + public CucaDiagramFileMakerJDot(CucaDiagram diagram) { + this.diagram = diagram; + this.dotStringFactory = new DotStringFactory(new ColorSequence(), stringBounder, diagram); + + printGroups(diagram.getRootGroup()); + printEntities(getUnpackagedEntities()); + + } + + public void drawGroup(UGraphic ug, YMirror ymirror, IGroup group, Agraph_s gr) { + JUtils.LOG2("drawGroup"); + final __ptr__ data = Macro.AGDATA(gr).castTo(Agraphinfo_t.class); + final __struct__ bb = data.getStruct("bb"); + final double llx = bb.getStruct("LL").getDouble("x"); + double lly = bb.getStruct("LL").getDouble("y"); + final double urx = bb.getStruct("UR").getDouble("x"); + double ury = bb.getStruct("UR").getDouble("y"); + if (ymirror != null) { + final double tmpUry = ury; + ury = ymirror.getMirrored(lly); + lly = ymirror.getMirrored(tmpUry); + } + + final Cluster cluster = dotStringFactory.getBibliotekon().getCluster(group); + cluster.setPosition(llx, lly, urx, ury); + JUtils.LOG2("cluster=" + cluster); + // ug.apply(new UTranslate(llx, lly)).apply(new UChangeColor(HtmlColorUtils.BLUE)) + // .draw(new URectangle(urx - llx, ury - lly)); + cluster.drawU(ug, new UStroke(1.5), diagram.getUmlDiagramType(), diagram.getSkinParam()); + } + + private void printGroups(IGroup parent) { + for (IGroup g : diagram.getChildrenGroups(parent)) { + if (g.isRemoved()) { + continue; + } + if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) { + final ILeaf folder = diagram.getEntityFactory().createLeaf(g.getCode(), g.getDisplay(), + LeafType.EMPTY_PACKAGE, g.getParentContainer(), null, diagram.getNamespaceSeparator()); + emptyGroups.put(g, folder); + final USymbol symbol = g.getUSymbol(); + folder.setUSymbol(symbol); + folder.setStereotype(g.getStereotype()); + if (g.getColors(diagram.getSkinParam()).getColor(ColorType.BACK) == null) { + final ColorParam param = symbol == null ? ColorParam.packageBackground : symbol.getColorParamBack(); + final HtmlColor c1 = diagram.getSkinParam().getHtmlColor(param, g.getStereotype(), false); + folder.setSpecificColorTOBEREMOVED(ColorType.BACK, c1 == null ? diagram.getSkinParam() + .getBackgroundColor() : c1); + } else { + folder.setSpecificColorTOBEREMOVED(ColorType.BACK, + g.getColors(diagram.getSkinParam()).getColor(ColorType.BACK)); + } + printEntityNew(folder); + } else { + printGroup(g); + } + } + } + + private void printGroup(IGroup g) { + if (g.getGroupType() == GroupType.CONCURRENT_STATE) { + return; + } + int titleAndAttributeWidth = 0; + int titleAndAttributeHeight = 0; + + final TextBlock title = getTitleBlock(g); + final TextBlock stereo = getStereoBlock(g); + final TextBlock stereoAndTitle = TextBlockUtils.mergeTB(stereo, title, HorizontalAlignment.CENTER); + final Dimension2D dimLabel = stereoAndTitle.calculateDimension(stringBounder); + if (dimLabel.getWidth() > 0) { + final List members = ((IEntity) g).getBodier().getFieldsToDisplay(); + final TextBlockWidth attribute; + if (members.size() == 0) { + attribute = new TextBlockEmpty(); + } else { + attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, diagram.getSkinParam(), + g.getStereotype()); + } + final Dimension2D dimAttribute = attribute.calculateDimension(stringBounder); + final double attributeHeight = dimAttribute.getHeight(); + final double attributeWidth = dimAttribute.getWidth(); + final double marginForFields = attributeHeight > 0 ? IEntityImage.MARGIN : 0; + final USymbol uSymbol = g.getUSymbol(); + final int suppHeightBecauseOfShape = uSymbol == null ? 0 : uSymbol.suppHeightBecauseOfShape(); + final int suppWidthBecauseOfShape = uSymbol == null ? 0 : uSymbol.suppWidthBecauseOfShape(); + + titleAndAttributeWidth = (int) Math.max(dimLabel.getWidth(), attributeWidth) + suppWidthBecauseOfShape; + titleAndAttributeHeight = (int) (dimLabel.getHeight() + attributeHeight + marginForFields + suppHeightBecauseOfShape); + } + + dotStringFactory.openCluster(g, titleAndAttributeWidth, titleAndAttributeHeight, title, stereo); + this.printEntities(g.getLeafsDirect()); + + printGroups(g); + + dotStringFactory.closeCluster(); + } + + private void printEntities(Collection entities2) { + for (ILeaf ent : entities2) { + if (ent.isRemoved()) { + continue; + } + printEntity(ent); + } + } + + private void exportEntities(Agraph_s g, Collection entities2) { + for (ILeaf ent : entities2) { + if (ent.isRemoved()) { + continue; + } + exportEntity(g, ent); + } + } + + private void exportEntity(Agraph_s g, ILeaf leaf) { + final Shape shape = dotStringFactory.getBibliotekon().getShape(leaf); + final Agnode_s node = agnode(g, new CString(shape.getUid()), true); + agsafeset(node, new CString("shape"), new CString("box"), new CString("")); + final String width = "" + (shape.getWidth() / 72); + final String height = "" + (shape.getHeight() / 72); + agsafeset(node, new CString("width"), new CString(width), new CString("")); + agsafeset(node, new CString("height"), new CString(height), new CString("")); + System.err.println("NODE " + leaf.getUid() + " " + width + " " + height); + nodes.put(leaf, node); + } + + private void printEntity(ILeaf ent) { + if (ent.isRemoved()) { + throw new IllegalStateException(); + } + 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.addShape(shape); + getBibliotekon().putShape(ent, shape); + } + + private TextBlock getTitleBlock(IGroup g) { + final Display label = g.getDisplay(); + if (label == null) { + return TextBlockUtils.empty(0, 0); + } + + final ISkinParam skinParam = diagram.getSkinParam(); + final FontConfiguration fontConfiguration = g.getFontConfigurationForTitle(skinParam); + return label.create(fontConfiguration, HorizontalAlignment.CENTER, skinParam); + } + + private TextBlock getStereoBlock(IGroup g) { + final Stereotype stereotype = g.getStereotype(); + if (stereotype == null) { + return TextBlockUtils.empty(0, 0); + } + if (stereotype.getSprite() != null) { + final Sprite tmp = diagram.getSkinParam().getSprite(stereotype.getSprite()); + if (tmp != null) { + return tmp.asTextBlock(stereotype.getHtmlColor(), 1); + } + } + final List stereos = stereotype.getLabels(diagram.getSkinParam().useGuillemet()); + if (stereos == null) { + return TextBlockUtils.empty(0, 0); + } + final boolean show = diagram.showPortion(EntityPortion.STEREOTYPE, g); + if (show == false) { + return TextBlockUtils.empty(0, 0); + } + + final FontParam fontParam = FontParam.PACKAGE_STEREOTYPE; + return Display.create(stereos).create(new FontConfiguration(diagram.getSkinParam(), fontParam, stereotype), + HorizontalAlignment.CENTER, diagram.getSkinParam()); + } + + private Collection getUnpackagedEntities() { + final List result = new ArrayList(); + for (ILeaf ent : diagram.getLeafsvalues()) { + if (diagram.getEntityFactory().getRootGroup() == ent.getParentContainer()) { + result.add(ent); + } + } + return result; + } + + private void printCluster(Agraph_s g, Cluster cluster) { + for (Shape shape : cluster.getShapes()) { + final Agnode_s node = agnode(g, new CString(shape.getUid()), true); + agsafeset(node, new CString("shape"), new CString("box"), new CString("")); + final String width = "" + (shape.getWidth() / 72); + final String height = "" + (shape.getHeight() / 72); + agsafeset(node, new CString("width"), new CString(width), new CString("")); + agsafeset(node, new CString("height"), new CString(height), new CString("")); + final ILeaf leaf = dotStringFactory.getBibliotekon().getLeaf(shape); + nodes.put(leaf, node); + } + + } + + public ImageData createFile(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException { + + for (ILeaf leaf : diagram.getLeafsvalues()) { + printEntityNew(leaf); + } + + Z.open(); + try { + final Agraph_s g = agopen(new CString("g"), Z._().Agdirected, null); + + // printCluster(g, root); + exportEntities(g, getUnpackagedEntities()); + exportGroups(g, diagram.getEntityFactory().getRootGroup()); + + // for (ILeaf leaf : diagram.getLeafsvalues()) { + // final Shape shape = bibliotekon.getShape(leaf); + // final Agnode_s node = agnode(g, new CString(shape.getUid()), true); + // agsafeset(node, new CString("shape"), new CString("box"), new CString("")); + // final String width = "" + (shape.getWidth() / 72); + // final String height = "" + (shape.getHeight() / 72); + // agsafeset(node, new CString("width"), new CString(width), new CString("")); + // agsafeset(node, new CString("height"), new CString(height), new CString("")); + // nodes.put(leaf, node); + // // System.err + // // .println("NODE " + leaf.getUid() + " [shape=box, width=" + width + ", height=" + height + "]"); + // } + // + for (Link link : diagram.getLinks()) { + System.err.println("link=" + link); + final Agedge_s e = createEdge(g, link); + System.err.println("Agedge_s=" + e); + if (e != null) { + edges.put(link, e); + } + } + + final GVC_s gvc = gvContext(); + gvLayoutJobs(gvc, g); + + // for (Agedge_s e : edges.values()) { + // DebugUtils.printDebugEdge(e); + // } + + final double scale = 1; + + final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam().getColorMapper(), scale, null, + fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null, null, 0, 10, + diagram.getAnimation(), diagram.getSkinParam().handwritten()); + + imageBuilder.setUDrawable(new Drawing(null)); + final Dimension2D dim = imageBuilder.getFinalDimension(); + + imageBuilder.setUDrawable(new Drawing(new YMirror(dim.getHeight()))); + + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); + } catch (Throwable e) { + UmlDiagram.exportDiagramError(os, e, fileFormatOption, diagram.getMetadata(), diagram.getFlashData(), + getFailureText3(e)); + return new ImageDataSimple(); + } finally { + Z.close(); + } + } + + private void exportGroups(Agraph_s graph, IGroup parent) { + for (IGroup g : diagram.getChildrenGroups(parent)) { + if (g.isRemoved()) { + continue; + } + if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) { + final ILeaf folder = emptyGroups.get(g); + exportEntity(graph, folder); + } else { + exportGroup(graph, g); + } + } + + } + + private void exportGroup(Agraph_s graph, IGroup group) { + final Cluster cluster = getBibliotekon().getCluster(group); + JUtils.LOG2("cluster = " + cluster.getClusterId()); + final Agraph_s cluster1 = agsubg(graph, new CString(cluster.getClusterId()), true); + if (cluster.isLabel()) { + final double width = cluster.getTitleAndAttributeWidth(); + final double height = cluster.getTitleAndAttributeHeight() - 5; + agsafeset(cluster1, new CString("label"), + Macro.createHackInitDimensionFromLabel((int) width, (int) height), new CString("")); + } + this.exportEntities(cluster1, group.getLeafsDirect()); + this.clusters.put(group, cluster1); + this.exportGroups(cluster1, group); + } + + private TextBlock getLabel(Link link) { + final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1; + ISkinParam skinParam = diagram.getSkinParam(); + final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.GENERIC_ARROW, null); + final TextBlock label = link.getLabel().create(labelFont, skinParam.getDefaultTextAlignment(), skinParam); + if (TextBlockUtils.isEmpty(label)) { + return label; + } + return TextBlockUtils.withMargin(label, marginLabel, marginLabel); + + } + + private Agnode_s getAgnodeFromLeaf(IEntity entity) { + final Agnode_s n = nodes.get(entity); + if (n != null) { + return n; + } + final String id = getBibliotekon().getShapeUid((ILeaf) entity); + for (Map.Entry ent : nodes.entrySet()) { + if (id.equals(getBibliotekon().getShapeUid(ent.getKey()))) { + return ent.getValue(); + } + } + return null; + + } + + private Agedge_s createEdge(final Agraph_s g, Link link) { + final Agnode_s n = getAgnodeFromLeaf(link.getEntity1()); + final Agnode_s m = getAgnodeFromLeaf(link.getEntity2()); + if (n == null) { + return null; + } + if (m == null) { + return null; + } + final Agedge_s e = agedge(g, n, m, null, true); + agsafeset(e, new CString("arrowtail"), new CString("none"), new CString("")); + agsafeset(e, new CString("arrowhead"), new CString("none"), new CString("")); + + int length = link.getLength(); + // System.err.println("length=" + length); + // if (/* pragma.horizontalLineBetweenDifferentPackageAllowed() || */link.isInvis() || length != 1) { + agsafeset(e, new CString("minlen"), new CString("" + (length - 1)), new CString("")); + // } + System.err.print("EDGE " + link.getEntity1().getUid() + "->" + link.getEntity2().getUid() + " minlen=" + + (length - 1) + " "); + + final TextBlock label = getLabel(link); + if (TextBlockUtils.isEmpty(label) == false) { + final Dimension2D dimLabel = label.calculateDimension(stringBounder); + // System.err.println("dimLabel = " + dimLabel); + final CString hackDim = Macro.createHackInitDimensionFromLabel((int) dimLabel.getWidth(), + (int) dimLabel.getHeight()); + agsafeset(e, new CString("label"), hackDim, new CString("")); + System.err.print(" label=" + hackDim.getContent()); + } + System.err.println(); + return e; + } + + static private List getFailureText3(Throwable exception) { + exception.printStackTrace(); + final List strings = new ArrayList(); + strings.add("An error has occured : " + exception); + final String quote = QuoteUtils.getSomeQuote(); + strings.add("" + quote); + strings.add(" "); + GraphvizCrash.addProperties(strings); + strings.add(" "); + strings.add("Sorry, the subproject Smetana is not finished yet..."); + strings.add(" "); + strings.add("You should send this diagram and this image to plantuml@gmail.com to solve this issue."); + strings.add(" "); + return strings; + } + + private void printEntityNew(ILeaf ent) { + if (ent.isRemoved()) { + throw new IllegalStateException(); + } + 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.addShape(shape); + getBibliotekon().putShape(ent, shape); + } + + private Bibliotekon getBibliotekon() { + return dotStringFactory.getBibliotekon(); + } + + private IEntityImage printEntityInternal(ILeaf ent) { + if (ent.isRemoved()) { + throw new IllegalStateException(); + } + if (ent.getSvekImage() == null) { + ISkinParam skinParam = diagram.getSkinParam(); + if (skinParam.sameClassWidth()) { + throw new UnsupportedOperationException(); + // final double width = getMaxWidth(); + // skinParam = new SkinParamSameClassWidth(dotData.getSkinParam(), width); + } + + return CucaDiagramFileMakerSvek2.createEntityImageBlock(ent, skinParam, + diagram.isHideEmptyDescriptionForState(), diagram, getBibliotekon(), null, + diagram.getUmlDiagramType()); + } + return ent.getSvekImage(); + } + +} diff --git a/src/net/sourceforge/plantuml/jdot/DebugUtils.java b/src/net/sourceforge/plantuml/jdot/DebugUtils.java new file mode 100644 index 0000000..6e9c166 --- /dev/null +++ b/src/net/sourceforge/plantuml/jdot/DebugUtils.java @@ -0,0 +1,132 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.jdot; + +import h.Agedge_s; +import h.Agedgeinfo_t; +import h.Agnode_s; +import h.Agnodeinfo_t; +import h.bezier; +import h.boxf; +import h.pointf; +import h.splines; +import h.textlabel_t; +import smetana.core.Macro; +import smetana.core.__ptr__; +import smetana.core.__struct__; +import smetana.core.amiga.StarArrayOfPtr; +import smetana.core.amiga.StarStruct; + +public class DebugUtils { + + public static void printDebugEdge(Agedge_s e) { + System.err.println("*********** PRINT EDGE ********** " + getUID(e)); + final Agedgeinfo_t data = (Agedgeinfo_t) Macro.AGDATA(e).castTo(Agedgeinfo_t.class); + final splines splines = (splines) data.getPtr("spl"); + __struct__ bb = splines.getStruct("bb"); + // final bezier list = (bezier) splines.getPtr("list"); + System.err.println("splines.UID=" + ((StarStruct) splines).getUID36()); + System.err.println("splines.size=" + splines.getInt("size")); + System.err.println("bb.LL=" + pointftoString(bb.getStruct("LL"))); + System.err.println("bb.UR=" + pointftoString(bb.getStruct("UR"))); + printDebugBezier((bezier) splines.getPtr("list").getPtr()); + + textlabel_t label = (textlabel_t) data.getPtr("label"); + if (label != null) { + System.err.println("LABEL dimen=" + pointftoString(label.getStruct("dimen"))); + System.err.println("LABEL space=" + pointftoString(label.getStruct("space"))); + System.err.println("LABEL pos=" + pointftoString(label.getStruct("pos"))); + } + + } + + public static String getUID(Object o) { + if (o instanceof StarArrayOfPtr) { + return ((StarArrayOfPtr) o).getUID36(); + } + return ((StarStruct) o).getUID36(); + } + + public static void printDebugBezier(bezier bezier) { + System.err.println("bezier.size=" + bezier.getInt("size")); + System.err.println("bezier.sflag=" + bezier.getInt("sflag")); + System.err.println("splines.eflag=" + bezier.getInt("eflag")); + System.err.println("bezier.sp=" + pointftoString(bezier.getStruct("sp"))); + System.err.println("bezier.ep=" + pointftoString(bezier.getStruct("ep"))); + System.err.println("bezier.list=" + getUID(bezier.getPtr("list"))); + for (int i = 0; i < bezier.getInt("size"); i++) { + final __ptr__ pt = bezier.getPtr("list").plus(i).getPtr(); + System.err.println("pt=" + pointftoString(pt)); + } + + } + + public static void printDebugNode(Agnode_s n) { + System.err.println("*********** PRINT NODE ********** "); + final Agnodeinfo_t data = (Agnodeinfo_t) Macro.AGDATA(n).castTo(Agnodeinfo_t.class); + System.err.println("width=" + data.getDouble("width")); + System.err.println("height=" + data.getDouble("height")); + System.err.println("ht=" + data.getDouble("ht")); + System.err.println("lw=" + data.getDouble("lw")); + System.err.println("rw=" + data.getDouble("rw")); + System.err.println("coord=" + pointftoString(data.getStruct("coord"))); + + __struct__ bb = data.getStruct("bb"); + System.err.println("bb.LL=" + pointftoString(bb.getStruct("LL"))); + System.err.println("bb.UR=" + pointftoString(bb.getStruct("UR"))); + // TODO Auto-generated method stub + } + + public static String pointftoString(__struct__ point) { + final StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(point.getDouble("x")); + sb.append(" ; "); + sb.append(point.getDouble("y")); + sb.append(")"); + return sb.toString(); + + } + + public static String pointftoString(__ptr__ point) { + final StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(point.getDouble("x")); + sb.append(" ; "); + sb.append(point.getDouble("y")); + sb.append(")"); + return sb.toString(); + } +} diff --git a/src/net/sourceforge/plantuml/jdot/JDotPath.java b/src/net/sourceforge/plantuml/jdot/JDotPath.java new file mode 100644 index 0000000..cb5f395 --- /dev/null +++ b/src/net/sourceforge/plantuml/jdot/JDotPath.java @@ -0,0 +1,215 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.jdot; + +import h.Agedge_s; +import h.Agedgeinfo_t; +import h.bezier; +import h.pointf; +import h.splines; +import h.textlabel_t; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.graphic.color.ColorType; +import net.sourceforge.plantuml.posimo.DotPath; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import smetana.core.Macro; +import smetana.core.__ptr__; +import smetana.core.__struct__; + +public class JDotPath implements UDrawable { + + private final Link link; + private final Agedge_s edge; + private final YMirror ymirror; + private final CucaDiagram diagram; + private final TextBlock label; + private final Rose rose = new Rose(); + + public JDotPath(Link link, Agedge_s edge, YMirror ymirror, CucaDiagram diagram, TextBlock label) { + this.link = link; + this.edge = edge; + this.ymirror = ymirror; + this.diagram = diagram; + this.label = label; + } + + private ColorParam getArrowColorParam() { + if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS) { + return ColorParam.classArrow; + } else if (diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) { + return ColorParam.objectArrow; + } else if (diagram.getUmlDiagramType() == UmlDiagramType.DESCRIPTION) { + return ColorParam.usecaseArrow; + } else if (diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return ColorParam.activityArrow; + } else if (diagram.getUmlDiagramType() == UmlDiagramType.STATE) { + return ColorParam.stateArrow; + } + throw new IllegalStateException(); + } + + public void drawU(UGraphic ug) { + + HtmlColor color = rose.getHtmlColor(diagram.getSkinParam(), getArrowColorParam(), null); + + if (this.link.getColors() != null) { + final HtmlColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE); + if (newColor != null) { + color = newColor; + } + + } else if (this.link.getSpecificColor() != null) { + color = this.link.getSpecificColor(); + } + + DotPath dotPath = getDotPath(edge); + if (ymirror != null) { + dotPath = ymirror.getMirrored(dotPath); + } + + ug.apply(new UChangeColor(color)).draw(dotPath); + if (getLabelRectangleTranslate() != null) { + label.drawU(ug.apply(getLabelRectangleTranslate())); + } + // printDebug(ug); + + } + + private void printDebug(UGraphic ug) { + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(HtmlColorUtils.BLUE)); + final splines splines = getSplines(edge); + final bezier beziers = (bezier) splines.getPtr("list"); + for (int i = 0; i < beziers.getInt("size"); i++) { + Point2D pt = getPoint(splines, i); + if (ymirror != null) { + pt = ymirror.getMirrored(pt); + } + ug.apply(new UTranslate(pt).compose(new UTranslate(-1, -1))).draw(new UEllipse(3, 3)); + } + if (getLabelRectangleTranslate() != null && getLabelURectangle() != null) { + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(null)); + ug.apply(getLabelRectangleTranslate()).draw(getLabelURectangle()); + } + + } + + private URectangle getLabelURectangle() { + final Agedgeinfo_t data = (Agedgeinfo_t) Macro.AGDATA(edge).castTo(Agedgeinfo_t.class); + textlabel_t label = (textlabel_t) data.getPtr("label"); + if (label == null) { + return null; + } + final __struct__ dimen = label.getStruct("dimen"); + final __struct__ space = label.getStruct("space"); + final __struct__ pos = label.getStruct("pos"); + final double x = pos.getDouble("x"); + final double y = pos.getDouble("y"); + final double width = dimen.getDouble("x"); + final double height = dimen.getDouble("y"); + return new URectangle(width, height); + } + + private UTranslate getLabelRectangleTranslate() { + final Agedgeinfo_t data = (Agedgeinfo_t) Macro.AGDATA(edge).castTo(Agedgeinfo_t.class); + textlabel_t label = (textlabel_t) data.getPtr("label"); + if (label == null) { + return null; + } + final __struct__ dimen = label.getStruct("dimen"); + final __struct__ space = label.getStruct("space"); + final __struct__ pos = label.getStruct("pos"); + final double x = pos.getDouble("x"); + final double y = pos.getDouble("y"); + final double width = dimen.getDouble("x"); + final double height = dimen.getDouble("y"); + + if (ymirror == null) { + return new UTranslate(x - width / 2, y - height / 2); + } + return ymirror.getMirrored(new UTranslate(x - width / 2, y + height / 2)); + } + + public DotPath getDotPath(Agedge_s e) { + final splines splines = getSplines(e); + return getDotPath(splines); + } + + private splines getSplines(Agedge_s e) { + final Agedgeinfo_t data = (Agedgeinfo_t) Macro.AGDATA(e).castTo(Agedgeinfo_t.class); + final splines splines = (splines) data.getPtr("spl"); + return splines; + } + + private DotPath getDotPath(splines splines) { + DotPath result = new DotPath(); + final bezier beziers = (bezier) splines.getPtr("list"); + final Point2D pt1 = getPoint(splines, 0); + final Point2D pt2 = getPoint(splines, 1); + final Point2D pt3 = getPoint(splines, 2); + final Point2D pt4 = getPoint(splines, 3); + result = result.addCurve(pt1, pt2, pt3, pt4); + final int n = beziers.getInt("size"); + for (int i = 4; i < n; i += 3) { + final Point2D ppt2 = getPoint(splines, i); + final Point2D ppt3 = getPoint(splines, i + 1); + final Point2D ppt4 = getPoint(splines, i + 2); + result = result.addCurve(ppt2, ppt3, ppt4); + } + return result; + } + + private Point2D getPoint(splines splines, int i) { + final bezier beziers = (bezier) splines.getPtr("list"); + final __ptr__ pt = beziers.getPtr("list").plus(i).getPtr(); + return new Point2D.Double(pt.getDouble("x"), pt.getDouble("y")); + } + +} diff --git a/src/net/sourceforge/plantuml/jdot/YMirror.java b/src/net/sourceforge/plantuml/jdot/YMirror.java new file mode 100644 index 0000000..756292b --- /dev/null +++ b/src/net/sourceforge/plantuml/jdot/YMirror.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.jdot; + +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.posimo.DotPath; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class YMirror { + + private final double max; + + public YMirror(double max) { + this.max = max; + } + + public double getMirrored(double v) { + if (v < 0 || v > max) { + throw new IllegalArgumentException(); + } + //return v; + return max - v; + } + + public Point2D getMirrored(Point2D pt) { + //return pt; + return new Point2D.Double(pt.getX(), max - pt.getY()); + } + + public DotPath getMirrored(DotPath path) { + DotPath result = new DotPath(); + for (CubicCurve2D.Double bez : path.getBeziers()) { + result = result.addCurve(getMirrored(bez.getP1()), getMirrored(bez.getCtrlP1()), + getMirrored(bez.getCtrlP2()), getMirrored(bez.getP2())); + } + return result; + } + + public UTranslate getMirrored(UTranslate tr) { + return new UTranslate(tr.getDx(), max - tr.getDy()); + //return tr; + } + +} diff --git a/src/net/sourceforge/plantuml/jungle/PSystemTree.java b/src/net/sourceforge/plantuml/jungle/PSystemTree.java index b4b90f3..8ace9a0 100644 --- a/src/net/sourceforge/plantuml/jungle/PSystemTree.java +++ b/src/net/sourceforge/plantuml/jungle/PSystemTree.java @@ -72,9 +72,9 @@ public class PSystemTree extends AbstractPSystem { final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true); tmp.drawU(limitFinder); final double minY = limitFinder.getMinY(); - builder.addUDrawable(UDrawableUtils.move(tmp, 0, -minY)); + builder.setUDrawable(UDrawableUtils.move(tmp, 0, -minY)); } else { - builder.addUDrawable(new GTileOneLevelFactory().createGTile(root)); + builder.setUDrawable(new GTileOneLevelFactory().createGTile(root)); } return builder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java b/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java index 71db0ba..16e246a 100644 --- a/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java +++ b/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java @@ -62,7 +62,7 @@ public class PSystemListOpenIconic extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java b/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java index 1ea7705..a3d0472 100644 --- a/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java +++ b/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java @@ -62,7 +62,7 @@ public class PSystemOpenIconic extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 5, 5, null, false); - imageBuilder.addUDrawable(icon.asTextBlock(HtmlColorUtils.BLACK, factor)); + imageBuilder.setUDrawable(icon.asTextBlock(HtmlColorUtils.BLACK, factor)); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); // UGraphic2 ug = fileFormat.createUGraphic(dim); diff --git a/src/net/sourceforge/plantuml/oregon/PSystemOregon.java b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java index c0f37e1..8bbdb0a 100644 --- a/src/net/sourceforge/plantuml/oregon/PSystemOregon.java +++ b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java @@ -101,7 +101,7 @@ public class PSystemOregon extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/png/MetadataTag.java b/src/net/sourceforge/plantuml/png/MetadataTag.java index b3576a6..de8b763 100644 --- a/src/net/sourceforge/plantuml/png/MetadataTag.java +++ b/src/net/sourceforge/plantuml/png/MetadataTag.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.png; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.Iterator; import javax.imageio.ImageIO; @@ -48,16 +49,21 @@ import org.w3c.dom.Node; public class MetadataTag { - private final File f; + private final Object source; private final String tag; - public MetadataTag(File f, String tag) { - this.f = f; + public MetadataTag(File file, String tag) { + this.source = file; + this.tag = tag; + } + + public MetadataTag(InputStream is, String tag) { + this.source = is; this.tag = tag; } public String getData() throws IOException { - final ImageInputStream iis = ImageIO.createImageInputStream(f); + final ImageInputStream iis = ImageIO.createImageInputStream(source); final Iterator readers = ImageIO.getImageReaders(iis); if (readers.hasNext()) { diff --git a/src/net/sourceforge/plantuml/png/PngIO.java b/src/net/sourceforge/plantuml/png/PngIO.java index d29aa09..a19ee8d 100644 --- a/src/net/sourceforge/plantuml/png/PngIO.java +++ b/src/net/sourceforge/plantuml/png/PngIO.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.Log; public class PngIO { - private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; + private static final String copyleft = "Generated by http://plantuml.com"; public static void write(RenderedImage image, File file, int dpi) throws IOException { write(image, file, null, dpi); diff --git a/src/net/sourceforge/plantuml/png/PngIOMetadata.java b/src/net/sourceforge/plantuml/png/PngIOMetadata.java index d5b4228..24b2118 100644 --- a/src/net/sourceforge/plantuml/png/PngIOMetadata.java +++ b/src/net/sourceforge/plantuml/png/PngIOMetadata.java @@ -42,6 +42,7 @@ import java.util.Iterator; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; import net.sourceforge.plantuml.Log; @@ -49,9 +50,10 @@ import com.sun.imageio.plugins.png.PNGMetadata; public class PngIOMetadata { - private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; + private static final String copyleft = "Generated by http://plantuml.com"; - public static void writeWithMetadata(RenderedImage image, OutputStream os, String metadata, int dpi, String debugData) throws IOException { + public static void writeWithMetadata(RenderedImage image, OutputStream os, String metadata, int dpi, + String debugData) throws IOException { // Create & populate metadata final PNGMetadata pngMetadata = new PNGMetadata(); @@ -67,19 +69,13 @@ public class PngIOMetadata { pngMetadata.zTXt_keyword.add("plantuml"); pngMetadata.zTXt_compressionMethod.add(new Integer(0)); pngMetadata.zTXt_text.add(metadata); - // Log.println("metadata=" + metadata); - // if (metadata.equals("Generated by - // http://plantuml.sourceforge.net")) { - // throw new IllegalArgumentException(); - // } } - + if (debugData != null) { pngMetadata.tEXt_keyword.add("debug"); pngMetadata.tEXt_text.add(debugData); } - pngMetadata.tEXt_keyword.add("copyleft"); pngMetadata.tEXt_text.add(copyleft); @@ -92,16 +88,26 @@ public class PngIOMetadata { final ImageWriter imagewriter = getImageWriter(); Log.debug("PngIOMetadata imagewriter=" + imagewriter); + // See http://plantuml.sourceforge.net/qa/?qa=4367/sometimes-missing-response-headers-for-broken-png-images + // Code provided by Michael Griffel synchronized (imagewriter) { - imagewriter.setOutput(ImageIO.createImageOutputStream(os)); - imagewriter.write(null, iioImage, null); - os.flush(); - imagewriter.reset(); - imagewriter.dispose(); + final ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(os); + imagewriter.setOutput(imageOutputStream); + try { + imagewriter.write(null /* default */, iioImage, null /* use default ImageWriteParam */); + } finally { + //os.flush(); + // Log.debug("PngIOMetadata finally 1"); + imageOutputStream.flush(); + // Log.debug("PngIOMetadata finally 2"); + imageOutputStream.close(); + // Log.debug("PngIOMetadata finally 3"); + imagewriter.reset(); + // Log.debug("PngIOMetadata finally 4"); + imagewriter.dispose(); + // Log.debug("PngIOMetadata finally 5"); + } } -// Log.debug("PngIOMetadata before flush"); -// os.flush(); -// Log.debug("PngIOMetadata after flush"); } private static ImageWriter getImageWriter() { diff --git a/src/net/sourceforge/plantuml/posimo/DotPath.java b/src/net/sourceforge/plantuml/posimo/DotPath.java index 7a7d7ae..4479db7 100644 --- a/src/net/sourceforge/plantuml/posimo/DotPath.java +++ b/src/net/sourceforge/plantuml/posimo/DotPath.java @@ -109,6 +109,25 @@ public class DotPath implements UShape, Moveable { this.beziers.addAll(beziers); } + public DotPath addCurve(Point2D pt1, Point2D pt2, Point2D pt3, Point2D pt4) { + final List beziersNew = new ArrayList(beziers); + beziersNew.add(new CubicCurve2D.Double(pt1.getX(), pt1.getY(), pt2.getX(), pt2.getY(), pt3.getX(), pt3.getY(), + pt4.getX(), pt4.getY())); + return new DotPath(beziersNew); + } + + public DotPath addCurve(Point2D pt2, Point2D pt3, Point2D pt4) { + final CubicCurve2D.Double last = beziers.get(beziers.size() - 1); + final Point2D p1 = last.getP2(); + return addCurve(p1, pt2, pt3, pt4); + } + + private Point2D mirror(Point2D center, Point2D pt) { + final double x = 2 * center.getX() - pt.getX(); + final double y = 2 * center.getY() - pt.getY(); + return new Point2D.Double(x, y); + } + public DotPath(String init, double deltaY) { if (init.startsWith("M") == false) { throw new IllegalArgumentException(); @@ -533,9 +552,9 @@ public class DotPath implements UShape, Moveable { } public DotPath simulateCompound(Cluster head, Cluster tail) { - if (OptionFlags.USE_COMPOUND) { - throw new IllegalStateException(); - } +// if (OptionFlags.USE_COMPOUND) { +// throw new IllegalStateException(); +// } if (head == null && tail == null) { return this; } diff --git a/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java b/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java index 4d1888a..dfe8802 100644 --- a/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java +++ b/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java @@ -103,7 +103,7 @@ public class GraphvizSolverB { // exportPng(dotString, new File("png", "test1.png")); - final Graphviz graphviz = GraphvizUtils.create(dotString, "svg"); + final Graphviz graphviz = GraphvizUtils.create(null, dotString, "svg"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ProcessState state = graphviz.createFile3(baos); baos.close(); @@ -244,7 +244,7 @@ public class GraphvizSolverB { } private void exportPng(final String dotString, File f) throws IOException { - final Graphviz graphviz = GraphvizUtils.create(dotString, "png"); + final Graphviz graphviz = GraphvizUtils.create(null, dotString, "png"); final OutputStream os = new BufferedOutputStream(new FileOutputStream(f)); final ProcessState state = graphviz.createFile3(os); os.close(); diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index d6c2f9f..320a64d 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -87,7 +87,7 @@ public class PSystemSalt extends AbstractPSystem { final Dimension2D size = salt.getPreferredDimension(TextBlockUtils.getDummyStringBounder(), 0, 0); final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, null, null, 5, 5, null, false); - builder.addUDrawable(new UDrawable() { + builder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/Participant.java b/src/net/sourceforge/plantuml/sequencediagram/Participant.java index 04d5ea7..8786a9c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/Participant.java +++ b/src/net/sourceforge/plantuml/sequencediagram/Participant.java @@ -136,7 +136,6 @@ public class Participant implements SpecificBackcolorable { private Colors colors = Colors.empty(); - public void setColors(Colors colors) { this.colors = colors; } @@ -166,7 +165,13 @@ public class Participant implements SpecificBackcolorable { if (stereoBackColor != null && specificBackColor == null) { specificBackColor = stereoBackColor; } - return new SkinParamBackcolored(skinParam, specificBackColor, clickable); + final SkinParamBackcolored result = new SkinParamBackcolored(skinParam, specificBackColor, clickable); + final HtmlColor stereoBorderColor = skinParam.getHtmlColor(ColorParam.participantBorder, getStereotype(), + clickable); + if (stereoBorderColor != null) { + result.forceColor(ColorParam.participantBorder, stereoBorderColor); + } + return result; } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java index 764b7cd..3fe070d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -64,7 +64,7 @@ public class CommandArrow extends SingleLineCommand2 { } public static String getColorOrStylePattern() { - return "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"; + return "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"; } static RegexConcat getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java index 20aef8d..f21bf8e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java @@ -183,7 +183,7 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker { dpiFactor), diagram.getSkinParam().getBackgroundColor(), metadata, null, 3, 10, diagram.getAnimation(), diagram.getSkinParam().handwritten()); - imageBuilder.addUDrawable(new UDrawable() { + imageBuilder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { double delta = 0; diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagram.java b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java index ee59870..1b7b523 100644 --- a/src/net/sourceforge/plantuml/statediagram/StateDiagram.java +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java @@ -166,52 +166,5 @@ public class StateDiagram extends AbstractEntityDiagram { return hideEmptyDescription; } - // public Link isEntryPoint(IEntity ent) { - // final Stereotype stereotype = ent.getStereotype(); - // if (stereotype == null) { - // return null; - // } - // final String label = stereotype.getLabel(); - // if ("<>".equalsIgnoreCase(label) == false) { - // return null; - // } - // Link inLink = null; - // Link outLink = null; - // for (Link link : getLinks()) { - // if (link.getEntity1() == ent) { - // if (outLink != null) { - // return null; - // } - // outLink = link; - // } - // if (link.getEntity2() == ent) { - // if (inLink != null) { - // return null; - // } - // inLink = link; - // } - // } - // if (inLink == null || outLink == null) { - // return null; - // } - // final Link result = Link.mergeForEntryPoint(inLink, outLink); - // result.setEntryPoint(ent.getContainer()); - // return result; - // } - // - // public void manageExitAndEntryPoints() { - // for (IEntity ent : getEntities().values()) { - // final Link entryPointLink = isEntryPoint(ent); - // if (entryPointLink != null) { - // addLink(entryPointLink); - // for (Link link : new ArrayList(getLinks())) { - // if (link.contains(ent)) { - // removeLink(link); - // } - // } - // } - // } - // - // } } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java index 7181b30..590b4c7 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java @@ -68,10 +68,10 @@ public class CommandLinkState extends SingleLineCommand2 { new RegexLeaf("ARROW_CROSS_START", "(x)?"), // new RegexLeaf("ARROW_BODY1", "(-+)"), // new RegexLeaf("ARROW_STYLE1", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_DIRECTION", "(left|right|up|down|le?|ri?|up?|do?)?"), // new RegexLeaf("ARROW_STYLE2", - "(?:\\[((?:#\\w+|dotted|dashed|bold|hidden)(?:,#\\w+|,dotted|,dashed|,bold|,hidden)*)\\])?"), // + "(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden)*)\\])?"), // new RegexLeaf("ARROW_BODY2", "(-*)"), // new RegexLeaf("\\>"), // new RegexLeaf("ARROW_CIRCLE_END", "(o[%s]+)?")), // diff --git a/src/net/sourceforge/plantuml/svek/Bibliotekon.java b/src/net/sourceforge/plantuml/svek/Bibliotekon.java index 7adb840..fbf8a71 100644 --- a/src/net/sourceforge/plantuml/svek/Bibliotekon.java +++ b/src/net/sourceforge/plantuml/svek/Bibliotekon.java @@ -190,4 +190,13 @@ public class Bibliotekon { } return null; } + + public ILeaf getLeaf(Shape shape) { + for (Map.Entry ent : shapeMap.entrySet()) { + if (ent.getValue() == shape) { + return ent.getKey(); + } + } + throw new IllegalArgumentException(); + } } diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java index d43bb76..ceac294 100644 --- a/src/net/sourceforge/plantuml/svek/Cluster.java +++ b/src/net/sourceforge/plantuml/svek/Cluster.java @@ -39,6 +39,7 @@ import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -52,6 +53,7 @@ import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.cucadiagram.EntityPosition; @@ -61,7 +63,6 @@ import net.sourceforge.plantuml.cucadiagram.IGroup; 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.cucadiagram.dot.GraphvizVersion; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorTransparent; @@ -81,7 +82,6 @@ import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.utils.UniqueSequence; public class Cluster implements Moveable { @@ -200,12 +200,12 @@ public class Cluster implements Moveable { return firsts; } - private List getShapesEntryExit(EntityPosition position) { + private List getShapesEntryExit(EnumSet positions) { final List result = new ArrayList(); for (final Iterator it = shapes.iterator(); it.hasNext();) { final Shape sh = it.next(); - if (sh.getEntityPosition() == position) { + if (positions.contains(sh.getEntityPosition())) { result.add(sh); } } @@ -297,11 +297,11 @@ public class Cluster implements Moveable { return SkinParamUtils.getColor(skinParam, colorParam, stereotype); } - public void drawU(UGraphic ug, DotData dotData, UStroke stroke) { + public void drawU(UGraphic ug, UStroke stroke, final UmlDiagramType umlDiagramType, final ISkinParam skinParam2) { final Stereotype stereotype = group.getStereotype(); HtmlColor borderColor; - if (dotData.getUmlDiagramType() == UmlDiagramType.STATE) { + if (umlDiagramType == UmlDiagramType.STATE) { borderColor = getColor(ColorParam.stateBorder, skinParam, stereotype); } else { borderColor = getColor(ColorParam.packageBorder, skinParam, stereotype); @@ -313,13 +313,13 @@ public class Cluster implements Moveable { } try { if (hasEntryOrExitPoint()) { - manageEntryExitPoint(dotData, ug.getStringBounder()); + manageEntryExitPoint(ug.getStringBounder()); } - if (skinParam.useSwimlanes(dotData.getUmlDiagramType())) { - drawSwinLinesState(ug, borderColor, dotData); + if (skinParam.useSwimlanes(umlDiagramType)) { + drawSwinLinesState(ug, borderColor); return; } - final boolean isState = dotData.getUmlDiagramType() == UmlDiagramType.STATE; + final boolean isState = umlDiagramType == UmlDiagramType.STATE; if (isState) { if (group.getColors(skinParam).getSpecificLineStroke() != null) { stroke = group.getColors(skinParam).getSpecificLineStroke(); @@ -327,32 +327,32 @@ public class Cluster implements Moveable { if (group.getColors(skinParam).getColor(ColorType.LINE) != null) { borderColor = group.getColors(skinParam).getColor(ColorType.LINE); } - drawUState(ug, borderColor, dotData, stroke); + drawUState(ug, borderColor, skinParam2, stroke); return; } PackageStyle style = group.getPackageStyle(); if (style == null) { - style = dotData.getSkinParam().getPackageStyle(); + style = skinParam2.getPackageStyle(); } if (border != null) { - final HtmlColor tmp = dotData.getSkinParam().getHtmlColor(border, group.getStereotype(), false); + final HtmlColor tmp = skinParam2.getHtmlColor(border, group.getStereotype(), false); if (tmp != null) { borderColor = tmp; } } if (ztitle != null || zstereo != null) { - final HtmlColor back = getBackColor(getBackColor(), dotData.getSkinParam(), group.getStereotype()); + final HtmlColor back = getBackColor(getBackColor(), skinParam2, group.getStereotype()); final ClusterDecoration decoration = new ClusterDecoration(style, group.getUSymbol(), ztitle, zstereo, - minX, minY, maxX, maxY, getStroke(dotData.getSkinParam(), group.getStereotype())); - decoration.drawU(ug, back, borderColor, dotData.getSkinParam().shadowing()); + minX, minY, maxX, maxY, getStroke(skinParam2, group.getStereotype())); + decoration.drawU(ug, back, borderColor, skinParam2.shadowing()); return; } final URectangle rect = new URectangle(maxX - minX, maxY - minY); - if (dotData.getSkinParam().shadowing()) { + if (skinParam2.shadowing()) { rect.setDeltaShadow(3.0); } - final HtmlColor backColor = getBackColor(getBackColor(), dotData.getSkinParam(), group.getStereotype()); + final HtmlColor backColor = getBackColor(getBackColor(), skinParam2, group.getStereotype()); ug = ug.apply(new UChangeBackColor(backColor)).apply(new UChangeColor(borderColor)); ug.apply(new UStroke(2)).apply(new UTranslate(minX, minY)).draw(rect); @@ -372,7 +372,7 @@ public class Cluster implements Moveable { return stroke; } - public void manageEntryExitPoint(DotData dotData, StringBounder stringBounder) { + public void manageEntryExitPoint(StringBounder stringBounder) { final Collection insides = new ArrayList(); final List points = new ArrayList(); for (Shape sh : shapes) { @@ -400,7 +400,7 @@ public class Cluster implements Moveable { xTitle = minX + ((maxX - minX - widthTitle) / 2); } - private void drawSwinLinesState(UGraphic ug, HtmlColor borderColor, DotData dotData) { + private void drawSwinLinesState(UGraphic ug, HtmlColor borderColor) { if (ztitle != null) { ztitle.drawU(ug.apply(new UTranslate(xTitle, 0))); } @@ -411,11 +411,11 @@ public class Cluster implements Moveable { } - private HtmlColor getColor(DotData dotData, ColorParam colorParam, Stereotype stereo) { - return new Rose().getHtmlColor(dotData.getSkinParam(), colorParam, stereo); + private HtmlColor getColor(ISkinParam skinParam, ColorParam colorParam, Stereotype stereo) { + return new Rose().getHtmlColor(skinParam, colorParam, stereo); } - private void drawUState(UGraphic ug, HtmlColor borderColor, DotData dotData, UStroke stroke) { + private void drawUState(UGraphic ug, HtmlColor borderColor, ISkinParam skinParam2, UStroke stroke) { final Dimension2D total = new Dimension2DDouble(maxX - minX, maxY - minY); final double suppY; if (ztitle == null) { @@ -427,14 +427,14 @@ public class Cluster implements Moveable { HtmlColor stateBack = getBackColor(); if (stateBack == null) { - stateBack = getColor(dotData, ColorParam.stateBackground, group.getStereotype()); + stateBack = getColor(skinParam2, ColorParam.stateBackground, group.getStereotype()); } - final HtmlColor background = getColor(dotData, ColorParam.background, null); - final TextBlockWidth attribute = getTextBlockAttribute(dotData); + final HtmlColor background = getColor(skinParam2, ColorParam.background, null); + final TextBlockWidth attribute = getTextBlockAttribute(skinParam2); final double attributeHeight = attribute.calculateDimension(ug.getStringBounder()).getHeight(); final RoundedContainer r = new RoundedContainer(total, suppY, attributeHeight + (attributeHeight > 0 ? IEntityImage.MARGIN : 0), borderColor, stateBack, background, stroke); - r.drawU(ug.apply(new UTranslate(minX, minY)), dotData.getSkinParam().shadowing()); + r.drawU(ug.apply(new UTranslate(minX, minY)), skinParam2.shadowing()); if (ztitle != null) { ztitle.drawU(ug.apply(new UTranslate(xTitle, yTitle))); @@ -453,13 +453,13 @@ public class Cluster implements Moveable { } - private TextBlockWidth getTextBlockAttribute(DotData dotData) { + private TextBlockWidth getTextBlockAttribute(ISkinParam skinParam) { final TextBlockWidth attribute; final List members = group.getBodier().getFieldsToDisplay(); if (members.size() == 0) { attribute = new TextBlockEmpty(); } else { - attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, dotData.getSkinParam()); + attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, skinParam, group.getStereotype()); } return attribute; } @@ -513,8 +513,7 @@ public class Cluster implements Moveable { } public void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) { - // final List entries = getShapesEntryExit(EntityPosition.ENTRY_POINT); - final List shapesEntryExitList = getShapesEntryExit(EntityPosition.ENTRY_POINT); + final List shapesEntryExitList = getShapesEntryExit(EntityPosition.getInputs()); final double maxWith = getMaxWidthFromLabelForEntryExit(shapesEntryExitList, stringBounder); final double naturalSpace = 70; final List entries; @@ -533,7 +532,7 @@ public class Cluster implements Moveable { sh.appendShape(sb); } } - final List exits = getShapesEntryExit(EntityPosition.EXIT_POINT); + final List exits = getShapesEntryExit(EntityPosition.getOutputs()); if (exits.size() > 0) { sb.append("{rank=sink;"); for (Shape sh : exits) { @@ -702,9 +701,8 @@ public class Cluster implements Moveable { sb.append("style=solid;"); sb.append("color=\"" + StringUtils.getAsHtml(color) + "\";"); - final boolean isLabel = getTitleAndAttributeHeight() > 0 && getTitleAndAttributeWidth() > 0; final String label; - if (isLabel) { + if (isLabel()) { final StringBuilder sblabel = new StringBuilder("<"); Line.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle); sblabel.append(">"); @@ -773,6 +771,10 @@ public class Cluster implements Moveable { SvekUtils.println(sb); } + public boolean isLabel() { + return getTitleAndAttributeHeight() > 0 && getTitleAndAttributeWidth() > 0; + } + private void subgraphCluster(StringBuilder sb, String id) { subgraphCluster(sb, id, "\"\""); } diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java index 458ee00..8054e7a 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java @@ -68,8 +68,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { static private final StringBounder stringBounder; static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - stringBounder = StringBounderUtils.asStringBounder(builder.getGraphics2D()); + stringBounder = StringBounderUtils.asStringBounder(); } public CucaDiagramFileMakerSvek(CucaDiagram diagram) throws IOException { @@ -125,7 +124,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam().getColorMapper(), scale, result.getBackcolor(), fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null, warningOrError, 0, 10, diagram.getAnimation(), diagram.getSkinParam().handwritten()); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java index 1343e86..f85c818 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java @@ -112,6 +112,7 @@ import net.sourceforge.plantuml.svek.image.EntityImageStateEmptyDescription; import net.sourceforge.plantuml.svek.image.EntityImageSynchroBar; import net.sourceforge.plantuml.svek.image.EntityImageTips; import net.sourceforge.plantuml.svek.image.EntityImageUseCase; +import net.sourceforge.plantuml.ugraphic.sprite.Sprite; public final class CucaDiagramFileMakerSvek2 { @@ -125,8 +126,7 @@ public final class CucaDiagramFileMakerSvek2 { static private final StringBounder stringBounder; static { - final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); - stringBounder = StringBounderUtils.asStringBounder(builder.getGraphics2D()); + stringBounder = StringBounderUtils.asStringBounder(); } public CucaDiagramFileMakerSvek2(DotData dotData, EntityFactory entityFactory, UmlSource source, Pragma pragma) { @@ -342,9 +342,9 @@ public final class CucaDiagramFileMakerSvek2 { } if (ent.getSvekImage() == null) { ISkinParam skinParam = dotData.getSkinParam(); - if (dotData.getSkinParam().sameClassWidth()) { + if (skinParam.sameClassWidth()) { final double width = getMaxWidth(); - skinParam = new SkinParamSameClassWidth(dotData.getSkinParam(), width); + skinParam = new SkinParamSameClassWidth(skinParam, width); } return createEntityImageBlock(ent, skinParam, dotData.isHideEmptyDescriptionForState(), dotData, @@ -527,7 +527,7 @@ public final class CucaDiagramFileMakerSvek2 { if (members.size() == 0) { attribute = new TextBlockEmpty(); } else { - attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, dotData.getSkinParam()); + attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, dotData.getSkinParam(), g.getStereotype()); } final Dimension2D dimAttribute = attribute.calculateDimension(stringBounder); final double attributeHeight = dimAttribute.getHeight(); @@ -566,7 +566,10 @@ public final class CucaDiagramFileMakerSvek2 { return TextBlockUtils.empty(0, 0); } if (stereotype.getSprite() != null) { - return dotData.getSkinParam().getSprite(stereotype.getSprite()).asTextBlock(stereotype.getHtmlColor()); + final Sprite tmp = dotData.getSkinParam().getSprite(stereotype.getSprite()); + if (tmp != null) { + return tmp.asTextBlock(stereotype.getHtmlColor(), 1); + } } final List stereos = stereotype.getLabels(dotData.getSkinParam().useGuillemet()); if (stereos == null) { diff --git a/src/net/sourceforge/plantuml/svek/DotStringFactory.java b/src/net/sourceforge/plantuml/svek/DotStringFactory.java index afa6acd..5fe4dbe 100644 --- a/src/net/sourceforge/plantuml/svek/DotStringFactory.java +++ b/src/net/sourceforge/plantuml/svek/DotStringFactory.java @@ -45,9 +45,11 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.dot.DotData; @@ -60,7 +62,6 @@ import net.sourceforge.plantuml.cucadiagram.dot.ProcessState; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.posimo.Moveable; -import net.sourceforge.plantuml.StringUtils; public class DotStringFactory implements Moveable { @@ -72,15 +73,31 @@ public class DotStringFactory implements Moveable { private final Cluster root; private Cluster current; - private final DotData dotData; + private final UmlDiagramType umlDiagramType; + private final ISkinParam skinParam; + private final DotMode dotMode; private final StringBounder stringBounder; public DotStringFactory(ColorSequence colorSequence, StringBounder stringBounder, DotData dotData) { + this.skinParam = dotData.getSkinParam(); + this.umlDiagramType = dotData.getUmlDiagramType(); + this.dotMode = dotData.getDotMode(); + + this.colorSequence = colorSequence; + this.stringBounder = stringBounder; + this.root = new Cluster(colorSequence, skinParam, dotData.getRootGroup()); + this.current = root; + } + + public DotStringFactory(ColorSequence colorSequence, StringBounder stringBounder, CucaDiagram diagram) { + this.skinParam = diagram.getSkinParam(); + this.umlDiagramType = diagram.getUmlDiagramType(); + this.dotMode = DotMode.NORMAL; + this.colorSequence = colorSequence; - this.dotData = dotData; this.stringBounder = stringBounder; - this.root = new Cluster(colorSequence, dotData.getSkinParam(), dotData.getRootGroup()); + this.root = new Cluster(colorSequence, skinParam, diagram.getEntityFactory().getRootGroup()); this.current = root; } @@ -130,8 +147,8 @@ public class DotStringFactory implements Moveable { if (nodesep < getMinNodeSep()) { nodesep = getMinNodeSep(); } - if (dotData.getSkinParam().getNodesep() != 0) { - nodesep = dotData.getSkinParam().getNodesep(); + if (skinParam.getNodesep() != 0) { + nodesep = skinParam.getNodesep(); } final String nodesepInches = SvekUtils.pixelToInches(nodesep); // Log.println("nodesep=" + nodesepInches); @@ -139,8 +156,8 @@ public class DotStringFactory implements Moveable { if (ranksep < getMinRankSep()) { ranksep = getMinRankSep(); } - if (dotData.getSkinParam().getRanksep() != 0) { - ranksep = dotData.getSkinParam().getRanksep(); + if (skinParam.getRanksep() != 0) { + ranksep = skinParam.getRanksep(); } final String ranksepInches = SvekUtils.pixelToInches(ranksep); // Log.println("ranksep=" + ranksepInches); @@ -163,12 +180,12 @@ public class DotStringFactory implements Moveable { SvekUtils.println(sb); sb.append("searchsize=500;"); SvekUtils.println(sb); - if (OptionFlags.USE_COMPOUND) { - sb.append("compound=true;"); - SvekUtils.println(sb); - } + // if (OptionFlags.USE_COMPOUND) { + // sb.append("compound=true;"); + // SvekUtils.println(sb); + // } - final DotSplines dotSplines = dotData.getSkinParam().getDotSplines(); + final DotSplines dotSplines = skinParam.getDotSplines(); if (dotSplines == DotSplines.POLYLINE) { sb.append("splines=polyline;"); SvekUtils.println(sb); @@ -177,7 +194,7 @@ public class DotStringFactory implements Moveable { SvekUtils.println(sb); } - if (dotData.getSkinParam().getRankdir() == Rankdir.LEFT_TO_RIGHT) { + if (skinParam.getRankdir() == Rankdir.LEFT_TO_RIGHT) { sb.append("rankdir=LR;"); SvekUtils.println(sb); } @@ -189,8 +206,7 @@ public class DotStringFactory implements Moveable { line.appendLine(sb); } root.fillRankMin(rankMin); - root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotData.getDotMode(), getGraphvizVersion(), - dotData.getUmlDiagramType()); + root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType); printMinRanking(sb); for (Line line : bibliotekon.lines1()) { @@ -206,11 +222,11 @@ public class DotStringFactory implements Moveable { final List minPointCluster = new ArrayList(); final List maxPointCluster = new ArrayList(); for (Cluster cluster : bibliotekon.allCluster()) { - final String minPoint = cluster.getMinPoint(dotData.getUmlDiagramType()); + final String minPoint = cluster.getMinPoint(umlDiagramType); if (minPoint != null) { minPointCluster.add(minPoint); } - final String maxPoint = cluster.getMaxPoint(dotData.getUmlDiagramType()); + final String maxPoint = cluster.getMaxPoint(umlDiagramType); if (maxPoint != null) { maxPointCluster.add(maxPoint); } @@ -238,7 +254,7 @@ public class DotStringFactory implements Moveable { } private int getMinRankSep() { - if (dotData.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + if (umlDiagramType == UmlDiagramType.ACTIVITY) { // return 29; return 40; } @@ -246,7 +262,7 @@ public class DotStringFactory implements Moveable { } private int getMinNodeSep() { - if (dotData.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + if (umlDiagramType == UmlDiagramType.ACTIVITY) { // return 15; return 20; } @@ -254,7 +270,7 @@ public class DotStringFactory implements Moveable { } public GraphvizVersion getGraphvizVersion() { - final Graphviz graphviz = GraphvizUtils.create("foo;", "svg"); + final Graphviz graphviz = GraphvizUtils.create(skinParam, "foo;", "svg"); final File f = graphviz.getDotExe(); return GraphvizVersions.getInstance().getVersion(f); } @@ -267,7 +283,7 @@ public class DotStringFactory implements Moveable { SvekUtils.traceDotString(dotString); } - final Graphviz graphviz = GraphvizUtils.create(dotString, "svg"); + final Graphviz graphviz = GraphvizUtils.create(skinParam, dotString, "svg"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ProcessState state = graphviz.createFile3(baos); baos.close(); @@ -286,13 +302,13 @@ public class DotStringFactory implements Moveable { } public boolean illegalDotExe() { - final Graphviz graphviz = GraphvizUtils.create(null, "svg"); + final Graphviz graphviz = GraphvizUtils.create(skinParam, "svg"); final File dotExe = graphviz.getDotExe(); return dotExe == null || dotExe.isFile() == false || dotExe.canRead() == false; } public File getDotExe() { - final Graphviz graphviz = GraphvizUtils.create(null, "svg"); + final Graphviz graphviz = GraphvizUtils.create(skinParam, "svg"); return graphviz.getDotExe(); } @@ -379,7 +395,7 @@ public class DotStringFactory implements Moveable { } for (Line line : bibliotekon.allLines()) { - line.solveLine(svg, fullHeight, corner1, dotData); + line.solveLine(svg, fullHeight, corner1); } for (Line line : bibliotekon.allLines()) { @@ -407,7 +423,7 @@ public class DotStringFactory implements Moveable { public void openCluster(IGroup g, int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title, TextBlock stereo) { this.current = current.createChild(g, titleAndAttributeWidth, titleAndAttributeHeight, title, stereo, - colorSequence, dotData.getSkinParam()); + colorSequence, skinParam); bibliotekon.addCluster(this.current); } @@ -435,4 +451,8 @@ public class DotStringFactory implements Moveable { return bibliotekon; } + public ColorSequence getColorSequence() { + return colorSequence; + } + } diff --git a/src/net/sourceforge/plantuml/svek/FrontierCalculator.java b/src/net/sourceforge/plantuml/svek/FrontierCalculator.java index dff8848..d2b9ada 100644 --- a/src/net/sourceforge/plantuml/svek/FrontierCalculator.java +++ b/src/net/sourceforge/plantuml/svek/FrontierCalculator.java @@ -37,11 +37,11 @@ package net.sourceforge.plantuml.svek; import java.awt.geom.Point2D; import java.util.Collection; -import net.sourceforge.plantuml.svek.image.EntityImageStateBorder; +import net.sourceforge.plantuml.cucadiagram.EntityPosition; public class FrontierCalculator { - private static final double DELTA = 3 * EntityImageStateBorder.RADIUS; + private static final double DELTA = 3 * EntityPosition.RADIUS; private ClusterPosition core; private final ClusterPosition initial; diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java index 4d8e252..977aff8 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java @@ -152,7 +152,7 @@ public final class GroupPngMakerState { if (members.size() == 0) { attribute = new TextBlockEmpty(); } else { - attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, diagram.getSkinParam()); + attribute = new MethodsOrFieldsArea(members, FontParam.STATE_ATTRIBUTE, diagram.getSkinParam(), group.getStereotype()); } final Stereotype stereotype = group.getStereotype(); diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index 70815a9..d29bfc1 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -43,7 +43,6 @@ import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.Hideable; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; @@ -54,10 +53,8 @@ import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkArrow; import net.sourceforge.plantuml.cucadiagram.LinkDecor; -import net.sourceforge.plantuml.cucadiagram.LinkHat; import net.sourceforge.plantuml.cucadiagram.LinkMiddleDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; -import net.sourceforge.plantuml.cucadiagram.dot.DotData; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -77,6 +74,7 @@ import net.sourceforge.plantuml.posimo.Moveable; import net.sourceforge.plantuml.posimo.Positionable; import net.sourceforge.plantuml.posimo.PositionableUtils; import net.sourceforge.plantuml.svek.SvekUtils.PointListIterator; +import net.sourceforge.plantuml.svek.extremity.Extremity; import net.sourceforge.plantuml.svek.extremity.ExtremityFactory; import net.sourceforge.plantuml.svek.image.EntityImageNoteLink; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; @@ -362,16 +360,6 @@ public class Line implements Moveable, Hideable { // sb.append(",labelangle=0"); } - if (OptionFlags.USE_COMPOUND && ltail != null) { - sb.append(","); - sb.append("ltail="); - sb.append(ltail.getClusterId()); - } - if (OptionFlags.USE_COMPOUND && lhead != null) { - sb.append(","); - sb.append("lhead="); - sb.append(lhead.getClusterId()); - } if (link.isInvis()) { sb.append(","); sb.append("style=invis"); @@ -434,11 +422,11 @@ public class Line implements Moveable, Hideable { return endUid; } - private UDrawable getExtremity(LinkHat hat, LinkDecor decor, PointListIterator pointListIterator, Point2D center, - double angle, Cluster cluster, boolean isGroup) { + private UDrawable getExtremity(LinkDecor decor, PointListIterator pointListIterator, Point2D center, double angle, + Cluster cluster) { final ExtremityFactory extremityFactory = decor.getExtremityFactory(); - if (OptionFlags.USE_COMPOUND == false && cluster != null) { + if (cluster != null) { if (extremityFactory != null) { // System.err.println("angle=" + angle * 180 / Math.PI); return extremityFactory.createUDrawable(center, angle); @@ -464,7 +452,7 @@ public class Line implements Moveable, Hideable { } - public void solveLine(final String svg, final int fullHeight, MinFinder corner1, DotData dotData) { + public void solveLine(final String svg, final int fullHeight, MinFinder corner1) { if (this.link.isInvis()) { return; } @@ -482,26 +470,44 @@ public class Line implements Moveable, Hideable { final String path = svg.substring(idx + 3, end); dotPath = new DotPath(path, fullHeight); - if (OptionFlags.USE_COMPOUND == false) { - if (projectionCluster != null) { - System.err.println("Line::solveLine1 projectionCluster=" + projectionCluster.getClusterPosition()); - projectionCluster.manageEntryExitPoint(dotData, TextBlockUtils.getDummyStringBounder()); - System.err.println("Line::solveLine2 projectionCluster=" + projectionCluster.getClusterPosition()); - if (lhead != null) - System.err.println("Line::solveLine ltail=" + lhead.getClusterPosition()); - if (ltail != null) - System.err.println("Line::solveLine ltail=" + ltail.getClusterPosition()); - } - dotPath = dotPath.simulateCompound(lhead, ltail); + + if (projectionCluster != null) { + // System.err.println("Line::solveLine1 projectionCluster=" + projectionCluster.getClusterPosition()); + projectionCluster.manageEntryExitPoint(TextBlockUtils.getDummyStringBounder()); + // System.err.println("Line::solveLine2 projectionCluster=" + projectionCluster.getClusterPosition()); + // if (lhead != null) + // System.err.println("Line::solveLine ltail=" + lhead.getClusterPosition()); + // if (ltail != null) + // System.err.println("Line::solveLine ltail=" + ltail.getClusterPosition()); } + dotPath = dotPath.simulateCompound(lhead, ltail); - final PointListIterator pointListIterator = new PointListIterator(svg.substring(end), fullHeight); + PointListIterator pointListIterator = new PointListIterator(svg.substring(end), fullHeight); final LinkType linkType = link.getType(); - this.extremity2 = getExtremity(linkType.getHat2(), linkType.getDecor2(), pointListIterator, - dotPath.getStartPoint(), dotPath.getStartAngle() + Math.PI, ltail, link.getEntity1().isGroup()); - this.extremity1 = getExtremity(linkType.getHat1(), linkType.getDecor1(), pointListIterator, - dotPath.getEndPoint(), dotPath.getEndAngle(), lhead, link.getEntity2().isGroup()); + this.extremity1 = getExtremity(linkType.getDecor2(), pointListIterator, dotPath.getStartPoint(), + dotPath.getStartAngle() + Math.PI, ltail); + this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(), + dotPath.getEndAngle(), lhead); + if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) { + final Point2D p1 = ((Extremity) extremity1).somePoint(); + final Point2D p2 = ((Extremity) extremity2).somePoint(); + if (p1 != null && p2 != null) { + // http://plantuml.sourceforge.net/qa/?qa=4240/some-relations-point-wrong-direction-when-the-linetype-ortho + final double dist1start = p1.distance(dotPath.getStartPoint()); + final double dist1end = p1.distance(dotPath.getEndPoint()); + final double dist2start = p2.distance(dotPath.getStartPoint()); + final double dist2end = p2.distance(dotPath.getEndPoint()); + if (dist1start > dist1end && dist2end > dist2start) { + pointListIterator = new PointListIterator(svg.substring(end), fullHeight); + this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(), + dotPath.getEndAngle(), lhead); + this.extremity1 = getExtremity(linkType.getDecor2(), pointListIterator, dotPath.getStartPoint(), + dotPath.getStartAngle() + Math.PI, ltail); + } + } + + } if (this.labelText != null) { final Point2D pos = getXY(svg, this.noteLabelColor, fullHeight); @@ -581,8 +587,10 @@ public class Line implements Moveable, Hideable { if (link.isAutoLinkOfAGroup()) { final Cluster cl = bibliotekon.getCluster((IGroup) link.getEntity1()); - x += cl.getWidth(); - x -= dotPath.getStartPoint().getX() - cl.getMinX(); + if (cl != null) { + x += cl.getWidth(); + x -= dotPath.getStartPoint().getX() - cl.getMinX(); + } } x += dx; @@ -609,76 +617,45 @@ public class Line implements Moveable, Hideable { stroke = link.getColors().getSpecificLineStroke(); } ug = ug.apply(stroke); - double moveStartX = 0; - double moveStartY = 0; - double moveEndX = 0; double moveEndY = 0; - if (OptionFlags.USE_COMPOUND && projectionCluster != null && link.getEntity1() == projectionCluster.getGroup()) { - final DotPath copy = new DotPath(dotPath); - final Point2D start = copy.getStartPoint(); - final Point2D proj = projectionCluster.getClusterPosition().getProjectionOnFrontier(start); - moveStartX = proj.getX() - start.getX(); - moveStartY = proj.getY() - start.getY(); - copy.forceStartPoint(proj.getX(), proj.getY()); - ug.apply(new UTranslate(x, y)).draw(copy); - } else if (OptionFlags.USE_COMPOUND && projectionCluster != null - && link.getEntity2() == projectionCluster.getGroup()) { - final DotPath copy = new DotPath(dotPath); - final Point2D end = copy.getEndPoint(); - final Point2D proj = projectionCluster.getClusterPosition().getProjectionOnFrontier(end); - moveEndX = proj.getX() - end.getX(); - moveEndY = proj.getY() - end.getY(); - copy.forceEndPoint(proj.getX(), proj.getY()); - ug.apply(new UTranslate(x, y)).draw(copy); - } else { - if (dotPath == null) { - Log.info("DotPath is null for " + this); - return; - } - DotPath todraw = dotPath; - if (link.getEntity2().isGroup() && link.getEntity2().getUSymbol() instanceof USymbolFolder) { - final Cluster endCluster = bibliotekon.getCluster((IGroup) link.getEntity2()); - if (endCluster != null) { - final double deltaFolderH = endCluster.checkFolderPosition(dotPath.getEndPoint(), - ug.getStringBounder()); - todraw = new DotPath(dotPath); - todraw.moveEndPoint(0, deltaFolderH); - moveEndY = deltaFolderH; - } - } - ug.apply(new UTranslate(x, y)).draw(todraw); + if (dotPath == null) { + Log.info("DotPath is null for " + this); + return; + } + DotPath todraw = dotPath; + if (link.getEntity2().isGroup() && link.getEntity2().getUSymbol() instanceof USymbolFolder) { + final Cluster endCluster = bibliotekon.getCluster((IGroup) link.getEntity2()); + if (endCluster != null) { + final double deltaFolderH = endCluster + .checkFolderPosition(dotPath.getEndPoint(), ug.getStringBounder()); + todraw = new DotPath(dotPath); + todraw.moveEndPoint(0, deltaFolderH); + moveEndY = deltaFolderH; + } } + ug.apply(new UTranslate(x, y)).draw(todraw); + ug = ug.apply(new UStroke()).apply(new UChangeColor(color)); - if (this.extremity1 != null) { + if (this.extremity2 != null) { if (linkType.getDecor1().isFill()) { ug = ug.apply(new UChangeBackColor(color)); } else { ug = ug.apply(new UChangeBackColor(null)); } - if (OptionFlags.USE_COMPOUND || lhead == null) { - this.extremity1.drawU(ug.apply(new UTranslate(x + moveEndX, y + moveEndY))); - } else { - // System.err.println("Line::draw EXTREMITY1"); - this.extremity1.drawU(ug.apply(new UTranslate(x, y))); - } + // System.err.println("Line::draw EXTREMITY1"); + this.extremity2.drawU(ug.apply(new UTranslate(x, y))); } - if (this.extremity2 != null) { + if (this.extremity1 != null) { if (linkType.getDecor2().isFill()) { ug = ug.apply(new UChangeBackColor(color)); } else { ug = ug.apply(new UChangeBackColor(null)); } - if (OptionFlags.USE_COMPOUND || ltail == null) { - this.extremity2.drawU(ug.apply(new UTranslate(x + moveStartX, y + moveStartY))); - } else { - // System.err.println("Line::draw EXTREMITY2"); - this.extremity2.drawU(ug.apply(new UTranslate(x, y))); - // this.extremity2.drawU(ug.apply(new UTranslate(dotPath.getStartPoint()))); - - } + // System.err.println("Line::draw EXTREMITY2"); + this.extremity1.drawU(ug.apply(new UTranslate(x, y))); } if (this.labelText != null && this.labelXY != null) { this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX(), y diff --git a/src/net/sourceforge/plantuml/svek/SvekResult.java b/src/net/sourceforge/plantuml/svek/SvekResult.java index 12119eb..5ddb391 100644 --- a/src/net/sourceforge/plantuml/svek/SvekResult.java +++ b/src/net/sourceforge/plantuml/svek/SvekResult.java @@ -67,7 +67,7 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage, public void drawU(UGraphic ug) { for (Cluster cluster : dotStringFactory.getBibliotekon().allCluster()) { - cluster.drawU(ug, dotData, new UStroke(1.5)); + cluster.drawU(ug, new UStroke(1.5), dotData.getUmlDiagramType(), dotData.getSkinParam()); } final HtmlColor color = rose.getHtmlColor(dotData.getSkinParam(), getArrowColorParam(), null); diff --git a/src/net/sourceforge/plantuml/svek/extremity/Extremity.java b/src/net/sourceforge/plantuml/svek/extremity/Extremity.java index 1fd6afb..1d5acf7 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/Extremity.java +++ b/src/net/sourceforge/plantuml/svek/extremity/Extremity.java @@ -34,9 +34,11 @@ */ package net.sourceforge.plantuml.svek.extremity; +import java.awt.geom.Point2D; + import net.sourceforge.plantuml.graphic.UDrawable; -abstract class Extremity implements UDrawable { +public abstract class Extremity implements UDrawable { protected double manageround(double angle) { @@ -65,5 +67,7 @@ abstract class Extremity implements UDrawable { } return false; } + + public abstract Point2D somePoint(); } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrow.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrow.java index f52d702..717bb7b 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrow.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrow.java @@ -47,6 +47,12 @@ class ExtremityArrow extends Extremity { private UPolygon polygon = new UPolygon(); private final ULine line; private final Point2D contact; + + @Override + public Point2D somePoint() { + return contact; + } + public ExtremityArrow(Point2D p1, double angle, Point2D center) { angle = manageround(angle); @@ -87,4 +93,5 @@ class ExtremityArrow extends Extremity { } } + } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrowAndCircle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrowAndCircle.java index ab0b5e5..157b573 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrowAndCircle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityArrowAndCircle.java @@ -47,10 +47,15 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class ExtremityArrowAndCircle extends Extremity { private UPolygon polygon = new UPolygon(); - // private final ULine line; private final Point2D contact; private final Point2D dest; private final double radius = 5; + + @Override + public Point2D somePoint() { + return contact; + } + public ExtremityArrowAndCircle(Point2D p1, double angle, Point2D center) { angle = manageround(angle); diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java index 18afcb0..6d1e9a7 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java @@ -48,6 +48,11 @@ class ExtremityCircle extends Extremity { private final Point2D dest; private final double radius = 6; + @Override + public Point2D somePoint() { + return dest; + } + public ExtremityCircle(Point2D p1) { this.dest = new Point2D.Double(p1.getX(), p1.getY()); } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleConnect.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleConnect.java index 4fbea97..445b5b0 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleConnect.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleConnect.java @@ -52,6 +52,11 @@ class ExtremityCircleConnect extends Extremity { private final double radius2 = 10; private final double ortho; + @Override + public Point2D somePoint() { + return dest; + } + public ExtremityCircleConnect(Point2D p1, double ortho) { this.px = p1.getX() - radius; this.py = p1.getY() - radius; diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleCross.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleCross.java index d9f47c6..ff39c27 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleCross.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircleCross.java @@ -51,6 +51,11 @@ class ExtremityCircleCross extends Extremity { private final Point2D dest; private final double radius = 7; + @Override + public Point2D somePoint() { + return dest; + } + public ExtremityCircleCross(Point2D p1) { this.px = p1.getX() - radius; this.py = p1.getY() - radius; diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java index 71035d0..4637109 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java @@ -45,9 +45,17 @@ class ExtremityDiamond extends Extremity { private UPolygon polygon = new UPolygon(); private final boolean fill; + private final Point2D contact; + + @Override + public Point2D somePoint() { + return contact; + } + public ExtremityDiamond(Point2D p1, double angle, boolean fill) { this.fill = fill; + this.contact = new Point2D.Double(p1.getX(), p1.getY()); angle = manageround(angle); polygon.addPoint(0, 0); final int xAile = 6; diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactorySquarre.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactorySquarre.java index 24c0843..f464dde 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactorySquarre.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactorySquarre.java @@ -41,6 +41,10 @@ import net.sourceforge.plantuml.svek.AbstractExtremityFactory; public class ExtremityFactorySquarre extends AbstractExtremityFactory implements ExtremityFactory { + public UDrawable createUDrawable(Point2D p0, double angle) { + return new ExtremitySquarre(p0); + } + public UDrawable createUDrawable(Point2D p0, Point2D p1, Point2D p2) { // final double ortho = atan2(p0, p2); return new ExtremitySquarre(p1); diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis.java index 72868e1..694fccf 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis.java @@ -53,6 +53,12 @@ class ExtremityParenthesis extends Extremity { this.dest = new Point2D.Double(p1.getX(), p1.getY()); this.ortho = ortho; } + + @Override + public Point2D somePoint() { + return dest; + } + public void drawU(UGraphic ug) { final double deg = -ortho * 180 / Math.PI + 90 - ang; diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis2.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis2.java index 42ea28a..2486b65 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis2.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityParenthesis2.java @@ -62,6 +62,12 @@ class ExtremityParenthesis2 extends Extremity { final double len = Math.round(distance1 + EntityImageLollipopInterfaceEye2.SIZE / 2); this.center = new Point2D.Double(contact.getX() + dx / distance1 * len, contact.getY() + dy / distance1 * len); } + + @Override + public Point2D somePoint() { + return contact; + } + public void drawU(UGraphic ug) { final double deg = -ortho * 180 / Math.PI + 90 - ang; diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityPlus.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityPlus.java index 74a957d..15775cb 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityPlus.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityPlus.java @@ -58,6 +58,12 @@ class ExtremityPlus extends Extremity { this.px = x; this.py = y; } + + @Override + public Point2D somePoint() { + return new Point2D.Double(px, py); + } + public static UDrawable create(Point2D p1, double angle) { final double x = p1.getX() - radius + radius * Math.sin(angle); diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremitySquarre.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremitySquarre.java index a1a7353..e88369c 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremitySquarre.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremitySquarre.java @@ -48,6 +48,11 @@ class ExtremitySquarre extends Extremity { private final Point2D dest; private final double radius = 5; + @Override + public Point2D somePoint() { + return dest; + } + public ExtremitySquarre(Point2D p1) { this.dest = new Point2D.Double(p1.getX(), p1.getY()); } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine1.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine1.java index bd3d89c..e5294f5 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine1.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine1.java @@ -51,6 +51,12 @@ class ExtremityStateLine1 extends Extremity { private final Point2D dest; private final double radius = 7; private final double angle; + + @Override + public Point2D somePoint() { + return dest; + } + public ExtremityStateLine1(double angle, Point2D center) { this.angle = manageround(angle); diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine2.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine2.java index cb15e34..d71c546 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine2.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityStateLine2.java @@ -50,6 +50,12 @@ class ExtremityStateLine2 extends Extremity { private final Point2D dest; private final double radius = 5; private final double angle; + + @Override + public Point2D somePoint() { + return dest; + } + public ExtremityStateLine2(double angle, Point2D center) { this.angle = manageround(angle); diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityTriangle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityTriangle.java index 697908a..1680673 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityTriangle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityTriangle.java @@ -44,9 +44,17 @@ class ExtremityTriangle extends Extremity { private UPolygon polygon = new UPolygon(); private final boolean fill; + private final Point2D contact; + + @Override + public Point2D somePoint() { + return contact; + } + public ExtremityTriangle(Point2D p1, double angle, boolean fill) { this.fill = fill; + this.contact = new Point2D.Double(p1.getX(), p1.getY()); angle = manageround(angle); polygon.addPoint(0, 0); final int xAile = 8; diff --git a/src/net/sourceforge/plantuml/svek/extremity/MiddleCircle.java b/src/net/sourceforge/plantuml/svek/extremity/MiddleCircle.java index 5009888..bac6975 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/MiddleCircle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/MiddleCircle.java @@ -34,6 +34,8 @@ */ package net.sourceforge.plantuml.svek.extremity; +import java.awt.geom.Point2D; + import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UEllipse; @@ -45,6 +47,12 @@ class MiddleCircle extends Extremity { private final double radius = 6; private final UEllipse circle = new UEllipse(2 * radius, 2 * radius); + + @Override + public Point2D somePoint() { + return null; + } + public void drawU(UGraphic ug) { ug.apply(new UChangeBackColor(HtmlColorUtils.WHITE)).apply(new UStroke(1.5)).apply(new UTranslate(-radius, -radius)).draw(circle); diff --git a/src/net/sourceforge/plantuml/svek/extremity/MiddleCircleCircled.java b/src/net/sourceforge/plantuml/svek/extremity/MiddleCircleCircled.java index 0a41d45..5025d68 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/MiddleCircleCircled.java +++ b/src/net/sourceforge/plantuml/svek/extremity/MiddleCircleCircled.java @@ -34,6 +34,8 @@ */ package net.sourceforge.plantuml.svek.extremity; +import java.awt.geom.Point2D; + import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -56,6 +58,12 @@ class MiddleCircleCircled extends Extremity { this.angle = angle; this.mode = mode; } + + @Override + public Point2D somePoint() { + return null; + } + public void drawU(UGraphic ug) { ug = ug.apply(new UChangeBackColor(HtmlColorUtils.WHITE)); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java index a913668..d32ccd2 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java @@ -82,7 +82,7 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil { this.shield = version != null && version.useShield() && entity.hasNearDecoration() ? 16 : 0; 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); + this.body = entity.getBodier().getBody(FontParam.CLASS_ATTRIBUTE, getSkinParam(), showMethods, showFields, entity.getStereotype()); header = new EntityImageClassHeader2(entity, getSkinParam(), portionShower); this.url = entity.getUrl99(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java index 7759835..3aec624 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java @@ -122,7 +122,7 @@ public class EntityImageClassHeader2 extends AbstractEntityImage { private TextBlock getCircledCharacter(ILeaf entity, ISkinParam skinParam) { final Stereotype stereotype = entity.getStereotype(); if (stereotype != null && stereotype.getSprite() != null) { - return skinParam.getSprite(stereotype.getSprite()).asTextBlock(stereotype.getHtmlColor()); + return skinParam.getSprite(stereotype.getSprite()).asTextBlock(stereotype.getHtmlColor(), 1); } final UFont font = SkinParamUtils.getFont(getSkinParam(), FontParam.CIRCLED_CHARACTER, null); final HtmlColor classBorder = SkinParamUtils.getColor(getSkinParam(), ColorParam.classBorder, stereotype); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java index 5b6dddf..e912b99 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java @@ -102,7 +102,7 @@ public class EntityImageDescription extends AbstractEntityImage { if (stereotype != null && stereotype.getSprite() != null && getSkinParam().getSprite(stereotype.getSprite()) != null) { symbol = symbol.withStereoAlignment(HorizontalAlignment.RIGHT); - stereo = getSkinParam().getSprite(stereotype.getSprite()).asTextBlock(stereotype.getHtmlColor()); + stereo = getSkinParam().getSprite(stereotype.getSprite()).asTextBlock(stereotype.getHtmlColor(), 1); } else if (stereotype != null && stereotype.getLabel(false) != null && portionShower.showPortion(EntityPortion.STEREOTYPE, entity)) { stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())).create( diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java index 5107c78..43b9142 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java @@ -99,7 +99,7 @@ public class EntityImageObject extends AbstractEntityImage implements Stencil { if (entity.getBodier().getFieldsToDisplay().size() == 0) { this.fields = new TextBlockLineBefore(new TextBlockEmpty(10, 16)); } else { - this.fields = entity.getBodier().getBody(FontParam.OBJECT_ATTRIBUTE, skinParam, false, true); + this.fields = entity.getBodier().getBody(FontParam.OBJECT_ATTRIBUTE, skinParam, false, true, entity.getStereotype()); } this.url = entity.getUrl99(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java index 0d47a1e..8782e9f 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.cucadiagram.EntityPosition; import net.sourceforge.plantuml.cucadiagram.ILeaf; +import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -56,26 +57,24 @@ import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Cluster; import net.sourceforge.plantuml.svek.Shape; import net.sourceforge.plantuml.svek.ShapeType; -import net.sourceforge.plantuml.ugraphic.Shadowable; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; -import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; public class EntityImageStateBorder extends AbstractEntityImage { - public static final double RADIUS = 6; private final TextBlock desc; private final Cluster stateParent; private final EntityPosition entityPosition; private final Bibliotekon bibliotekon; + private final Rankdir rankdir; public EntityImageStateBorder(ILeaf leaf, ISkinParam skinParam, Cluster stateParent, final Bibliotekon bibliotekon) { super(leaf, skinParam); this.bibliotekon = bibliotekon; + this.rankdir = skinParam.getRankdir(); this.entityPosition = leaf.getEntityPosition(); if (entityPosition == EntityPosition.NORMAL) { @@ -95,7 +94,7 @@ public class EntityImageStateBorder extends AbstractEntityImage { } public Dimension2D calculateDimension(StringBounder stringBounder) { - return new Dimension2DDouble(RADIUS * 2, RADIUS * 2); + return entityPosition.getDimension(rankdir); } public double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) { @@ -104,18 +103,14 @@ public class EntityImageStateBorder extends AbstractEntityImage { } final public void drawU(UGraphic ug) { - final Shadowable circle = new UEllipse(RADIUS * 2, RADIUS * 2); - // if (getSkinParam().shadowing()) { - // circle.setDeltaShadow(4); - // } double y = 0; final Dimension2D dimDesc = desc.calculateDimension(ug.getStringBounder()); - final double x = 0 - (dimDesc.getWidth() - 2 * RADIUS) / 2; + final double x = 0 - (dimDesc.getWidth() - 2 * EntityPosition.RADIUS) / 2; if (upPosition()) { - y -= 2 * RADIUS + dimDesc.getHeight(); + y -= 2 * EntityPosition.RADIUS + dimDesc.getHeight(); } else { - y += 2 * RADIUS; + y += 2 * EntityPosition.RADIUS; } desc.drawU(ug.apply(new UTranslate(x, y))); @@ -127,33 +122,12 @@ public class EntityImageStateBorder extends AbstractEntityImage { } ug = ug.apply(new UChangeBackColor(backcolor)); - ug.draw(circle); - if (entityPosition == EntityPosition.EXIT_POINT) { - final double xc = 0 + RADIUS + .5; - final double yc = 0 + RADIUS + .5; - final double radius = RADIUS - .5; - drawLine(ug, getPointOnCircle(xc, yc, Math.PI / 4, radius), - getPointOnCircle(xc, yc, Math.PI + Math.PI / 4, radius)); - drawLine(ug, getPointOnCircle(xc, yc, -Math.PI / 4, radius), - getPointOnCircle(xc, yc, Math.PI - Math.PI / 4, radius)); - } - } - - private Point2D getPointOnCircle(double xc, double yc, double angle, double radius) { - final double x = xc + radius * Math.cos(angle); - final double y = yc + radius * Math.sin(angle); - return new Point2D.Double(x, y); - } - - static private void drawLine(UGraphic ug, Point2D p1, Point2D p2) { - final double dx = p2.getX() - p1.getX(); - final double dy = p2.getY() - p1.getY(); - ug.apply(new UTranslate(p1.getX(), p1.getY())).draw(new ULine(dx, dy)); + entityPosition.drawSymbol(ug, rankdir); } public ShapeType getShapeType() { - return ShapeType.CIRCLE; + return entityPosition.getShapeType(); } public int getShield() { diff --git a/src/net/sourceforge/plantuml/swing/ImageWindow2.java b/src/net/sourceforge/plantuml/swing/ImageWindow2.java index 672adf7..7f2a22c 100644 --- a/src/net/sourceforge/plantuml/swing/ImageWindow2.java +++ b/src/net/sourceforge/plantuml/swing/ImageWindow2.java @@ -286,7 +286,7 @@ class ImageWindow2 extends JFrame { final GraphicStrings error = GraphicStrings.createDefault(Arrays.asList(msg), false); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, error.getBackcolor(), null, null, 0, 0, null, false); - imageBuilder.addUDrawable(error); + imageBuilder.setUDrawable(error); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { imageBuilder.writeImageTOBEMOVED(new FileFormatOption(FileFormat.PNG), baos); diff --git a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java index 6466b1b..003d71f 100644 --- a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java +++ b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java @@ -57,6 +57,7 @@ public class TikzGraphics { // http://cremeronline.com/LaTeX/minimaltikz.pdf private final List cmd = new ArrayList(); + private final boolean withPreamble; private Color color = Color.BLACK; private Color fillcolor = Color.BLACK; @@ -65,6 +66,10 @@ public class TikzGraphics { private final Map colornames = new LinkedHashMap(); + public TikzGraphics(boolean withPreamble) { + this.withPreamble = withPreamble; + } + private String getColorName(Color c) { if (c.equals(Color.WHITE)) { return "white"; @@ -80,17 +85,18 @@ public class TikzGraphics { } public void createData(OutputStream os) throws IOException { - out(os, "\\documentclass{article}"); - out(os, "\\usepackage{tikz}"); - out(os, "\\usepackage{aeguill}"); - if (hasUrl) { - out(os, "\\usetikzlibrary{calc}"); - out(os, "\\usepackage{hyperref}"); + if (withPreamble) { + out(os, "\\documentclass{article}"); + out(os, "\\usepackage{tikz}"); + out(os, "\\usepackage{aeguill}"); + if (hasUrl) { + out(os, "\\usetikzlibrary{calc}"); + out(os, "\\usepackage{hyperref}"); + } + out(os, "\\begin{document}"); } - // out(os, "\\usetikzlibrary{trees}"); - out(os, "\\begin{document}"); out(os, "% generated by Plantuml " + Version.versionString(10)); - if (hasUrl) { + if (hasUrl && withPreamble) { out(os, "\\tikzset{"); out(os, " href node/.style={"); out(os, " alias=sourcenode,"); @@ -133,7 +139,9 @@ public class TikzGraphics { out(os, s); } out(os, "\\end{tikzpicture}"); - out(os, "\\end{document}"); + if (withPreamble) { + out(os, "\\end{document}"); + } } private String definecolor(String name, Color color) { diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java index 4a00609..286b95f 100644 --- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java +++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java @@ -169,7 +169,7 @@ public class FontChecker { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, null, null, 0, 0, null, false); final double dim = 20; - imageBuilder.addUDrawable(new UDrawable() { + imageBuilder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK)); ug.draw(new URectangle(dim - 1, dim - 1)); diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index a9925ec..f3fce49 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -91,17 +91,13 @@ public class ImageBuilder { private final String warningOrError; private final double margin1; private final double margin2; - private final Animation affineTransformations; + private final Animation animation; private final boolean useHandwritten; - // private final AffineTransform affineTransform; - // private final boolean withMetadata; - // private final boolean useRedForError; - private UDrawable udrawable; public ImageBuilder(ColorMapper colorMapper, double dpiFactor, HtmlColor mybackcolor, String metadata, - String warningOrError, double margin1, double margin2, Animation affineTransformations, + String warningOrError, double margin1, double margin2, Animation animation, boolean useHandwritten) { this.colorMapper = colorMapper; this.dpiFactor = dpiFactor; @@ -110,11 +106,11 @@ public class ImageBuilder { this.warningOrError = warningOrError; this.margin1 = margin1; this.margin2 = margin2; - this.affineTransformations = affineTransformations; + this.animation = animation; this.useHandwritten = useHandwritten; } - public void addUDrawable(UDrawable udrawable) { + public void setUDrawable(UDrawable udrawable) { this.udrawable = udrawable; } @@ -125,26 +121,23 @@ public class ImageBuilder { } else if (fileFormat == FileFormat.ANIMATED_GIF) { return writeImageAnimatedGif(os); } - return writeImageTOBEMOVED(fileFormatOption, os, affineTransformations); + return writeImageInternal(fileFormatOption, os, animation); } - private ImageData writeImageTOBEMOVED(FileFormatOption fileFormatOption, OutputStream os, Animation affineTransforms) + private ImageData writeImageInternal(FileFormatOption fileFormatOption, OutputStream os, Animation animationArg) throws IOException { - final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true); - udrawable.drawU(limitFinder); - Dimension2D dim = new Dimension2DDouble(limitFinder.getMaxX() + 1 + margin1 + margin2, limitFinder.getMaxY() - + 1 + margin1 + margin2); + Dimension2D dim = getFinalDimension(); double dx = 0; double dy = 0; - if (affineTransforms != null) { - final MinMax minmax = affineTransformations.getMinMax(dim); - affineTransforms.setDimension(dim); + if (animationArg != null) { + final MinMax minmax = animation.getMinMax(dim); + animationArg.setDimension(dim); dim = minmax.getDimension(); dx = -minmax.getMinX(); dy = -minmax.getMinY(); } - final UGraphic2 ug = createUGraphic(fileFormatOption, dim, affineTransforms, dx, dy); + final UGraphic2 ug = createUGraphic(fileFormatOption, dim, animationArg, dx, dy); final UGraphic ugDecored = handwritten(ug.apply(new UTranslate(margin1, margin1))); udrawable.drawU(ugDecored); ugDecored.flushUg(); @@ -162,6 +155,14 @@ public class ImageBuilder { return new ImageDataSimple(dim); } + public Dimension2D getFinalDimension() { + final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true); + udrawable.drawU(limitFinder); + Dimension2D dim = new Dimension2DDouble(limitFinder.getMaxX() + 1 + margin1 + margin2, limitFinder.getMaxY() + + 1 + margin1 + margin2); + return dim; + } + private UGraphic handwritten(UGraphic ug) { if (useHandwritten) { return new UGraphicHandwritten(ug); @@ -211,7 +212,7 @@ public class ImageBuilder { final Dimension2D dim = new Dimension2DDouble(limitFinder.getMaxX() + 1 + margin1 + margin2, limitFinder.getMaxY() + 1 + margin1 + margin2); - final MinMax minmax = affineTransformations.getMinMax(dim); + final MinMax minmax = animation.getMinMax(dim); final AnimatedGifEncoder e = new AnimatedGifEncoder(); // e.setQuality(1); @@ -222,7 +223,7 @@ public class ImageBuilder { e.setDelay(60); // 16 frame per sec // e.setDelay(50); // 20 frame per sec - for (AffineTransformation at : affineTransformations.getAll()) { + for (AffineTransformation at : animation.getAll()) { final ImageIcon ii = new ImageIcon(getAviImage(at)); e.addFrame((BufferedImage) ii.getImage()); } @@ -233,7 +234,7 @@ public class ImageBuilder { private Image getAviImage(AffineTransformation affineTransform) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeImageTOBEMOVED(new FileFormatOption(FileFormat.PNG), baos, Animation.singleton(affineTransform)); + writeImageInternal(new FileFormatOption(FileFormat.PNG), baos, Animation.singleton(affineTransform)); baos.close(); final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); @@ -243,11 +244,11 @@ public class ImageBuilder { } private UGraphic2 createUGraphic(FileFormatOption fileFormatOption, final Dimension2D dim, - Animation affineTransforms, double dx, double dy) { + Animation animationArg, double dx, double dy) { final FileFormat fileFormat = fileFormatOption.getFileFormat(); switch (fileFormat) { case PNG: - return createUGraphicPNG(colorMapper, dpiFactor, dim, mybackcolor, affineTransforms, dx, dy); + return createUGraphicPNG(colorMapper, dpiFactor, dim, mybackcolor, animationArg, dx, dy); case SVG: return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor, fileFormatOption.getSvgLinkTarget()); case EPS: @@ -259,7 +260,9 @@ public class ImageBuilder { case VDX: return new UGraphicVdx(colorMapper); case LATEX: - return new UGraphicTikz(colorMapper); + return new UGraphicTikz(colorMapper, true); + case LATEX_NO_PREAMBLE: + return new UGraphicTikz(colorMapper, false); default: throw new UnsupportedOperationException(fileFormat.toString()); } diff --git a/src/net/sourceforge/plantuml/ugraphic/UImage.java b/src/net/sourceforge/plantuml/ugraphic/UImage.java index 9834de0..2db8816 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UImage.java +++ b/src/net/sourceforge/plantuml/ugraphic/UImage.java @@ -34,6 +34,8 @@ */ package net.sourceforge.plantuml.ugraphic; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; public class UImage implements UShape { @@ -44,6 +46,25 @@ public class UImage implements UShape { this.image = image; } + public UImage(BufferedImage before, double scale) { + if (scale == 1) { + this.image = before; + return; + } + + final int w = (int) Math.round(before.getWidth() * scale); + final int h = (int) Math.round(before.getHeight() * scale); + final BufferedImage after = new BufferedImage(w, h, before.getType()); + final AffineTransform at = new AffineTransform(); + at.scale(scale, scale); + final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); + this.image = scaleOp.filter(before, after); + } + + public UImage scale(double scale) { + return new UImage(image, scale); + } + public final BufferedImage getImage() { return image; } diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextAsPathG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextAsPathG2d.java index 0d1259d..29f4a6c 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextAsPathG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextAsPathG2d.java @@ -83,7 +83,7 @@ public class DriverTextAsPathG2d implements UDriver { final FontConfiguration fontConfiguration = shape.getFontConfiguration(); final UFont font = fontConfiguration.getFont().scaled(param.getScale()); - final Dimension2D dimBack = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dimBack = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) { final Color extended = mapper.getMappedColor(fontConfiguration.getExtendedColor()); if (extended != null) { @@ -108,14 +108,14 @@ public class DriverTextAsPathG2d implements UDriver { if (extended != null) { g2d.setColor(mapper.getMappedColor(extended)); } - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final int ypos = (int) (y + 2.5); g2d.setStroke(new BasicStroke((float) 1)); g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); g2d.setStroke(new BasicStroke()); } if (fontConfiguration.containsStyle(FontStyle.WAVE)) { - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final int ypos = (int) (y + 2.5) - 1; final HtmlColor extended = fontConfiguration.getExtendedColor(); if (extended != null) { @@ -127,7 +127,7 @@ public class DriverTextAsPathG2d implements UDriver { } } if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final FontMetrics fm = g2d.getFontMetrics(font.getFont()); final int ypos = (int) (y - fm.getDescent() - 0.5); final HtmlColor extended = fontConfiguration.getExtendedColor(); diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java index 28c6b9c..81db80a 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java @@ -79,7 +79,7 @@ public class DriverTextG2d implements UDriver { final FontConfiguration fontConfiguration = shape.getFontConfiguration(); final UFont font = fontConfiguration.getFont().scaled(param.getScale()); - final Dimension2D dimBack = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dimBack = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) { final Color extended = mapper.getMappedColor(fontConfiguration.getExtendedColor()); if (extended != null) { @@ -101,14 +101,14 @@ public class DriverTextG2d implements UDriver { if (extended != null) { g2d.setColor(mapper.getMappedColor(extended)); } - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final int ypos = (int) (y + 2.5); g2d.setStroke(new BasicStroke((float) 1)); g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); g2d.setStroke(new BasicStroke()); } if (fontConfiguration.containsStyle(FontStyle.WAVE)) { - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final int ypos = (int) (y + 2.5) - 1; final HtmlColor extended = fontConfiguration.getExtendedColor(); if (extended != null) { @@ -120,7 +120,7 @@ public class DriverTextG2d implements UDriver { } } if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { - final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(), font, shape.getText()); final FontMetrics fm = g2d.getFontMetrics(font.getFont()); final int ypos = (int) (y - fm.getDescent() - 0.5); final HtmlColor extended = fontConfiguration.getExtendedColor(); diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java index 7b0d0af..f905fc9 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java @@ -157,7 +157,7 @@ public class UGraphicG2d extends AbstractUGraphic implements EnsureV if (hasAffineTransform) { return TextBlockUtils.getDummyStringBounder(); } - return StringBounderUtils.asStringBounder(getGraphicObject()); + return StringBounderUtils.asStringBounder(); } @Override diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/PSystemListInternalSprites.java b/src/net/sourceforge/plantuml/ugraphic/sprite/PSystemListInternalSprites.java index bf608c0..9cec515 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/PSystemListInternalSprites.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/PSystemListInternalSprites.java @@ -59,7 +59,7 @@ public class PSystemListInternalSprites extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/Sprite.java b/src/net/sourceforge/plantuml/ugraphic/sprite/Sprite.java index a32a62f..ff600b5 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/Sprite.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/Sprite.java @@ -39,6 +39,6 @@ import net.sourceforge.plantuml.graphic.TextBlock; public interface Sprite { - public TextBlock asTextBlock(final HtmlColor color); + public TextBlock asTextBlock(final HtmlColor color, double scale); } diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteImage.java b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteImage.java index 8eb6653..626c0b5 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteImage.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteImage.java @@ -57,15 +57,15 @@ public class SpriteImage implements Sprite { this.img = new UImage(img); } - public TextBlock asTextBlock(final HtmlColor color) { + public TextBlock asTextBlock(final HtmlColor color, final double scale) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { - ug.draw(img); + ug.draw(img.scale(scale)); } public Dimension2D calculateDimension(StringBounder stringBounder) { - return new Dimension2DDouble(img.getWidth(), img.getHeight()); + return new Dimension2DDouble(img.getWidth() * scale, img.getHeight() * scale); } }; } diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteMonochrome.java b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteMonochrome.java index d7b9749..51fcaa6 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteMonochrome.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteMonochrome.java @@ -107,15 +107,16 @@ public class SpriteMonochrome implements Sprite { return new UImage(im); } - public TextBlock asTextBlock(final HtmlColor color) { + public TextBlock asTextBlock(final HtmlColor color, final double scale) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { - ug.draw(toUImage(ug.getColorMapper(), ug.getParam().getBackcolor(), color)); + final UImage image = toUImage(ug.getColorMapper(), ug.getParam().getBackcolor(), color); + ug.draw(image.scale(scale)); } public Dimension2D calculateDimension(StringBounder stringBounder) { - return new Dimension2DDouble(getWidth(), getHeight()); + return new Dimension2DDouble(getWidth() * scale, getHeight() * scale); } }; } diff --git a/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java b/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java index 74a74dc..3f8a0d7 100644 --- a/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java +++ b/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java @@ -69,8 +69,8 @@ public class UGraphicTikz extends AbstractUGraphic implements Clip } - public UGraphicTikz(ColorMapper colorMapper) { - this(colorMapper, new TikzGraphics()); + public UGraphicTikz(ColorMapper colorMapper, boolean withPreamble) { + this(colorMapper, new TikzGraphics(withPreamble)); } diff --git a/src/net/sourceforge/plantuml/version/PSystemLicense.java b/src/net/sourceforge/plantuml/version/PSystemLicense.java index 3a7d062..a5b7a7f 100644 --- a/src/net/sourceforge/plantuml/version/PSystemLicense.java +++ b/src/net/sourceforge/plantuml/version/PSystemLicense.java @@ -65,7 +65,7 @@ public class PSystemLicense extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index 56e4972..7e53415 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -141,7 +141,7 @@ public class PSystemVersion extends AbstractPSystem { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); - imageBuilder.addUDrawable(result); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } @@ -178,7 +178,7 @@ public class PSystemVersion extends AbstractPSystem { strings.add("Logo: Benjamin Croizet"); strings.add(" "); - strings.add("http://plantuml.sourceforge.net"); + strings.add("http://plantuml.com"); strings.add(" "); return new PSystemVersion(true, strings); } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 386c3b2..18b4679 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -40,11 +40,11 @@ import java.util.Date; public class Version { public static int version() { - return 8036; + return 8038; } public static String versionString() { - if (beta() != 0) { + if (beta() != 1) { return "" + (version() + 1) + "beta" + beta(); } return "" + version(); @@ -64,7 +64,7 @@ public class Version { } private static long compileTime() { - return 1454874605178L; + return 1459789355152L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/version/out.png b/src/net/sourceforge/plantuml/version/out.png index 4bd1fac..7072f10 100644 Binary files a/src/net/sourceforge/plantuml/version/out.png and b/src/net/sourceforge/plantuml/version/out.png differ diff --git a/src/net/sourceforge/plantuml/webp/Portrait.java b/src/net/sourceforge/plantuml/webp/Portrait.java index 85ef65b..1c48677 100644 --- a/src/net/sourceforge/plantuml/webp/Portrait.java +++ b/src/net/sourceforge/plantuml/webp/Portrait.java @@ -46,10 +46,12 @@ public class Portrait { private final String name; private final int age; + private final String quote; private final byte webp[]; - public Portrait(String name, int age, byte webp[]) throws IOException { + public Portrait(String name, int age, String quote, byte webp[]) throws IOException { this.name = name; + this.quote = quote; this.age = age; this.webp = webp; } @@ -76,4 +78,8 @@ public class Portrait { return age; } + public String getQuote() { + return quote; + } + } diff --git a/src/net/sourceforge/plantuml/webp/Portraits.java b/src/net/sourceforge/plantuml/webp/Portraits.java index fcedb90..db0d93e 100644 --- a/src/net/sourceforge/plantuml/webp/Portraits.java +++ b/src/net/sourceforge/plantuml/webp/Portraits.java @@ -37,24 +37,26 @@ package net.sourceforge.plantuml.webp; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; +import java.text.Normalizer; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Locale; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; import net.sourceforge.plantuml.version.PSystemVersion; public class Portraits { - private final List all = new ArrayList(); - - public void all(Portrait p) { - all.add(p); - } + private final static List all = new ArrayList(); + private final static AtomicInteger current = new AtomicInteger(); private static InputStream getInputStream() { return PSystemVersion.class.getResourceAsStream("out.png"); } - public Portraits() { + static { final InputStream is = getInputStream(); if (is != null) { try { @@ -72,33 +74,81 @@ public class Portraits { } - private void read(InputStream is) throws IOException { + private static void read(InputStream is) throws IOException { final DataInputStream dis = new DataInputStream(is); final int nb = dis.readShort(); final List names = new ArrayList(); final List ages = new ArrayList(); + final List quotes = new ArrayList(); for (int i = 0; i < nb; i++) { names.add(dis.readUTF()); ages.add((int) dis.readByte()); + quotes.add(dis.readUTF()); } for (int i = 0; i < nb; i++) { final int len = dis.readShort(); final byte data[] = new byte[len]; dis.readFully(data); - all.add(new Portrait(names.get(i), ages.get(i), data)); + all.add(new Portrait(names.get(i), ages.get(i), quotes.get(i), data)); } + Collections.shuffle(all); } - public static void main(String[] args) { - final Portraits p = new Portraits(); - System.err.println(p.all); - } - - public Portrait getOne() { + public static Portrait getOne() { if (all.size() == 0) { return null; } - return all.get(0); + final int nb = current.get() % all.size(); + return all.get(nb); + } + + public static void nextOne() { + current.getAndIncrement(); + } + + public static Portrait getOne(String line) { + Portrait candidat = null; + for (Portrait p : all) { + final int dist = similar(p.getName(), line); + if (dist <= 3) { + if (candidat != null && dist < similar(candidat.getName(), line)) { + continue; + } + candidat = p; + } + } + return candidat; } + public static int similar(String s1, String s2) { + final int[] tab1 = countLetter(s1); + final int[] tab2 = countLetter(s2); + int result = 0; + for (int i = 0; i < tab1.length; i++) { + result += Math.abs(tab1[i] - tab2[i]); + } + return result; + } + + private static String noAccent(String str) { + final String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); + final Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); + return pattern.matcher(nfdNormalizedString).replaceAll(""); + } + + private static int[] countLetter(String s) { + s = noAccent(s).toLowerCase(Locale.US); + final int[] result = new int[26]; + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + if (c >= 'a' && c <= 'z') { + result[c - 'a']++; + } + } + return result; + } + + static final List getAll() { + return all; + } } diff --git a/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java b/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java index 6fec7d8..0d05c66 100644 --- a/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java +++ b/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.statediagram.StateDiagram; public final class CucaDiagramXmiMaker { @@ -58,7 +59,9 @@ public final class CucaDiagramXmiMaker { public void createFiles(OutputStream fos) throws IOException { try { final IXmiClassDiagram xmi; - if (fileFormat == FileFormat.XMI_STANDARD) { + if (diagram instanceof StateDiagram) { + xmi = new XmiStateDiagram((StateDiagram) diagram); + } else if (fileFormat == FileFormat.XMI_STANDARD) { xmi = new XmiClassDiagramStandard((ClassDiagram) diagram); } else if (fileFormat == FileFormat.XMI_ARGO) { xmi = new XmiClassDiagramArgo((ClassDiagram) diagram); @@ -68,8 +71,6 @@ public final class CucaDiagramXmiMaker { throw new UnsupportedOperationException(); } xmi.transformerXml(fos); - // fos.close(); - // return Collections.singletonList(suggestedFile); } catch (ParserConfigurationException e) { Log.error(e.toString()); e.printStackTrace(); diff --git a/src/net/sourceforge/plantuml/xmi/XmiClassDiagramStar.java b/src/net/sourceforge/plantuml/xmi/XmiClassDiagramStar.java index 260b59e..2a549f0 100644 --- a/src/net/sourceforge/plantuml/xmi/XmiClassDiagramStar.java +++ b/src/net/sourceforge/plantuml/xmi/XmiClassDiagramStar.java @@ -122,14 +122,14 @@ public class XmiClassDiagramStar implements IXmiClassDiagram { // } } -// private boolean isStandalone(IEntity ent) { -// for (final Link link : classDiagram.getLinks()) { -// if (link.getEntity1() == ent || link.getEntity2() == ent) { -// return false; -// } -// } -// return true; -// } + // private boolean isStandalone(IEntity ent) { + // for (final Link link : classDiagram.getLinks()) { + // if (link.getEntity1() == ent || link.getEntity2() == ent) { + // return false; + // } + // } + // return true; + // } public static String forXMI(String s) { return s.replace(':', ' '); @@ -148,7 +148,7 @@ public class XmiClassDiagramStar implements IXmiClassDiagram { final Element association = document.createElement("UML:Association"); association.setAttribute("xmi.id", assId); association.setAttribute("namespace", "model1"); - if (link.getLabel() != null) { + if (Display.isNull(link.getLabel()) == false) { association.setAttribute("name", forXMI(link.getLabel())); } diff --git a/src/net/sourceforge/plantuml/xmi/XmiStateDiagram.java b/src/net/sourceforge/plantuml/xmi/XmiStateDiagram.java new file mode 100644 index 0000000..8213849 --- /dev/null +++ b/src/net/sourceforge/plantuml/xmi/XmiStateDiagram.java @@ -0,0 +1,256 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * This file is part of PlantUML. + * + * Licensed under The MIT License (Massachusetts Institute of Technology License) + * + * See http://opensource.org/licenses/MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Original Author: Arnaud Roques + */ +package net.sourceforge.plantuml.xmi; + +import java.io.OutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.GroupRoot; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.IGroup; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.statediagram.StateDiagram; +import net.sourceforge.plantuml.utils.UniqueSequence; +import net.sourceforge.plantuml.version.Version; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class XmiStateDiagram implements IXmiClassDiagram { + + private final StateDiagram diagram; + private final Document document; + private final Element ownedElement; + + public XmiStateDiagram(StateDiagram diagram) throws ParserConfigurationException { + this.diagram = diagram; + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + final DocumentBuilder builder = factory.newDocumentBuilder(); + this.document = builder.newDocument(); + document.setXmlVersion("1.0"); + document.setXmlStandalone(true); + + final Element xmi = document.createElement("XMI"); + xmi.setAttribute("xmi.version", "1.1"); + xmi.setAttribute("xmlns:UML", "href://org.omg/UML/1.3"); + document.appendChild(xmi); + + final Element header = document.createElement("XMI.header"); + xmi.appendChild(header); + + final Element metamodel = document.createElement("XMI.metamodel"); + metamodel.setAttribute("xmi.name", "UML"); + metamodel.setAttribute("xmi.version", "1.3"); + header.appendChild(metamodel); + + final Element content = document.createElement("XMI.content"); + xmi.appendChild(content); + + // + final Element model = document.createElement("UML:Model"); + model.setAttribute("xmi.id", "model1"); + model.setAttribute("name", "PlantUML "+Version.versionString()); + content.appendChild(model); + + // + this.ownedElement = document.createElement("UML:Namespace.ownedElement"); + model.appendChild(ownedElement); + + for (final IGroup gr : diagram.getGroups(false)) { + if (gr.getParentContainer() instanceof GroupRoot) { + addState(gr, ownedElement); + } + } + + for (final IEntity ent : diagram.getLeafsvalues()) { + if (ent.getParentContainer() instanceof GroupRoot) { + addState(ent, ownedElement); + } + } + + for (final Link link : diagram.getLinks()) { + addLink(link); + } + } + + private void addState(final IEntity tobeAdded, Element container) { + final Element elementState = createEntityNode(tobeAdded); + container.appendChild(elementState); + for (final IEntity ent : diagram.getGroups(false)) { + if (ent.getParentContainer() == tobeAdded) { + addState(ent, elementState); + } + } + for (final IEntity ent : diagram.getLeafsvalues()) { + if (ent.getParentContainer() == tobeAdded) { + addState(ent, elementState); + } + } + } + + public static String forXMI(String s) { + return s.replace(':', ' '); + } + + public static String forXMI(Display s) { + return s.get(0).toString().replace(':', ' '); + } + + private void addLink(Link link) { + final String assId = "ass" + UniqueSequence.getValue(); + + final Element association = document.createElement("UML:Association"); + association.setAttribute("xmi.id", assId); + association.setAttribute("namespace", "model1"); + if (Display.isNull(link.getLabel()) == false) { + association.setAttribute("name", forXMI(link.getLabel())); + } + + final Element connection = document.createElement("UML:Association.connection"); + final Element end1 = document.createElement("UML:AssociationEnd"); + end1.setAttribute("xmi.id", "end" + UniqueSequence.getValue()); + end1.setAttribute("association", assId); + end1.setAttribute("type", link.getEntity1().getUid()); + if (link.getQualifier1() != null) { + end1.setAttribute("name", forXMI(link.getQualifier1())); + } + final Element endparticipant1 = document.createElement("UML:AssociationEnd.participant"); + + if (link.getType().getDecor2() == LinkDecor.COMPOSITION) { + end1.setAttribute("aggregation", "composite"); + } + if (link.getType().getDecor2() == LinkDecor.AGREGATION) { + end1.setAttribute("aggregation", "aggregate"); + } + // } + end1.appendChild(endparticipant1); + connection.appendChild(end1); + + final Element end2 = document.createElement("UML:AssociationEnd"); + end2.setAttribute("xmi.id", "end" + UniqueSequence.getValue()); + end2.setAttribute("association", assId); + end2.setAttribute("type", link.getEntity2().getUid()); + if (link.getQualifier2() != null) { + end2.setAttribute("name", forXMI(link.getQualifier2())); + } + final Element endparticipant2 = document.createElement("UML:AssociationEnd.participant"); + if (link.getType().getDecor1() == LinkDecor.COMPOSITION) { + end2.setAttribute("aggregation", "composite"); + } + if (link.getType().getDecor1() == LinkDecor.AGREGATION) { + end2.setAttribute("aggregation", "aggregate"); + } + // } + end2.appendChild(endparticipant2); + connection.appendChild(end2); + + association.appendChild(connection); + + ownedElement.appendChild(association); + + } + + private Element createEntityNode(IEntity entity) { + // + final Element cla = document.createElement("UML:State"); + + cla.setAttribute("xmi.id", entity.getUid()); + cla.setAttribute("name", entity.getDisplay().get(0).toString()); + cla.setAttribute("namespace", "model1"); + + final Element feature = document.createElement("UML:Classifier.feature"); + cla.appendChild(feature); + + for (Member m : entity.getBodier().getFieldsToDisplay()) { + // + final Element attribute = document.createElement("UML:Attribute"); + attribute.setAttribute("xmi.id", "att" + UniqueSequence.getValue()); + attribute.setAttribute("name", m.getDisplay(false)); + feature.appendChild(attribute); + } + + for (Member m : entity.getBodier().getMethodsToDisplay()) { + // + final Element operation = document.createElement("UML:Operation"); + operation.setAttribute("xmi.id", "att" + UniqueSequence.getValue()); + operation.setAttribute("name", m.getDisplay(false)); + feature.appendChild(operation); + } + return cla; + } + + public void transformerXml(OutputStream os) throws TransformerException, ParserConfigurationException { + final Source source = new DOMSource(document); + + final Result resultat = new StreamResult(os); + + final TransformerFactory fabrique = TransformerFactory.newInstance(); + final Transformer transformer = fabrique.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + // transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + // tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.transform(source, resultat); + } + +} -- cgit v1.2.3