1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-11 16:15:50 +00:00

version 1.2017.19

This commit is contained in:
Arnaud Roques 2017-11-20 17:10:36 +01:00
parent 4b65d2140f
commit a628cfdb76
1028 changed files with 55366 additions and 397 deletions

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId> <groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId> <artifactId>plantuml</artifactId>
<version>1.2017.19-SNAPSHOT</version> <version>1.2017.20-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>PlantUML</name> <name>PlantUML</name>
@ -120,6 +120,12 @@
<include>net/sourceforge/plantuml/math/*.js</include> <include>net/sourceforge/plantuml/math/*.js</include>
</includes> </includes>
</resource> </resource>
<resource>
<directory>${project.basedir}</directory>
<includes>
<include>stdlib/**/*.puml</include>
</includes>
</resource>
</resources> </resources>
<plugins> <plugins>
<plugin> <plugin>

View File

@ -39,7 +39,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -65,8 +64,8 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
this.defines = defines; this.defines = defines;
try { try {
reader2 = new UncommentReadLine(new ReadLineReader(reader, desc)); reader2 = new UncommentReadLine(new ReadLineReader(reader, desc));
includer = new Preprocessor(reader2, charset, defines, newCurrentDir, this); includer = new Preprocessor(config, reader2, charset, defines, newCurrentDir, this);
init(includer, config); init(includer);
} finally { } finally {
if (includer != null) { if (includer != null) {
includer.close(); includer.close();
@ -79,7 +78,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
this(config, charset, defines, reader, null, null); this(config, charset, defines, reader, null, null);
} }
private void init(Preprocessor includer, List<String> config) throws IOException { private void init(Preprocessor includer) throws IOException {
CharSequence2 s = null; CharSequence2 s = null;
List<CharSequence2> current2 = null; List<CharSequence2> current2 = null;
boolean paused = false; boolean paused = false;
@ -108,21 +107,21 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
reader2.setPaused(false); reader2.setPaused(false);
} }
if (StartUtils.isArobaseEndDiagram(s) && current2 != null) { if (StartUtils.isArobaseEndDiagram(s) && current2 != null) {
current2.addAll(1, convert(config, new LineLocationImpl(null, null).oneLineRead())); // current2.addAll(1, convert(config, new LineLocationImpl(null, null).oneLineRead()));
blocks.add(new BlockUml(current2, startLine - config.size(), defines.cloneMe())); blocks.add(new BlockUml(current2, startLine/* - config.size() */, defines.cloneMe()));
current2 = null; current2 = null;
reader2.setPaused(false); reader2.setPaused(false);
} }
} }
} }
private Collection<CharSequence2> convert(List<String> config, LineLocation location) { // private Collection<CharSequence2> convert(List<String> config, LineLocation location) {
final List<CharSequence2> result = new ArrayList<CharSequence2>(); // final List<CharSequence2> result = new ArrayList<CharSequence2>();
for (String s : config) { // for (String s : config) {
result.add(new CharSequence2Impl(s, location)); // result.add(new CharSequence2Impl(s, location));
} // }
return result; // return result;
} // }
public List<BlockUml> getBlockUmls() { public List<BlockUml> getBlockUmls() {
return Collections.unmodifiableList(blocks); return Collections.unmodifiableList(blocks);

View File

@ -282,8 +282,8 @@ public class Option {
OptionFlags.getInstance().setGui(true); OptionFlags.getInstance().setGui(true);
} else if (s.equalsIgnoreCase("-encodesprite")) { } else if (s.equalsIgnoreCase("-encodesprite")) {
OptionFlags.getInstance().setEncodesprite(true); OptionFlags.getInstance().setEncodesprite(true);
} else if (s.equalsIgnoreCase("-nosuggestengine")) { // } else if (s.equalsIgnoreCase("-nosuggestengine")) {
OptionFlags.getInstance().setUseSuggestEngine(false); // OptionFlags.getInstance().setUseSuggestEngine(false);
} else if (s.equalsIgnoreCase("-printfonts")) { } else if (s.equalsIgnoreCase("-printfonts")) {
OptionFlags.getInstance().setPrintFonts(true); OptionFlags.getInstance().setPrintFonts(true);
} else if (s.equalsIgnoreCase("-dumphtmlstats")) { } else if (s.equalsIgnoreCase("-dumphtmlstats")) {

View File

@ -97,7 +97,7 @@ public class OptionFlags {
quiet = false; quiet = false;
checkDotError = false; checkDotError = false;
printFonts = false; printFonts = false;
useSuggestEngine = true; // useSuggestEngine = true;
// failOnError = false; // failOnError = false;
encodesprite = false; encodesprite = false;
// PIC_LINE = false; // PIC_LINE = false;
@ -116,7 +116,7 @@ public class OptionFlags {
private boolean quiet; private boolean quiet;
private boolean checkDotError; private boolean checkDotError;
private boolean printFonts; private boolean printFonts;
private boolean useSuggestEngine; // private boolean useSuggestEngine;
private boolean encodesprite; private boolean encodesprite;
private boolean dumpHtmlStats; private boolean dumpHtmlStats;
private boolean dumpStats; private boolean dumpStats;
@ -250,13 +250,17 @@ public class OptionFlags {
this.printFonts = printFonts; this.printFonts = printFonts;
} }
public final boolean isUseSuggestEngine() { public final boolean isUseSuggestEngine2() {
return useSuggestEngine; return false;
} }
public final void setUseSuggestEngine(boolean useSuggestEngine) { // public final boolean isUseSuggestEngine() {
this.useSuggestEngine = useSuggestEngine; // return useSuggestEngine;
} // }
//
// public final void setUseSuggestEngine(boolean useSuggestEngine) {
// this.useSuggestEngine = useSuggestEngine;
// }
public final boolean isEncodesprite() { public final boolean isEncodesprite() {
return encodesprite; return encodesprite;

View File

@ -119,7 +119,7 @@ public class OptionPrint {
System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL"); System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images"); System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
System.out.println(" -language\t\tTo print the list of PlantUML keywords"); System.out.println(" -language\t\tTo print the list of PlantUML keywords");
System.out.println(" -nosuggestengine\tTo disable the suggest engine when errors in diagrams"); // System.out.println(" -nosuggestengine\tTo disable the suggest engine when errors in diagrams");
System.out.println(" -checkonly\t\tTo check the syntax of files without generating images"); System.out.println(" -checkonly\t\tTo check the syntax of files without generating images");
System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs"); System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs");
System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster"); System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster");

View File

@ -57,6 +57,7 @@ import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory;
import net.sourceforge.plantuml.directdot.PSystemDotFactory; import net.sourceforge.plantuml.directdot.PSystemDotFactory;
import net.sourceforge.plantuml.ditaa.PSystemDitaaFactory; import net.sourceforge.plantuml.ditaa.PSystemDitaaFactory;
import net.sourceforge.plantuml.donors.PSystemDonorsFactory; import net.sourceforge.plantuml.donors.PSystemDonorsFactory;
import net.sourceforge.plantuml.donors.PSystemSkinparameterListFactory;
import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory; import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory;
import net.sourceforge.plantuml.eggs.PSystemCharlieFactory; import net.sourceforge.plantuml.eggs.PSystemCharlieFactory;
import net.sourceforge.plantuml.eggs.PSystemColorsFactory; import net.sourceforge.plantuml.eggs.PSystemColorsFactory;
@ -157,6 +158,7 @@ public class PSystemBuilder {
factories.add(new PSystemLicenseFactory()); factories.add(new PSystemLicenseFactory());
factories.add(new PSystemVersionFactory()); factories.add(new PSystemVersionFactory());
factories.add(new PSystemDonorsFactory()); factories.add(new PSystemDonorsFactory());
factories.add(new PSystemSkinparameterListFactory());
factories.add(new PSystemListFontsFactory()); factories.add(new PSystemListFontsFactory());
factories.add(new PSystemOpenIconicFactory()); factories.add(new PSystemOpenIconicFactory());
factories.add(new PSystemListOpenIconicFactory()); factories.add(new PSystemListOpenIconicFactory());
@ -188,7 +190,8 @@ public class PSystemBuilder {
if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) { if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) {
factories.add(new PSystemXearthFactory()); factories.add(new PSystemXearthFactory());
} }
factories.add(new GanttDiagramFactory()); factories.add(new GanttDiagramFactory(DiagramType.GANTT));
factories.add(new GanttDiagramFactory(DiagramType.UML));
factories.add(new FlowDiagramFactory()); factories.add(new FlowDiagramFactory());
factories.add(new PSystemTreeFactory(DiagramType.JUNGLE)); factories.add(new PSystemTreeFactory(DiagramType.JUNGLE));
factories.add(new PSystemCuteFactory(DiagramType.CUTE)); factories.add(new PSystemCuteFactory(DiagramType.CUTE));

View File

@ -65,6 +65,7 @@ import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder; import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage; import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -185,6 +186,10 @@ public class PSystemError extends AbstractPSystem {
return new Dimension2DDouble(imWidth + 1, imHeight + 1); return new Dimension2DDouble(imWidth + 1, imHeight + 1);
} }
public MinMax getMinMax(StringBounder stringBounder) {
return MinMax.fromMax(imWidth + 1, imHeight + 1);
}
public HtmlColor getBackcolor() { public HtmlColor getBackcolor() {
return backImage; return backImage;
} }

View File

@ -50,6 +50,7 @@ import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2; import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.creole.CommandCreoleMonospaced; import net.sourceforge.plantuml.creole.CommandCreoleMonospaced;
import net.sourceforge.plantuml.cucadiagram.LinkStyle;
import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Rankdir;
import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.cucadiagram.dot.DotSplines; import net.sourceforge.plantuml.cucadiagram.dot.DotSplines;
@ -112,7 +113,18 @@ public class SkinParam implements ISkinParam {
return result; return result;
} }
static List<String> cleanForKey(String key) { private final Map<String, List<String>> cacheCleanForKey = new HashMap<String, List<String>>();
List<String> cleanForKey(String key) {
List<String> result = cacheCleanForKey.get(key);
if (result == null) {
result = cleanForKeySlow(key);
cacheCleanForKey.put(key, result);
}
return result;
}
List<String> cleanForKeySlow(String key) {
key = StringUtils.trin(StringUtils.goLowerCase(key)); key = StringUtils.trin(StringUtils.goLowerCase(key));
key = key.replaceAll("_|\\.|\\s", ""); key = key.replaceAll("_|\\.|\\s", "");
// key = replaceSmart(key, "partition", "package"); // key = replaceSmart(key, "partition", "package");
@ -134,7 +146,7 @@ public class SkinParam implements ISkinParam {
if (result.size() == 0) { if (result.size() == 0) {
result.add(key); result.add(key);
} }
return result; return Collections.unmodifiableList(result);
} }
private static String replaceSmart(String s, String src, String target) { private static String replaceSmart(String s, String src, String target) {
@ -200,7 +212,7 @@ public class SkinParam implements ISkinParam {
return null; return null;
} }
final boolean acceptTransparent = param == ColorParam.background final boolean acceptTransparent = param == ColorParam.background
|| param == ColorParam.sequenceGroupBodyBackground; || param == ColorParam.sequenceGroupBodyBackground || param == ColorParam.sequenceBoxBackground;
return getIHtmlColorSet().getColorIfValid(value, acceptTransparent); return getIHtmlColorSet().getColorIfValid(value, acceptTransparent);
} }
@ -643,16 +655,38 @@ public class SkinParam implements ISkinParam {
} }
public UStroke getThickness(LineParam param, Stereotype stereotype) { public UStroke getThickness(LineParam param, Stereotype stereotype) {
LinkStyle style = null;
if (stereotype != null) { if (stereotype != null) {
checkStereotype(stereotype); checkStereotype(stereotype);
final String styleValue = getValue(param.name() + "style" + stereotype.getLabel(false));
if (styleValue != null) {
style = LinkStyle.fromString2(styleValue);
}
final String value2 = getValue(param.name() + "thickness" + stereotype.getLabel(false)); final String value2 = getValue(param.name() + "thickness" + stereotype.getLabel(false));
if (value2 != null && value2.matches("[\\d.]+")) { if (value2 != null && value2.matches("[\\d.]+")) {
return new UStroke(Double.parseDouble(value2)); if (style == null) {
style = LinkStyle.NORMAL();
}
return style.goThickness(Double.parseDouble(value2)).getStroke3();
} }
} }
final String value = getValue(param.name() + "thickness"); final String value = getValue(param.name() + "thickness");
if (value != null && value.matches("[\\d.]+")) { if (value != null && value.matches("[\\d.]+")) {
return new UStroke(Double.parseDouble(value)); if (style == null) {
style = LinkStyle.NORMAL();
}
return style.goThickness(Double.parseDouble(value)).getStroke3();
}
if (style == null) {
final String styleValue = getValue(param.name() + "style");
if (styleValue != null) {
style = LinkStyle.fromString2(styleValue);
}
}
if (style != null && style.isNormal() == false) {
return style.getStroke3();
} }
return null; return null;
} }

View File

@ -48,7 +48,6 @@ import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlanes; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlanes;
import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.DiagramDescription;
@ -59,7 +58,6 @@ import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockCompressed; import net.sourceforge.plantuml.graphic.TextBlockCompressed;
import net.sourceforge.plantuml.graphic.TextBlockRecentred; import net.sourceforge.plantuml.graphic.TextBlockRecentred;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.sequencediagram.NotePosition; import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType; import net.sourceforge.plantuml.sequencediagram.NoteType;
@ -191,8 +189,9 @@ public class ActivityDiagram3 extends UmlDiagram {
result = new TextBlockRecentred(result); result = new TextBlockRecentred(result);
final ISkinParam skinParam = getSkinParam(); final ISkinParam skinParam = getSkinParam();
result = new AnnotatedWorker(this, skinParam).addAdd(result); result = new AnnotatedWorker(this, skinParam).addAdd(result);
final Dimension2D dim = TextBlockUtils.getMinMax(result, fileFormatOption.getDefaultStringBounder()) // final Dimension2D dim = TextBlockUtils.getMinMax(result, fileFormatOption.getDefaultStringBounder())
.getDimension(); // .getDimension();
final Dimension2D dim = result.getMinMax(fileFormatOption.getDefaultStringBounder()).getDimension();
final double margin = 10; final double margin = 10;
final double dpiFactor = getDpiFactor(fileFormatOption, Dimension2DDouble.delta(dim, 2 * margin, 0)); final double dpiFactor = getDpiFactor(fileFormatOption, Dimension2DDouble.delta(dim, 2 * margin, 0));

View File

@ -46,21 +46,15 @@ import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
public abstract class AbstractFtile extends AbstractTextBlock implements Ftile { public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
private final boolean shadowing;
private final ISkinParam skinParam; private final ISkinParam skinParam;
private AbstractFtile(boolean shadowing) {
this.shadowing = shadowing;
this.skinParam = null;
}
public AbstractFtile(ISkinParam skinParam) { public AbstractFtile(ISkinParam skinParam) {
this.shadowing = skinParam.shadowing();
this.skinParam = skinParam; this.skinParam = skinParam;
} }
@ -101,10 +95,31 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
public Collection<Ftile> getMyChildren() { public Collection<Ftile> getMyChildren() {
throw new UnsupportedOperationException("" + getClass()); throw new UnsupportedOperationException("" + getClass());
// return Collections.emptyList();
} }
public HorizontalAlignment arrowHorizontalAlignment() { public HorizontalAlignment arrowHorizontalAlignment() {
return skinParam.getHorizontalAlignment(AlignParam.ARROW_MESSAGE_ALIGN, null); return skinParam.getHorizontalAlignment(AlignParam.ARROW_MESSAGE_ALIGN, null);
} }
private FtileGeometry cachedGeometry;
final public FtileGeometry calculateDimension(StringBounder stringBounder) {
if (cachedGeometry == null) {
cachedGeometry = calculateDimensionFtile(stringBounder);
}
return cachedGeometry;
}
abstract protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder);
@Override
final public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
// return getMinMaxFtile(stringBounder);
}
// protected MinMax getMinMaxFtile(StringBounder stringBounder) {
// throw new UnsupportedOperationException();
// }
} }

View File

@ -40,8 +40,10 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinParam;
@ -76,7 +78,18 @@ public class FtileAssemblySimple extends AbstractTextBlock implements Ftile {
return tile2.getSwimlaneOut(); return tile2.getSwimlaneOut();
} }
private final Map<Ftile, UTranslate> cachedTranslation = new HashMap<Ftile, UTranslate>();
public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) { public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) {
UTranslate result = cachedTranslation.get(child);
if (result == null) {
result = getTranslateForSlow(child, stringBounder);
cachedTranslation.put(child, result);
}
return result;
}
private UTranslate getTranslateForSlow(Ftile child, StringBounder stringBounder) {
if (child == tile1) { if (child == tile1) {
return getTranslated1(stringBounder); return getTranslated1(stringBounder);
} }
@ -96,8 +109,8 @@ public class FtileAssemblySimple extends AbstractTextBlock implements Ftile {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder(); final StringBounder stringBounder = ug.getStringBounder();
ug.apply(getTranslated1(stringBounder)).draw(tile1); ug.apply(getTranslateFor(tile1, stringBounder)).draw(tile1);
ug.apply(getTranslated2(stringBounder)).draw(tile2); ug.apply(getTranslateFor(tile2, stringBounder)).draw(tile2);
} }
public LinkRendering getInLinkRendering() { public LinkRendering getInLinkRendering() {

View File

@ -58,8 +58,9 @@ public class FtileBreak extends FtileEmpty implements WeldingPoint {
return "FtileBreak"; return "FtileBreak";
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
return super.calculateDimension(stringBounder).withoutPointOut(); protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return calculateDimensionEmpty().withoutPointOut();
} }
@Override @Override

View File

@ -85,7 +85,12 @@ public class FtileEmpty extends AbstractFtile {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return calculateDimensionEmpty();
}
final protected FtileGeometry calculateDimensionEmpty() {
return new FtileGeometry(width, height, width / 2, 0, height); return new FtileGeometry(width, height, width / 2, 0, height);
} }

View File

@ -47,8 +47,9 @@ public class FtileGoto extends FtileEmpty {
this.name = name; this.name = name;
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
return super.calculateDimension(stringBounder).withoutPointOut(); protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return calculateDimensionEmpty().withoutPointOut();
} }
public String getName() { public String getName() {

View File

@ -76,7 +76,8 @@ public class FtileHeightFixed extends AbstractFtile {
return tile.getSwimlaneOut(); return tile.getSwimlaneOut();
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return tile.calculateDimension(stringBounder).translate(getTranslate(stringBounder)).fixedHeight(fixedHeight); return tile.calculateDimension(stringBounder).translate(getTranslate(stringBounder)).fixedHeight(fixedHeight);
} }

View File

@ -61,7 +61,8 @@ public class FtileKilled extends AbstractFtile {
return tile.getSwimlaneOut(); return tile.getSwimlaneOut();
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry geo = tile.calculateDimension(stringBounder); final FtileGeometry geo = tile.calculateDimension(stringBounder);
return new FtileGeometry(tile.calculateDimension(stringBounder), geo.getLeft(), geo.getInY()); return new FtileGeometry(tile.calculateDimension(stringBounder), geo.getLeft(), geo.getInY());
} }

View File

@ -85,7 +85,8 @@ public class FtileMarged extends AbstractFtile {
return tile.getSwimlaneOut(); return tile.getSwimlaneOut();
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry orig = tile.calculateDimension(stringBounder); final FtileGeometry orig = tile.calculateDimension(stringBounder);
return new FtileGeometry(orig.getWidth() + margin1 + margin2, orig.getHeight(), orig.getLeft() + margin1, return new FtileGeometry(orig.getWidth() + margin1 + margin2, orig.getHeight(), orig.getLeft() + margin1,
orig.getInY(), orig.getOutY()); orig.getInY(), orig.getOutY());

View File

@ -74,7 +74,8 @@ public class FtileMargedRight extends AbstractFtile {
return tile.getSwimlaneOut(); return tile.getSwimlaneOut();
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry orig = tile.calculateDimension(stringBounder); final FtileGeometry orig = tile.calculateDimension(stringBounder);
if (orig.getWidth() > maxX) { if (orig.getWidth() > maxX) {
throw new IllegalStateException(); throw new IllegalStateException();

View File

@ -58,7 +58,16 @@ public class FtileMargedVertically extends FtileDecorate {
ug.draw(getFtileDelegated()); ug.draw(getFtileDelegated());
} }
private FtileGeometry cached;
public FtileGeometry calculateDimension(StringBounder stringBounder) { public FtileGeometry calculateDimension(StringBounder stringBounder) {
if (cached == null) {
this.cached = calculateDimensionSlow(stringBounder);
}
return this.cached;
}
private FtileGeometry calculateDimensionSlow(StringBounder stringBounder) {
final FtileGeometry orig = getFtileDelegated().calculateDimension(stringBounder); final FtileGeometry orig = getFtileDelegated().calculateDimension(stringBounder);
return new FtileGeometry(orig.getWidth(), orig.getHeight() + margin1 + margin2, orig.getLeft(), orig.getInY() return new FtileGeometry(orig.getWidth(), orig.getHeight() + margin1 + margin2, orig.getLeft(), orig.getInY()
+ margin1, orig.hasPointOut() ? orig.getOutY() + margin1 : orig.getOutY()); + margin1, orig.hasPointOut() ? orig.getOutY() + margin1 : orig.getOutY());

View File

@ -64,7 +64,6 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.UGraphicDelegator; import net.sourceforge.plantuml.graphic.UGraphicDelegator;
import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.skin.rose.Rose;
@ -113,7 +112,8 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
factory = new FtileFactoryDelegatorWhile(factory); factory = new FtileFactoryDelegatorWhile(factory);
factory = new FtileFactoryDelegatorRepeat(factory); factory = new FtileFactoryDelegatorRepeat(factory);
factory = new FtileFactoryDelegatorCreateParallel(factory); factory = new FtileFactoryDelegatorCreateParallel(factory);
// factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new FtileFactoryDelegatorCreateParallel1(factory)); // factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new
// FtileFactoryDelegatorCreateParallel1(factory));
factory = new FtileFactoryDelegatorAddNote(factory); factory = new FtileFactoryDelegatorAddNote(factory);
factory = new FtileFactoryDelegatorCreateGroup(factory); factory = new FtileFactoryDelegatorCreateGroup(factory);
return factory; return factory;
@ -173,16 +173,20 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
} }
static private final double separationMargin = 10; static private final double separationMargin = 10;
private TextBlock full;
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final FtileFactory factory = getFtileFactory(ug.getStringBounder()); if (full == null) {
TextBlock full = root.createFtile(factory); final FtileFactory factory = getFtileFactory(ug.getStringBounder());
full = root.createFtile(factory);
if (swimlanes.size() <= 1) {
// BUG42
full = new TextBlockInterceptorUDrawable(full);
}
}
ug = new UGraphicForSnake(ug); ug = new UGraphicForSnake(ug);
if (swimlanes.size() <= 1) { if (swimlanes.size() <= 1) {
full = new TextBlockInterceptorUDrawable(full);
// BUG42
// full.drawU(ug);
full.drawU(ug); full.drawU(ug);
ug.flushUg(); ug.flushUg();
return; return;
@ -383,10 +387,21 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height)); ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height));
} }
// private Dimension2D cachedDimension;
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
return TextBlockUtils.getMinMax(this, stringBounder).getDimension(); return getMinMax(stringBounder).getDimension();
// if (cachedDimension == null) {
// cachedDimension = calculateDimensionSlow(stringBounder);
// }
// return cachedDimension;
} }
// private Dimension2D calculateDimensionSlow(StringBounder stringBounder) {
// final Dimension2D result = TextBlockUtils.getMinMax(this, stringBounder).getDimension();
// return result;
// }
public Instruction getCurrent() { public Instruction getCurrent() {
return currentInstruction; return currentInstruction;
} }

View File

@ -41,7 +41,6 @@ import java.util.HashMap;
import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -59,7 +58,8 @@ public class TextBlockInterceptorUDrawable extends AbstractTextBlock implements
} }
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
return TextBlockUtils.getMinMax(this, stringBounder).getDimension(); // return TextBlockUtils.getMinMax(this, stringBounder).getDimension();
throw new UnsupportedOperationException();
} }
} }

View File

@ -93,7 +93,8 @@ class FtileForkInner extends AbstractFtile {
} }
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
double height = 0; double height = 0;
double width = 0; double width = 0;
for (Ftile ftile : forks) { for (Ftile ftile : forks) {

View File

@ -93,7 +93,8 @@ class FtileForkInnerOverlapped extends AbstractFtile {
} }
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
double height = 0; double height = 0;
double width = 0; double width = 0;
for (Ftile ftile : forks) { for (Ftile ftile : forks) {

View File

@ -130,12 +130,12 @@ public class FtileGroup extends AbstractFtile {
return new UTranslate(suppWidth / 2, diffHeightTitle(stringBounder) + headerNoteHeight(stringBounder)); return new UTranslate(suppWidth / 2, diffHeightTitle(stringBounder) + headerNoteHeight(stringBounder));
} }
private static MinMax getMinMax(TextBlock tb, StringBounder stringBounder) { private MinMax getInnerMinMax(StringBounder stringBounder) {
final LimitFinder limitFinder = new LimitFinder(stringBounder, false); final LimitFinder limitFinder = new LimitFinder(stringBounder, false);
final UGraphicForSnake interceptor = new UGraphicForSnake(limitFinder); final UGraphicForSnake interceptor = new UGraphicForSnake(limitFinder);
final UGraphicInterceptorUDrawable interceptor2 = new UGraphicInterceptorUDrawable(interceptor); final UGraphicInterceptorUDrawable interceptor2 = new UGraphicInterceptorUDrawable(interceptor);
tb.drawU(interceptor2); inner.drawU(interceptor2);
interceptor2.flushUg(); interceptor2.flushUg();
return limitFinder.getMinMax(); return limitFinder.getMinMax();
} }
@ -149,9 +149,19 @@ public class FtileGroup extends AbstractFtile {
return suppWidth; return suppWidth;
} }
private FtileGeometry cachedInnerDimension;
private FtileGeometry getInnerDimension(StringBounder stringBounder) { private FtileGeometry getInnerDimension(StringBounder stringBounder) {
if (cachedInnerDimension == null) {
cachedInnerDimension = getInnerDimensionSlow(stringBounder);
}
return cachedInnerDimension;
}
private FtileGeometry getInnerDimensionSlow(StringBounder stringBounder) {
final FtileGeometry orig = inner.calculateDimension(stringBounder); final FtileGeometry orig = inner.calculateDimension(stringBounder);
final MinMax minMax = getMinMax(inner, stringBounder); final MinMax minMax = getInnerMinMax(stringBounder);
final double missingWidth = minMax.getMaxX() - orig.getWidth(); final double missingWidth = minMax.getMaxX() - orig.getWidth();
if (missingWidth > 0) { if (missingWidth > 0) {
return orig.addDim(missingWidth + 5, 0); return orig.addDim(missingWidth + 5, 0);
@ -159,7 +169,8 @@ public class FtileGroup extends AbstractFtile {
return orig; return orig;
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry orig = getInnerDimension(stringBounder); final FtileGeometry orig = getInnerDimension(stringBounder);
final double suppWidth = suppWidth(stringBounder); final double suppWidth = suppWidth(stringBounder);
final double width = orig.getWidth() + suppWidth; final double width = orig.getWidth() + suppWidth;

View File

@ -271,7 +271,8 @@ class FtileIfAndStop extends AbstractFtile {
ug.apply(getTranslateStop(stringBounder)).draw(stop2); ug.apply(getTranslateStop(stringBounder)).draw(stop2);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimStop2 = stop2.calculateDimension(stringBounder); final Dimension2D dimStop2 = stop2.calculateDimension(stringBounder);
final FtileGeometry dim1 = tile1.calculateDimension(stringBounder).addDim(0, final FtileGeometry dim1 = tile1.calculateDimension(stringBounder).addDim(0,
getDiamondStopDistance() + dimStop2.getWidth()); getDiamondStopDistance() + dimStop2.getWidth());

View File

@ -341,7 +341,8 @@ public class FtileIfDown extends AbstractFtile {
} }
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder); final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder);
final FtileGeometry geoThen = thenBlock.calculateDimension(stringBounder); final FtileGeometry geoThen = thenBlock.calculateDimension(stringBounder);
final FtileGeometry geoDiamond2 = diamond2.calculateDimension(stringBounder); final FtileGeometry geoDiamond2 = diamond2.calculateDimension(stringBounder);

View File

@ -38,7 +38,6 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -561,7 +560,8 @@ class FtileIfLongHorizontal extends AbstractFtile {
return new FtileGeometry(result, result.getWidth() / 2, 0); return new FtileGeometry(result, result.getWidth() / 2, 0);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
final List<Ftile> all = new ArrayList<Ftile>(tiles); final List<Ftile> all = new ArrayList<Ftile>(tiles);

View File

@ -571,7 +571,8 @@ class FtileIfLongVertical extends AbstractFtile {
return width; return width;
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
final List<Ftile> all = new ArrayList<Ftile>(tiles); final List<Ftile> all = new ArrayList<Ftile>(tiles);

View File

@ -113,7 +113,8 @@ public class FtileNoteAlone extends AbstractFtile implements Stencil {
opale.drawU(ug); opale.drawU(ug);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
if (withOutPoint) { if (withOutPoint) {
return new FtileGeometry(dimTotal, dimTotal.getWidth() / 2, 0, dimTotal.getHeight()); return new FtileGeometry(dimTotal, dimTotal.getWidth() / 2, 0, dimTotal.getHeight());

View File

@ -490,7 +490,8 @@ class FtileRepeat extends AbstractFtile {
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
return new FtileGeometry(dimTotal, getLeft(stringBounder), 0, dimTotal.getHeight()); return new FtileGeometry(dimTotal, getLeft(stringBounder), 0, dimTotal.getHeight());
} }

View File

@ -91,7 +91,8 @@ class FtileSplit1 extends AbstractFtile {
} }
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
double height = 0; double height = 0;
double width = 0; double width = 0;
for (Ftile ftile : forks) { for (Ftile ftile : forks) {

View File

@ -454,7 +454,8 @@ class FtileWhile extends AbstractFtile {
} }
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder); final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder);
FtileGeometry geoWhile = whileBlock.calculateDimension(stringBounder); FtileGeometry geoWhile = whileBlock.calculateDimension(stringBounder);
final double diff = -geoWhile.getWidth(); final double diff = -geoWhile.getWidth();

View File

@ -199,7 +199,8 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil {
ug.apply(getTranslate(stringBounder)).draw(tile); ug.apply(getTranslate(stringBounder)).draw(tile);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
final FtileGeometry orig = tile.calculateDimension(stringBounder); final FtileGeometry orig = tile.calculateDimension(stringBounder);
final UTranslate translate = getTranslate(stringBounder); final UTranslate translate = getTranslate(stringBounder);

View File

@ -173,7 +173,8 @@ public class FtileWithNotes extends AbstractFtile {
ug.apply(getTranslate(stringBounder)).draw(tile); ug.apply(getTranslate(stringBounder)).draw(tile);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
final FtileGeometry orig = tile.calculateDimension(stringBounder); final FtileGeometry orig = tile.calculateDimension(stringBounder);
final UTranslate translate = getTranslate(stringBounder); final UTranslate translate = getTranslate(stringBounder);

View File

@ -128,7 +128,8 @@ public class FtileIfNude extends FtileDimensionMemoize {
ug.apply(getTranslate2(stringBounder)).draw(tile2); ug.apply(getTranslate2(stringBounder)).draw(tile2);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry dimTotal = calculateDimensionInternal(stringBounder); final FtileGeometry dimTotal = calculateDimensionInternal(stringBounder);
if (tile1.calculateDimension(stringBounder).hasPointOut() if (tile1.calculateDimension(stringBounder).hasPointOut()
|| tile2.calculateDimension(stringBounder).hasPointOut()) { || tile2.calculateDimension(stringBounder).hasPointOut()) {

View File

@ -81,7 +81,8 @@ public class FtileBlackBlock extends AbstractFtile {
this.label = label; this.label = label;
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
double supp = label.calculateDimension(stringBounder).getWidth(); double supp = label.calculateDimension(stringBounder).getWidth();
if (supp > 0) { if (supp > 0) {
supp += labelMargin; supp += labelMargin;

View File

@ -151,7 +151,8 @@ public class FtileBox extends AbstractFtile {
tb.drawU(ug.apply(new UTranslate(MARGIN, MARGIN))); tb.drawU(ug.apply(new UTranslate(MARGIN, MARGIN)));
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dim = tb.calculateDimension(stringBounder); final Dimension2D dim = tb.calculateDimension(stringBounder);
return new FtileGeometry(Dimension2DDouble.delta(dim, 2 * MARGIN, 2 * MARGIN), dim.getWidth() / 2 + MARGIN, 0, return new FtileGeometry(Dimension2DDouble.delta(dim, 2 * MARGIN, 2 * MARGIN), dim.getWidth() / 2 + MARGIN, 0,
dim.getHeight() + 2 * MARGIN); dim.getHeight() + 2 * MARGIN);

View File

@ -111,7 +111,8 @@ public class FtileCircleEnd extends AbstractFtile {
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0); return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0);
} }

View File

@ -92,7 +92,8 @@ public class FtileCircleStart extends AbstractFtile {
ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(backColor)).draw(circle); ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(backColor)).draw(circle);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0, SIZE); return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0, SIZE);
} }

View File

@ -108,7 +108,8 @@ public class FtileCircleStop extends AbstractFtile {
.draw(circleSmall); .draw(circleSmall);
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0); return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0);
} }

View File

@ -147,7 +147,8 @@ public class FtileDiamond extends AbstractFtile {
+ Diamond.diamondHalfSize))); + Diamond.diamondHalfSize)));
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final double suppY1 = north.calculateDimension(stringBounder).getHeight(); final double suppY1 = north.calculateDimension(stringBounder).getHeight();
final Dimension2D dim = new Dimension2DDouble(Diamond.diamondHalfSize * 2, Diamond.diamondHalfSize * 2 + suppY1); final Dimension2D dim = new Dimension2DDouble(Diamond.diamondHalfSize * 2, Diamond.diamondHalfSize * 2 + suppY1);
return new FtileGeometry(dim, dim.getWidth() / 2, suppY1, dim.getHeight()); return new FtileGeometry(dim, dim.getWidth() / 2, suppY1, dim.getHeight());

View File

@ -130,7 +130,8 @@ public class FtileDiamondFoo1 extends AbstractFtile {
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D dim = calculateDimensionInternal(stringBounder); final Dimension2D dim = calculateDimensionInternal(stringBounder);
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight()); return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
} }

View File

@ -161,7 +161,8 @@ public class FtileDiamondInside extends AbstractFtile {
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight()); return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final FtileGeometry dimDiamonAlone = calculateDimensionAlone(stringBounder); final FtileGeometry dimDiamonAlone = calculateDimensionAlone(stringBounder);
final Dimension2D dimWest = west.calculateDimension(stringBounder); final Dimension2D dimWest = west.calculateDimension(stringBounder);
final Dimension2D dimEast = east.calculateDimension(stringBounder); final Dimension2D dimEast = east.calculateDimension(stringBounder);

View File

@ -150,7 +150,8 @@ public class FtileDiamondInside2 extends AbstractFtile {
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight()); return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D diamond = calculateDimensionAlone(stringBounder); final Dimension2D diamond = calculateDimensionAlone(stringBounder);
final Dimension2D north = this.north.calculateDimension(stringBounder); final Dimension2D north = this.north.calculateDimension(stringBounder);
final double height = diamond.getHeight() + north.getHeight(); final double height = diamond.getHeight() + north.getHeight();

View File

@ -152,7 +152,8 @@ public class FtileDiamondInside3 extends AbstractFtile implements FtileOverpassi
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight()); return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
final Dimension2D diamond = calculateDimensionAlone(stringBounder); final Dimension2D diamond = calculateDimensionAlone(stringBounder);
final Dimension2D north = this.north.calculateDimension(stringBounder); final Dimension2D north = this.north.calculateDimension(stringBounder);
final double height = diamond.getHeight() + north.getHeight(); final double height = diamond.getHeight() + north.getHeight();

View File

@ -44,7 +44,6 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
@ -73,7 +72,8 @@ public class FtileThinSplit extends AbstractFtile {
this.last = last; this.last = last;
} }
public FtileGeometry calculateDimension(StringBounder stringBounder) { @Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return new FtileGeometry(width, height, width / 2, 0, height); return new FtileGeometry(width, height, width / 2, 0, height);
} }

View File

@ -362,10 +362,10 @@ public class PlantUmlTask extends Task {
setNbThread(s); setNbThread(s);
} }
public void setSuggestEngine(String s) { // public void setSuggestEngine(String s) {
OptionFlags.getInstance().setUseSuggestEngine( // OptionFlags.getInstance().setUseSuggestEngine(
"true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s)); // "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s));
} // }
public void setFailFast(String s) { public void setFailFast(String s) {
final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s); final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s);

View File

@ -52,6 +52,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -111,6 +112,10 @@ public class BpmElement extends AbstractConnectorPuzzle implements ConnectorPuzz
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
return raw.calculateDimension(stringBounder); return raw.calculateDimension(stringBounder);
} }
public MinMax getMinMax(StringBounder stringBounder) {
return raw.getMinMax(stringBounder);
}
}; };
} }

View File

@ -44,6 +44,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
@ -116,6 +117,11 @@ public class ConnectorPuzzleEmpty extends AbstractConnectorPuzzle implements Pla
return new Dimension2DDouble(20, 20); return new Dimension2DDouble(20, 20);
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
return null; return null;
} }

View File

@ -58,16 +58,14 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
public class ClassDiagram extends AbstractClassOrObjectDiagram { public class ClassDiagram extends AbstractClassOrObjectDiagram {
private String namespaceSeparator = ".";
@Override @Override
public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) { public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) {
if (namespaceSeparator != null) { if (getNamespaceSeparator() != null) {
code = code.withSeparator(namespaceSeparator); code = code.withSeparator(getNamespaceSeparator());
} }
if (type == null) { if (type == null) {
code = code.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); code = code.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
if (namespaceSeparator == null) { if (getNamespaceSeparator() == null) {
return getOrCreateLeafDefault(code, LeafType.CLASS, symbol); return getOrCreateLeafDefault(code, LeafType.CLASS, symbol);
} }
code = code.getFullyQualifiedCode(getCurrentGroup()); code = code.getFullyQualifiedCode(getCurrentGroup());
@ -77,7 +75,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())), return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())),
LeafType.CLASS, symbol); LeafType.CLASS, symbol);
} }
if (namespaceSeparator == null) { if (getNamespaceSeparator() == null) {
return getOrCreateLeafDefault(code, LeafType.CLASS, symbol); return getOrCreateLeafDefault(code, LeafType.CLASS, symbol);
} }
code = code.getFullyQualifiedCode(getCurrentGroup()); code = code.getFullyQualifiedCode(getCurrentGroup());
@ -87,42 +85,18 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())), type, symbol); return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())), type, symbol);
} }
public IGroup getOrCreateNamespace(Code namespace, Display display, GroupType type, IGroup parent) {
if (namespaceSeparator != null) {
namespace = namespace.withSeparator(namespaceSeparator).getFullyQualifiedCode(getCurrentGroup());
}
final IGroup g = getOrCreateNamespaceInternal(namespace, display, type, parent);
currentGroup = g;
return g;
}
private IGroup getOrCreateNamespaceInternal(Code namespace, Display display, GroupType type, IGroup parent) {
IGroup result = entityFactory.getGroups().get(namespace);
if (result != null) {
return result;
}
if (entityFactory.getLeafs().containsKey(namespace)) {
result = entityFactory.muteToGroup(namespace, namespace, type, parent);
result.setDisplay(display);
} else {
result = entityFactory.createGroup(namespace, display, namespace, type, parent, getHides(),
getNamespaceSeparator());
}
entityFactory.addGroup(result);
return result;
}
@Override @Override
public ILeaf createLeaf(Code code, Display display, LeafType type, USymbol symbol) { public ILeaf createLeaf(Code code, Display display, LeafType type, USymbol symbol) {
if (namespaceSeparator != null) { if (getNamespaceSeparator() != null) {
code = code.withSeparator(namespaceSeparator); code = code.withSeparator(getNamespaceSeparator());
} }
if (type != LeafType.ABSTRACT_CLASS && type != LeafType.ANNOTATION && type != LeafType.CLASS if (type != LeafType.ABSTRACT_CLASS && type != LeafType.ANNOTATION && type != LeafType.CLASS
&& type != LeafType.INTERFACE && type != LeafType.ENUM && type != LeafType.LOLLIPOP && type != LeafType.INTERFACE && type != LeafType.ENUM && type != LeafType.LOLLIPOP
&& type != LeafType.NOTE) { && type != LeafType.NOTE) {
return super.createLeaf(code, display, type, symbol); return super.createLeaf(code, display, type, symbol);
} }
if (namespaceSeparator == null) { if (getNamespaceSeparator() == null) {
return super.createLeaf(code, display, type, symbol); return super.createLeaf(code, display, type, symbol);
} }
code = code.getFullyQualifiedCode(getCurrentGroup()); code = code.getFullyQualifiedCode(getCurrentGroup());
@ -150,21 +124,21 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
private final String getNamespace(Code fullyCode) { private final String getNamespace(Code fullyCode) {
String name = fullyCode.getFullName(); String name = fullyCode.getFullName();
do { do {
final int x = name.lastIndexOf(namespaceSeparator); final int x = name.lastIndexOf(getNamespaceSeparator());
if (x == -1) { if (x == -1) {
return null; return null;
} }
name = name.substring(0, x); name = name.substring(0, x);
} while (getLeafs().containsKey(Code.of(name, namespaceSeparator))); } while (getLeafs().containsKey(Code.of(name, getNamespaceSeparator())));
return name; return name;
} }
@Override @Override
public final boolean leafExist(Code code) { public final boolean leafExist(Code code) {
if (namespaceSeparator == null) { if (getNamespaceSeparator() == null) {
return super.leafExist(code); return super.leafExist(code);
} }
code = code.withSeparator(namespaceSeparator); code = code.withSeparator(getNamespaceSeparator());
return super.leafExist(code.getFullyQualifiedCode(getCurrentGroup())); return super.leafExist(code.getFullyQualifiedCode(getCurrentGroup()));
} }
@ -173,14 +147,6 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
return UmlDiagramType.CLASS; return UmlDiagramType.CLASS;
} }
public void setNamespaceSeparator(String namespaceSeparator) {
this.namespaceSeparator = namespaceSeparator;
}
public String getNamespaceSeparator() {
return namespaceSeparator;
}
private boolean allowMixing; private boolean allowMixing;
public void setAllowMixing(boolean allowMixing) { public void setAllowMixing(boolean allowMixing) {

View File

@ -118,7 +118,7 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory {
if (commandControl == CommandControl.NOT_OK) { if (commandControl == CommandControl.NOT_OK) {
final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", /* it.currentNum(), */it.peek() final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", /* it.currentNum(), */it.peek()
.getLocation()); .getLocation());
if (OptionFlags.getInstance().isUseSuggestEngine()) { if (OptionFlags.getInstance().isUseSuggestEngine2()) {
final SuggestEngine engine = new SuggestEngine(source, this); final SuggestEngine engine = new SuggestEngine(source, this);
final SuggestEngineResult result = engine.tryToSuggest(sys); final SuggestEngineResult result = engine.tryToSuggest(sys);
if (result.getStatus() == SuggestEngineStatus.ONE_SUGGESTION) { if (result.getStatus() == SuggestEngineStatus.ONE_SUGGESTION) {

View File

@ -38,7 +38,7 @@ package net.sourceforge.plantuml.core;
import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.utils.StartUtils;
public enum DiagramType { public enum DiagramType {
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, UNKNOWN; UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, UNKNOWN;
static public DiagramType getTypeFromArobaseStart(String s) { static public DiagramType getTypeFromArobaseStart(String s) {
s = s.toLowerCase(); s = s.toLowerCase();
@ -87,6 +87,9 @@ public enum DiagramType {
if (StartUtils.startsWithSymbolAnd("startdef", s)) { if (StartUtils.startsWithSymbolAnd("startdef", s)) {
return DEFINITION; return DEFINITION;
} }
if (StartUtils.startsWithSymbolAnd("startgantt", s)) {
return GANTT;
}
return UNKNOWN; return UNKNOWN;
} }
} }

View File

@ -80,10 +80,20 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
public abstract IEntity getOrCreateLeaf(Code code, LeafType type, USymbol symbol); public abstract IEntity getOrCreateLeaf(Code code, LeafType type, USymbol symbol);
public String getNamespaceSeparator() { private String namespaceSeparator = ".";
return null;
final public void setNamespaceSeparator(String namespaceSeparator) {
this.namespaceSeparator = namespaceSeparator;
} }
final public String getNamespaceSeparator() {
return namespaceSeparator;
}
// public String getNamespaceSeparator() {
// return null;
// }
@Override @Override
public boolean hasUrl() { public boolean hasUrl() {
for (IEntity entity : getGroups(true)) { for (IEntity entity : getGroups(true)) {
@ -158,12 +168,40 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return Collections.unmodifiableCollection(result); return Collections.unmodifiableCollection(result);
} }
final public IGroup getOrCreateNamespace(Code namespace, Display display, GroupType type, IGroup parent) {
if (getNamespaceSeparator() != null) {
namespace = namespace.withSeparator(getNamespaceSeparator()).getFullyQualifiedCode(getCurrentGroup());
}
final IGroup g = getOrCreateNamespaceInternal(namespace, display, type, parent);
currentGroup = g;
return g;
}
final public IGroup getOrCreateGroup(Code code, Display display, GroupType type, IGroup parent) { final public IGroup getOrCreateGroup(Code code, Display display, GroupType type, IGroup parent) {
final IGroup g = getOrCreateGroupInternal(code, display, null, type, parent); final IGroup g = getOrCreateGroupInternal(code, display, null, type, parent);
currentGroup = g; currentGroup = g;
return g; return g;
} }
final protected IGroup getOrCreateNamespaceInternal(Code namespace, Display display, GroupType type, IGroup parent) {
IGroup result = entityFactory.getGroups().get(namespace);
if (result != null) {
return result;
}
if (entityFactory.getLeafs().containsKey(namespace)) {
result = entityFactory.muteToGroup(namespace, namespace, type, parent);
result.setDisplay(display);
} else {
result = entityFactory.createGroup(namespace, display, namespace, type, parent, getHides(),
getNamespaceSeparator());
}
entityFactory.addGroup(result);
return result;
}
private IGroup getOrCreateGroupInternal(Code code, Display display, Code namespace2, GroupType type, IGroup parent) { private IGroup getOrCreateGroupInternal(Code code, Display display, Code namespace2, GroupType type, IGroup parent) {
IGroup result = entityFactory.getGroups().get(code); IGroup result = entityFactory.getGroups().get(code);
if (result != null) { if (result != null) {

View File

@ -206,6 +206,19 @@ public class Display implements Iterable<CharSequence> {
return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode);
} }
public Display withPage(int page, int lastpage) {
if (display == null) {
return this;
}
final List<CharSequence> result = new ArrayList<CharSequence>();
for (CharSequence line : display) {
line = line.toString().replace("%page%", "" + page);
line = line.toString().replace("%lastpage%", "" + lastpage);
result.add(line);
}
return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode);
}
public Display underlined() { public Display underlined() {
final List<CharSequence> result = new ArrayList<CharSequence>(); final List<CharSequence> result = new ArrayList<CharSequence>();
for (CharSequence line : display) { for (CharSequence line : display) {

View File

@ -121,7 +121,15 @@ public class LinkStyle {
return thickness; return thickness;
} }
public static LinkStyle fromString(String s) { public static LinkStyle fromString1(String s) {
final LinkStyle result = fromString2(s);
if (result == null) {
return LinkStyle.NORMAL();
}
return result;
}
public static LinkStyle fromString2(String s) {
if ("dashed".equalsIgnoreCase(s)) { if ("dashed".equalsIgnoreCase(s)) {
return DASHED(); return DASHED();
} }
@ -134,12 +142,7 @@ public class LinkStyle {
if ("hidden".equalsIgnoreCase(s)) { if ("hidden".equalsIgnoreCase(s)) {
return INVISIBLE(); return INVISIBLE();
} }
return LinkStyle.NORMAL(); return null;
}
@Deprecated
public static LinkStyle valueOf(String s) {
return fromString(s);
} }
public boolean isThicknessOverrided() { public boolean isThicknessOverrided() {

View File

@ -45,14 +45,12 @@ import net.sourceforge.plantuml.graphic.USymbol;
public class DescriptionDiagram extends AbstractEntityDiagram { public class DescriptionDiagram extends AbstractEntityDiagram {
private String namespaceSeparator = null;
@Override @Override
public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) { public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) {
if (namespaceSeparator != null) { if (getNamespaceSeparator() != null) {
code = code.withSeparator(namespaceSeparator); code = code.withSeparator(getNamespaceSeparator());
} }
if (namespaceSeparator != null && code.getFullName().contains(namespaceSeparator)) { if (getNamespaceSeparator() != null && code.getFullName().contains(getNamespaceSeparator())) {
// System.err.println("code=" + code); // System.err.println("code=" + code);
final Code fullyCode = code; final Code fullyCode = code;
// final String namespace = fullyCode.getNamespace(getLeafs()); // final String namespace = fullyCode.getNamespace(getLeafs());
@ -138,12 +136,4 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
return UmlDiagramType.DESCRIPTION; return UmlDiagramType.DESCRIPTION;
} }
public void setNamespaceSeparator(String namespaceSeparator) {
this.namespaceSeparator = namespaceSeparator;
}
public String getNamespaceSeparator() {
return namespaceSeparator;
}
} }

View File

@ -62,7 +62,7 @@ import net.sourceforge.plantuml.graphic.color.Colors;
public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiagram> { public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiagram> {
public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle"; public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle|collections";
public CommandCreateElementFull() { public CommandCreateElementFull() {
super(getRegexConcat()); super(getRegexConcat());
@ -205,7 +205,8 @@ public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiag
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }
public static boolean existsWithBadType(AbstractEntityDiagram diagram, final Code code, LeafType type, USymbol usymbol) { public static boolean existsWithBadType(AbstractEntityDiagram diagram, final Code code, LeafType type,
USymbol usymbol) {
if (diagram.leafExist(code) == false) { if (diagram.leafExist(code) == false) {
return false; return false;
} }
@ -213,7 +214,7 @@ public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiag
if (other.getLeafType() != type) { if (other.getLeafType() != type) {
return true; return true;
} }
if (other.getUSymbol() != usymbol) { if (usymbol != null && other.getUSymbol() != usymbol) {
return true; return true;
} }
return false; return false;

View File

@ -77,7 +77,7 @@ public class PSystemDonors extends AbstractPSystem {
+ "VHC7Wx0p1ovU3ReAoyPmPtB36bh8p5kG0R6JrqsbaLqTW8wKWlfJ_H2ahn_g7z1BEzOksNZ5yZ08h6Ol" + "VHC7Wx0p1ovU3ReAoyPmPtB36bh8p5kG0R6JrqsbaLqTW8wKWlfJ_H2ahn_g7z1BEzOksNZ5yZ08h6Ol"
+ "d9iEd26PzTfIAMOouyQDyD-fCiSrAZ4jdMAFr5_gXwVx-dlpbAW_ru_rp_hnwGF_xldJDpYpL8angeoT" + "d9iEd26PzTfIAMOouyQDyD-fCiSrAZ4jdMAFr5_gXwVx-dlpbAW_ru_rp_hnwGF_xldJDpYpL8angeoT"
+ "THxskf4hiLvFIJM7EcWRloA3gHX5F2IxB5XWr_HoA4M5uhdHKibXSKZeSgW_rb-F9M5Wx3cVvyei9SFe" + "THxskf4hiLvFIJM7EcWRloA3gHX5F2IxB5XWr_HoA4M5uhdHKibXSKZeSgW_rb-F9M5Wx3cVvyei9SFe"
+ "eyr2dx88J6VmAHwXNeLhxcfOkAtF-PyPyzpDFxMzjnO0"; + "eyr2dx88J6VmAHwXNeLhxcfOkAtF-PyPyzpDgyhFkpzUfhdf";
@Override @Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed) final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)

View File

@ -0,0 +1,111 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.donors;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.StringBounder;
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.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class PSystemSkinparameterList extends AbstractPSystem {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)
throws IOException {
final UDrawable result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(result);
return imageBuilder.writeImageTOBEMOVED(fileFormat, seed, os);
}
private UDrawable getGraphicStrings() throws IOException {
final List<TextBlock> cols = getCols(getDonors(), 5);
return new UDrawable() {
public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
double x = 0;
double y = 0;
for (TextBlock tb : cols) {
final Dimension2D dim = tb.calculateDimension(stringBounder);
tb.drawU(ug.apply(new UTranslate(x, 0)));
x += dim.getWidth() + 10;
y = Math.max(y, dim.getHeight());
}
}
};
}
public static List<TextBlock> getCols(List<String> lines, final int nbCol) throws IOException {
final List<TextBlock> result = new ArrayList<TextBlock>();
final int maxLine = (lines.size() + (nbCol - 1)) / nbCol;
for (int i = 0; i < lines.size(); i += maxLine) {
final List<String> current = lines.subList(i, Math.min(lines.size(), i + maxLine));
result.add(GraphicStrings.createBlackOnWhite(current));
}
return result;
}
private List<String> getDonors() throws IOException {
final List<String> lines = new ArrayList<String>(SkinParam.getPossibleValues());
return lines;
}
public DiagramDescription getDescription() {
return new DiagramDescription("(Parameters)");
}
public static PSystemSkinparameterList create() {
return new PSystemSkinparameterList();
}
}

View File

@ -0,0 +1,51 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.donors;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.command.PSystemSingleLineFactory;
public class PSystemSkinparameterListFactory extends PSystemSingleLineFactory {
@Override
protected AbstractPSystem executeLine(String line) {
if (line.matches("(?i)^(skinparameters)\\s*$")) {
return PSystemSkinparameterList.create();
}
return null;
}
}

View File

@ -62,6 +62,7 @@ import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UEllipse;
@ -209,4 +210,9 @@ public class FlowDiagram extends UmlDiagram implements TextBlock {
final MinMaxGolem minMax = getMinMax(); final MinMaxGolem minMax = getMinMax();
return new Dimension2DDouble(minMax.getWidth() * SINGLE_SIZE_X, minMax.getHeight() * SINGLE_SIZE_Y); return new Dimension2DDouble(minMax.getWidth() * SINGLE_SIZE_X, minMax.getHeight() * SINGLE_SIZE_Y);
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
} }

View File

@ -37,9 +37,15 @@ package net.sourceforge.plantuml.graphic;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import net.sourceforge.plantuml.ugraphic.MinMax;
public abstract class AbstractTextBlock implements TextBlock { public abstract class AbstractTextBlock implements TextBlock {
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
throw new UnsupportedOperationException("member=" + member + " " + getClass().toString()); throw new UnsupportedOperationException("member=" + member + " " + getClass().toString());
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException(getClass().toString());
}
} }

View File

@ -88,7 +88,7 @@ public class HtmlColorAndStyle {
LinkStyle style = LinkStyle.NORMAL(); LinkStyle style = LinkStyle.NORMAL();
final IHtmlColorSet set = skinParam.getIHtmlColorSet(); final IHtmlColorSet set = skinParam.getIHtmlColorSet();
for (String s : definition.split(",")) { for (String s : definition.split(",")) {
final LinkStyle tmpStyle = LinkStyle.fromString(s); final LinkStyle tmpStyle = LinkStyle.fromString1(s);
if (tmpStyle.isNormal() == false) { if (tmpStyle.isNormal() == false) {
style = tmpStyle; style = tmpStyle;
continue; continue;

View File

@ -243,7 +243,10 @@ public class QuoteUtils {
"P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.", "P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.",
"Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.", "Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.",
"Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag", "Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag",
"Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf"); "Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf",
"L'n dhrydhrf dhrfgvbaf dhv erfgrag fbhf fvyrapr...",
"Vs gurer vf ab fbyhgvba, gurer vf ab ceboyrz",
"V unir zrzbevrf, ohg V pna'g gryy vs gurl'er erny.");
private QuoteUtils() { private QuoteUtils() {
} }

View File

@ -92,6 +92,9 @@ public class SkinParameter {
public static final SkinParameter RECTANGLE = new SkinParameter("RECTANGLE", ColorParam.rectangleBackground, public static final SkinParameter RECTANGLE = new SkinParameter("RECTANGLE", ColorParam.rectangleBackground,
ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE); ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
public static final SkinParameter COLLECTIONS = new SkinParameter("COLLECTIONS", ColorParam.collectionsBackground,
ColorParam.collectionsBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
public static final SkinParameter ACTOR = new SkinParameter("ACTOR", ColorParam.actorBackground, public static final SkinParameter ACTOR = new SkinParameter("ACTOR", ColorParam.actorBackground,
ColorParam.actorBorder, FontParam.ACTOR, FontParam.ACTOR_STEREOTYPE); ColorParam.actorBorder, FontParam.ACTOR, FontParam.ACTOR_STEREOTYPE);

View File

@ -68,17 +68,28 @@ public class SymbolContext {
} }
final public UGraphic apply(UGraphic ug) { final public UGraphic apply(UGraphic ug) {
return applyStroke(applyColors(ug)); ug = applyColors(ug);
ug = applyStroke(ug);
return ug;
} }
public UGraphic applyColors(UGraphic ug) { public UGraphic applyColors(UGraphic ug) {
return ug.apply(new UChangeColor(foreColor)).apply(new UChangeBackColor(backColor)); ug = ug.apply(new UChangeColor(foreColor));
ug = ug.apply(new UChangeBackColor(backColor));
return ug;
} }
public UGraphic applyStroke(UGraphic ug) { public UGraphic applyStroke(UGraphic ug) {
return ug.apply(stroke); return ug.apply(stroke);
} }
public SymbolContext transparentBackColorToNull() {
if (backColor instanceof HtmlColorTransparent) {
return new SymbolContext(null, foreColor, stroke, shadowing, deltaShadow, roundCorner);
}
return this;
}
public SymbolContext(HtmlColor backColor, HtmlColor foreColor) { public SymbolContext(HtmlColor backColor, HtmlColor foreColor) {
this(backColor, foreColor, new UStroke(), false, 0, 0); this(backColor, foreColor, new UStroke(), false, 0, 0);
} }

View File

@ -38,13 +38,15 @@ package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UShape; import net.sourceforge.plantuml.ugraphic.UShape;
public interface TextBlock extends UDrawable, UShape { public interface TextBlock extends UDrawable, UShape {
public Dimension2D calculateDimension(StringBounder stringBounder); public Dimension2D calculateDimension(StringBounder stringBounder);
public MinMax getMinMax(StringBounder stringBounder);
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy); public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy);
} }

View File

@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.CompressionTransform; import net.sourceforge.plantuml.ugraphic.CompressionTransform;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.SlotFinder; import net.sourceforge.plantuml.ugraphic.SlotFinder;
import net.sourceforge.plantuml.ugraphic.SlotSet; import net.sourceforge.plantuml.ugraphic.SlotSet;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -58,7 +59,26 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
textBlock.drawU(new UGraphicCompress(ug, compressionTransform)); textBlock.drawU(new UGraphicCompress(ug, compressionTransform));
} }
private MinMax cachedMinMax;
@Override
public MinMax getMinMax(StringBounder stringBounder) {
if (cachedMinMax == null) {
cachedMinMax = TextBlockUtils.getMinMax(this, stringBounder);
}
return cachedMinMax;
}
private CompressionTransform cachedCompressionTransform;
private CompressionTransform getCompressionTransform(final StringBounder stringBounder) { private CompressionTransform getCompressionTransform(final StringBounder stringBounder) {
if (cachedCompressionTransform == null) {
cachedCompressionTransform = getCompressionTransformSlow(stringBounder);
}
return cachedCompressionTransform;
}
private CompressionTransform getCompressionTransformSlow(final StringBounder stringBounder) {
final SlotFinder slotFinder = new SlotFinder(stringBounder); final SlotFinder slotFinder = new SlotFinder(stringBounder);
textBlock.drawU(slotFinder); textBlock.drawU(slotFinder);
final SlotSet ysSlotSet = slotFinder.getYSlotSet().reverse().smaller(5.0); final SlotSet ysSlotSet = slotFinder.getYSlotSet().reverse().smaller(5.0);

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -51,12 +52,29 @@ public class TextBlockRecentred extends AbstractTextBlock implements TextBlockBa
} }
public void drawU(final UGraphic ug) { public void drawU(final UGraphic ug) {
final MinMax minMax = TextBlockUtils.getMinMax(textBlock, ug.getStringBounder()); StringBounder stringBounder = ug.getStringBounder();
final MinMax minMax = getMinMax(stringBounder);
textBlock.drawU(ug.apply(new UTranslate(-minMax.getMinX(), -minMax.getMinY()))); textBlock.drawU(ug.apply(new UTranslate(-minMax.getMinX(), -minMax.getMinY())));
} }
// private MinMax cachedMinMax;
public MinMax getMinMax(StringBounder stringBounder) {
return textBlock.getMinMax(stringBounder);
// if (cachedMinMax == null) {
// cachedMinMax = getMinMaxSlow(stringBounder);
// }
// // assert cachedMinMax.toString().equals(getMinMaxSlow(stringBounder).toString());
// return cachedMinMax;
}
// private MinMax getMinMaxSlow(StringBounder stringBounder) {
// final MinMax result = TextBlockUtils.getMinMax(textBlock, stringBounder);
// return result;
// }
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
final MinMax minMax = TextBlockUtils.getMinMax(textBlock, stringBounder); final MinMax minMax = getMinMax(stringBounder);
return minMax.getDimension(); return minMax.getDimension();
} }

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.LineBreakStrategy;
import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -71,6 +72,10 @@ public class TextBlockTitle implements TextBlock {
return new Dimension2DDouble(width, height); return new Dimension2DDouble(width, height);
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
return null; return null;
} }

View File

@ -165,6 +165,10 @@ public class TextBlockUtils {
return bloc.calculateDimension(stringBounder); return bloc.calculateDimension(stringBounder);
} }
public MinMax getMinMax(StringBounder stringBounder) {
return bloc.getMinMax(stringBounder);
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
if (strategy.check(display, member)) { if (strategy.check(display, member)) {
final Dimension2D dim = calculateDimension(stringBounder); final Dimension2D dim = calculateDimension(stringBounder);

View File

@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
public class TextBlockWithUrl implements TextBlock { public class TextBlockWithUrl implements TextBlock {
@ -69,6 +70,10 @@ public class TextBlockWithUrl implements TextBlock {
return block.calculateDimension(stringBounder); return block.calculateDimension(stringBounder);
} }
public MinMax getMinMax(StringBounder stringBounder) {
return block.getMinMax(stringBounder);
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
return block.getInnerPosition(member, stringBounder, strategy); return block.getInnerPosition(member, stringBounder, strategy);
} }

View File

@ -62,6 +62,8 @@ public abstract class USymbol {
public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile()); public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile());
public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect( public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect(
SkinParameter.RECTANGLE, HorizontalAlignment.CENTER)); SkinParameter.RECTANGLE, HorizontalAlignment.CENTER));
public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS, new USymbolCollections(
SkinParameter.RECTANGLE, HorizontalAlignment.CENTER));
public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT, public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT,
HorizontalAlignment.CENTER)); HorizontalAlignment.CENTER));
public final static USymbol ACTOR = record("ACTOR", SkinParameter.ACTOR, new USymbolActor()); public final static USymbol ACTOR = record("ACTOR", SkinParameter.ACTOR, new USymbolActor());
@ -197,6 +199,8 @@ public abstract class USymbol {
usymbol = USymbol.PACKAGE; usymbol = USymbol.PACKAGE;
} else if (symbol.equalsIgnoreCase("rectangle")) { } else if (symbol.equalsIgnoreCase("rectangle")) {
usymbol = USymbol.RECTANGLE; usymbol = USymbol.RECTANGLE;
} else if (symbol.equalsIgnoreCase("collections")) {
usymbol = USymbol.COLLECTIONS;
} else if (symbol.equalsIgnoreCase("node")) { } else if (symbol.equalsIgnoreCase("node")) {
usymbol = USymbol.NODE; usymbol = USymbol.NODE;
} else if (symbol.equalsIgnoreCase("frame")) { } else if (symbol.equalsIgnoreCase("frame")) {

View File

@ -0,0 +1,145 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
class USymbolCollections extends USymbol {
private final SkinParameter skinParameter;
private final HorizontalAlignment stereotypeAlignement;
public USymbolCollections(SkinParameter skinParameter, HorizontalAlignment stereotypeAlignement) {
this.skinParameter = skinParameter;
this.stereotypeAlignement = stereotypeAlignement;
}
@Override
public USymbol withStereoAlignment(HorizontalAlignment alignment) {
return new USymbolCollections(skinParameter, alignment);
}
@Override
public SkinParameter getSkinParameter() {
return skinParameter;
}
private void drawCollections(UGraphic ug, double width, double height, boolean shadowing, double roundCorner) {
final URectangle small = new URectangle(width - getDeltaCollection(), height - getDeltaCollection(),
roundCorner, roundCorner);
if (shadowing) {
small.setDeltaShadow(3.0);
}
ug.apply(new UTranslate(getDeltaCollection(), getDeltaCollection())).draw(small);
small.setDeltaShadow(0);
ug.apply(new UTranslate(0, 0)).draw(small);
}
private Margin getMargin() {
return new Margin(10, 10, 10, 10);
}
private double getDeltaCollection() {
return 4;
}
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
final SymbolContext symbolContext) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawCollections(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(),
symbolContext.getRoundCorner());
final Margin margin = getMargin();
final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereotypeAlignement);
tb.drawU(ug.apply(new UTranslate(margin.getX1() - getDeltaCollection() / 2, margin.getY1()
- getDeltaCollection() / 2)));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
final Dimension2D dimLabel = label.calculateDimension(stringBounder);
final Dimension2D dimStereo = stereotype.calculateDimension(stringBounder);
return getMargin().addDimension(Dimension2DDouble.mergeTB(dimStereo, dimLabel));
}
};
}
public TextBlock asBig(final TextBlock title, final TextBlock stereotype, final double width, final double height,
final SymbolContext symbolContext) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = symbolContext.apply(ug);
drawCollections(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(),
symbolContext.getRoundCorner());
final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder());
final double posStereoX;
final double posStereoY;
if (stereotypeAlignement == HorizontalAlignment.RIGHT) {
posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2;
posStereoY = getMargin().getY1() / 2;
} else {
posStereoX = (width - dimStereo.getWidth()) / 2;
posStereoY = 2;
}
stereotype.drawU(ug.apply(new UTranslate(posStereoX, posStereoY)));
final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder());
final double posTitle = (width - dimTitle.getWidth()) / 2;
title.drawU(ug.apply(new UTranslate(posTitle, 2 + dimStereo.getHeight())));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return new Dimension2DDouble(width, height);
}
};
}
@Override
public boolean manageHorizontalLine() {
return true;
}
}

View File

@ -170,7 +170,7 @@ public class Colors {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
final Colors result = copy(); final Colors result = copy();
result.lineStyle = LinkStyle.valueOf(StringUtils.goUpperCase(s)); result.lineStyle = LinkStyle.fromString1(StringUtils.goUpperCase(s));
return result; return result;
} }

View File

@ -66,16 +66,35 @@ public class Preprocessor implements ReadLine {
private final Defines defines; private final Defines defines;
private final PreprocessorInclude rawSource; private final PreprocessorInclude rawSource;
private final ReadLineInsertable source; private final ReadLineInsertable source;
private final SubPreprocessor subPreprocessor;
public Preprocessor(ReadLine reader, String charset, Defines defines, File newCurrentDir, public Sub getSub(String blocname) {
return subPreprocessor.getSub(blocname);
}
public Preprocessor(List<String> config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
DefinitionsContainer definitionsContainer) { DefinitionsContainer definitionsContainer) {
this.defines = defines; this.defines = defines;
this.defines.saveState(); this.defines.saveState();
this.rawSource = new PreprocessorInclude(reader, defines, charset, newCurrentDir, definitionsContainer); this.rawSource = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
this.source = new ReadLineInsertable(new IfManager(rawSource, defines)); this.source = new ReadLineInsertable(new IfManager(rawSource, defines));
this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, new ReadLine() {
public void close() throws IOException {
Preprocessor.this.close();
}
public CharSequence2 readLine() throws IOException {
return readLineInternal();
}
});
} }
public CharSequence2 readLine() throws IOException { public CharSequence2 readLine() throws IOException {
return subPreprocessor.readLine();
}
private CharSequence2 readLineInternal() throws IOException {
final CharSequence2 s = source.readLine(); final CharSequence2 s = source.readLine();
if (s == null) { if (s == null) {
return null; return null;

View File

@ -44,6 +44,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -72,6 +73,7 @@ public class PreprocessorInclude implements ReadLine {
private final ReadLine reader2; private final ReadLine reader2;
private final String charset; private final String charset;
private final Defines defines; private final Defines defines;
private final List<String> config;
private final DefinitionsContainer definitionsContainer; private final DefinitionsContainer definitionsContainer;
private int numLine = 0; private int numLine = 0;
@ -82,19 +84,20 @@ public class PreprocessorInclude implements ReadLine {
private final Set<FileWithSuffix> filesUsedCurrent; private final Set<FileWithSuffix> filesUsedCurrent;
private final Set<FileWithSuffix> filesUsedGlobal; private final Set<FileWithSuffix> filesUsedGlobal;
public PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir, public PreprocessorInclude(List<String> config, ReadLine reader, Defines defines, String charset,
DefinitionsContainer definitionsContainer) { File newCurrentDir, DefinitionsContainer definitionsContainer) {
this(reader, defines, charset, newCurrentDir, new HashSet<FileWithSuffix>(), new HashSet<FileWithSuffix>(), this(config, reader, defines, charset, newCurrentDir, new HashSet<FileWithSuffix>(),
definitionsContainer); new HashSet<FileWithSuffix>(), definitionsContainer);
} }
public Set<FileWithSuffix> getFilesUsedGlobal() { public Set<FileWithSuffix> getFilesUsedGlobal() {
return Collections.unmodifiableSet(filesUsedGlobal); return Collections.unmodifiableSet(filesUsedGlobal);
} }
private PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir, private PreprocessorInclude(List<String> config, ReadLine reader, Defines defines, String charset,
Set<FileWithSuffix> filesUsedCurrent, Set<FileWithSuffix> filesUsedGlobal, File newCurrentDir, Set<FileWithSuffix> filesUsedCurrent, Set<FileWithSuffix> filesUsedGlobal,
DefinitionsContainer definitionsContainer) { DefinitionsContainer definitionsContainer) {
this.config = config;
this.defines = defines; this.defines = defines;
this.charset = charset; this.charset = charset;
this.reader2 = reader; this.reader2 = reader;
@ -117,6 +120,11 @@ public class PreprocessorInclude implements ReadLine {
public CharSequence2 readLine() throws IOException { public CharSequence2 readLine() throws IOException {
final CharSequence2 result = readLineInternal(); final CharSequence2 result = readLineInternal();
if (result != null && StartUtils.isArobaseStartDiagram(result) && config.size() > 0) {
final List<String> empty = new ArrayList<String>();
included = new PreprocessorInclude(empty, new ReadLineList(config, result.getLocation()), defines, charset,
null, filesUsedCurrent, filesUsedGlobal, definitionsContainer);
}
if (result != null && (StartUtils.isArobaseEndDiagram(result) || StartUtils.isArobaseStartDiagram(result))) { if (result != null && (StartUtils.isArobaseEndDiagram(result) || StartUtils.isArobaseStartDiagram(result))) {
// http://plantuml.sourceforge.net/qa/?qa=3389/error-generating-when-same-file-included-different-diagram // http://plantuml.sourceforge.net/qa/?qa=3389/error-generating-when-same-file-included-different-diagram
filesUsedCurrent.clear(); filesUsedCurrent.clear();
@ -173,8 +181,8 @@ public class PreprocessorInclude implements ReadLine {
} }
try { try {
final URL url = new URL(urlString); final URL url = new URL(urlString);
included = new PreprocessorInclude(getReaderInclude(s, url, suf), defines, charset, null, filesUsedCurrent, included = new PreprocessorInclude(config, getReaderInclude(s, url, suf), defines, charset, null,
filesUsedGlobal, definitionsContainer); filesUsedCurrent, filesUsedGlobal, definitionsContainer);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
return s.withErrorPreprocessor("Cannot include url " + urlString); return s.withErrorPreprocessor("Cannot include url " + urlString);
} }
@ -184,8 +192,8 @@ public class PreprocessorInclude implements ReadLine {
private CharSequence2 manageDefinitionInclude(CharSequence2 s, Matcher2 matcher) throws IOException { private CharSequence2 manageDefinitionInclude(CharSequence2 s, Matcher2 matcher) throws IOException {
final String definitionName = matcher.group(1); final String definitionName = matcher.group(1);
final List<? extends CharSequence> definition = definitionsContainer.getDefinition(definitionName); final List<? extends CharSequence> definition = definitionsContainer.getDefinition(definitionName);
included = new PreprocessorInclude(new ReadLineList(definition, s.getLocation()), defines, charset, null, included = new PreprocessorInclude(config, new ReadLineList(definition, s.getLocation()), defines, charset,
filesUsedCurrent, filesUsedGlobal, definitionsContainer); null, filesUsedCurrent, filesUsedGlobal, definitionsContainer);
return this.readLine(); return this.readLine();
} }
@ -197,8 +205,8 @@ public class PreprocessorInclude implements ReadLine {
if (strlibReader == null) { if (strlibReader == null) {
return s.withErrorPreprocessor("Cannot include " + fileName); return s.withErrorPreprocessor("Cannot include " + fileName);
} }
included = new PreprocessorInclude(strlibReader, defines, charset, null, filesUsedCurrent, filesUsedGlobal, included = new PreprocessorInclude(config, strlibReader, defines, charset, null, filesUsedCurrent,
definitionsContainer); filesUsedGlobal, definitionsContainer);
return this.readLine(); return this.readLine();
} }
final int idx = fileName.lastIndexOf('!'); final int idx = fileName.lastIndexOf('!');
@ -214,12 +222,11 @@ public class PreprocessorInclude implements ReadLine {
} else if (allowMany == false && filesUsedCurrent.contains(f2)) { } else if (allowMany == false && filesUsedCurrent.contains(f2)) {
// return CharSequence2Impl.errorPreprocessor("File already included " + f.getAbsolutePath(), lineLocation); // return CharSequence2Impl.errorPreprocessor("File already included " + f.getAbsolutePath(), lineLocation);
return this.readLine(); return this.readLine();
} else {
filesUsedCurrent.add(f2);
filesUsedGlobal.add(f2);
included = new PreprocessorInclude(getReaderInclude(s, f, suf), defines, charset, f.getParentFile(),
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
} }
filesUsedCurrent.add(f2);
filesUsedGlobal.add(f2);
included = new PreprocessorInclude(config, getReaderInclude(s, f, suf), defines, charset, f.getParentFile(),
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
return this.readLine(); return this.readLine();
} }

View File

@ -0,0 +1,72 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.preproc;
import java.io.IOException;
import net.sourceforge.plantuml.CharSequence2;
public class ReadLineConcat implements ReadLine {
private ReadLine file1;
final private ReadLine file2;
public ReadLineConcat(ReadLine file1, ReadLine file2) {
this.file1 = file1;
this.file2 = file2;
}
public void close() throws IOException {
if (file1 != null) {
throw new IllegalStateException();
}
file2.close();
}
public CharSequence2 readLine() throws IOException {
CharSequence2 result = null;
if (file1 != null) {
result = file1.readLine();
if (result == null) {
file1.close();
file1 = null;
}
return readLine();
}
return file2.readLine();
}
}

View File

@ -0,0 +1,61 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.preproc;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.LineLocation;
public class Sub {
private final String name;
private final List<CharSequence2> lines = new ArrayList<CharSequence2>();
public Sub(String name) {
this.name = name;
}
public void add(CharSequence2 s) {
this.lines.add(s);
}
public ReadLine getReadLine(LineLocation lineLocation) {
return new ReadLineList(lines, lineLocation);
}
}

View File

@ -0,0 +1,183 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.preproc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.DefinitionsContainer;
import net.sourceforge.plantuml.FileSystem;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
public class SubPreprocessor implements ReadLine {
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
private static final Pattern2 includeSubPattern = MyPattern.cmpile("^[%s]*!includesub[%s]+[%g]?([^%g]+)[%g]?$");
private static final Pattern2 startsub = MyPattern.cmpile("^[%s]*!startsub[%s]+(" + ID + ")");
private static final Pattern2 endsub = MyPattern.cmpile("^[%s]*!endsub[%s]*");
private final ReadLine source;
private final Defines defines;
private final DefinitionsContainer definitionsContainer;
private final String charset;
private final Map<String, Sub> subs = new HashMap<String, Sub>();
private final List<String> config;
private Sub learningSub;
private ReadLine includedSub;
public SubPreprocessor(List<String> config, String charset, Defines defines,
DefinitionsContainer definitionsContainer, ReadLine source) {
this.config = config;
this.source = source;
this.charset = charset;
this.defines = defines;
this.definitionsContainer = definitionsContainer;
}
public CharSequence2 readLine() throws IOException {
if (includedSub != null) {
final CharSequence2 s = includedSub.readLine();
if (s != null) {
eventuallyLearn(s);
return s;
}
includedSub = null;
}
final CharSequence2 s = source.readLine();
if (s == null) {
return null;
}
final Matcher2 m1 = includeSubPattern.matcher(s);
if (m1.find()) {
return manageIncludeSub(s, m1);
}
Matcher2 m = startsub.matcher(s);
if (m.find()) {
return manageStartsub(m);
}
m = endsub.matcher(s);
if (m.find()) {
return manageEndsub(m);
}
eventuallyLearn(s);
return s;
}
private void eventuallyLearn(final CharSequence2 s) {
if (learningSub != null) {
learningSub.add(s);
}
}
private CharSequence2 manageIncludeSub(CharSequence2 s, Matcher2 m) throws IOException {
final String name = m.group(1);
final int idx = name.indexOf('!');
if (idx != -1) {
final String filename = name.substring(0, idx);
final String blocname = name.substring(idx + 1);
final File f = FileSystem.getInstance().getFile(PreprocessorInclude.withEnvironmentVariable(filename));
if (f.exists() == false || f.isDirectory()) {
return s.withErrorPreprocessor("Cannot include " + f.getAbsolutePath());
}
final Preprocessor data = new Preprocessor(config, getReaderInclude(s, f), charset, defines, null,
definitionsContainer);
while (data.readLine() != null) {
// Read file
}
data.close();
this.includedSub = data.getSub(blocname).getReadLine(s.getLocation());
} else {
this.includedSub = getSub(name).getReadLine(s.getLocation());
}
return this.readLine();
}
private ReadLine getReaderInclude(CharSequence2 s, final File f) {
try {
if (charset == null) {
Log.info("Using default charset");
return new ReadLineReader(new FileReader(f), f.getAbsolutePath(), s.getLocation());
}
Log.info("Using charset " + charset);
return new ReadLineReader(new InputStreamReader(new FileInputStream(f), charset), f.getAbsolutePath(),
s.getLocation());
} catch (IOException e) {
return new ReadLineSimple(s, e.toString());
}
}
private CharSequence2 manageStartsub(Matcher2 m) throws IOException {
final String name = m.group(1);
this.learningSub = getSub(name);
return this.readLine();
}
private CharSequence2 manageEndsub(Matcher2 m) throws IOException {
this.learningSub = null;
return this.readLine();
}
Sub getSub(String name) {
Sub result = subs.get(name);
if (result == null) {
result = new Sub(name);
subs.put(name, result);
}
return result;
}
public void close() throws IOException {
source.close();
}
}

View File

@ -0,0 +1,83 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project3;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class CommandGanttArrow extends SingleLineCommand2<GanttDiagram> {
public CommandGanttArrow() {
super(getRegexConcat());
}
static RegexConcat getRegexConcat() {
return new RegexConcat(new RegexLeaf("^"), //
new RegexLeaf("CODE1", "([\\p{L}0-9_.]+)"), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("ARROW", "(-+)\\>"), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("CODE2", "([\\p{L}0-9_.]+)"), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("$"));
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) {
final String code1 = arg.get("CODE1", 0);
final String code2 = arg.get("CODE2", 0);
final Task task1 = diagram.getExistingTask(code1);
if (task1 == null) {
return CommandExecutionResult.error("No such task " + code1);
}
final Task task2 = diagram.getExistingTask(code2);
if (task2 == null) {
return CommandExecutionResult.error("No such task " + code2);
}
final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END);
task2.setStart(end1.getInstantPrecise());
diagram.addContraint(new GanttConstraint(end1, new TaskInstant(task2, TaskAttribute.START)));
return CommandExecutionResult.ok();
}
}

View File

@ -35,7 +35,7 @@
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project3;
public class DayAsDate implements Complement { public class DayAsDate implements Complement, Comparable<DayAsDate> {
private final int year; private final int year;
private final int dayOfMonth; private final int dayOfMonth;
@ -55,6 +55,10 @@ public class DayAsDate implements Complement {
this.month = month; this.month = month;
} }
private int internalNumber() {
return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth;
}
@Override @Override
public String toString() { public String toString() {
return "" + year + "/" + month + "/" + dayOfMonth; return "" + year + "/" + month + "/" + dayOfMonth;
@ -94,4 +98,21 @@ public class DayAsDate implements Complement {
final int h = ((q + 13 * (m + 1) / 5) + k + k / 4 + j / 4 + 5 * j) % 7; final int h = ((q + 13 * (m + 1) / 5) + k + k / 4 + j / 4 + 5 * j) % 7;
return DayOfWeek.fromH(h); return DayOfWeek.fromH(h);
} }
public InstantDay asInstantDay(DayAsDate reference) {
// if (this.compareTo(reference) < 0) {
// throw new IllegalArgumentException();
// }
int cmp = 0;
DayAsDate current = reference;
while (current.compareTo(this) < 0) {
current = current.next();
cmp++;
}
return new InstantDay(cmp);
}
public int compareTo(DayAsDate other) {
return this.internalNumber() - other.internalNumber();
}
} }

View File

@ -41,4 +41,6 @@ public interface GCalendar {
public DayAsDate toDayAsDate(InstantDay day); public DayAsDate toDayAsDate(InstantDay day);
public DayAsDate getStartingDate();
} }

View File

@ -51,4 +51,8 @@ public class GCalendarSimple implements GCalendar {
return result; return result;
} }
public DayAsDate getStartingDate() {
return start;
}
} }

View File

@ -75,7 +75,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
private final IHtmlColorSet colorSet = new HtmlColorSetSimple(); private final IHtmlColorSet colorSet = new HtmlColorSetSimple();
private GCalendar calendar; private GCalendar calendar;
private Instant min; private final Instant min = new InstantDay(0);
private Instant max; private Instant max;
public DiagramDescription getDescription() { public DiagramDescription getDescription() {
@ -95,7 +95,8 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, "", "", 0, 0, null, final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, "", "", 0, 0, null,
false); false);
imageBuilder.setUDrawable(getUDrawable()); final UDrawable result = getUDrawable();
imageBuilder.setUDrawable(result);
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os);
} }
@ -226,14 +227,14 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
} }
private void initMinMax() { private void initMinMax() {
min = tasks.values().iterator().next().getStart(); // min = tasks.values().iterator().next().getStart();
max = tasks.values().iterator().next().getEnd(); max = tasks.values().iterator().next().getEnd();
for (Task task : tasks.values()) { for (Task task : tasks.values()) {
final Instant start = task.getStart(); final Instant start = task.getStart();
final Instant end = task.getEnd(); final Instant end = task.getEnd();
if (min.compareTo(start) > 0) { // if (min.compareTo(start) > 0) {
min = start; // min = start;
} // }
if (max.compareTo(end) < 0) { if (max.compareTo(end) < 0) {
max = end; max = end;
} }
@ -320,4 +321,8 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
this.calendar = new GCalendarSimple(start); this.calendar = new GCalendarSimple(start);
} }
public DayAsDate getStartingDate() {
return this.calendar.getStartingDate();
}
} }

View File

@ -54,20 +54,21 @@ public class GanttDiagramFactory extends UmlDiagramFactory {
return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek()); return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek());
} }
public GanttDiagramFactory() { public GanttDiagramFactory(DiagramType type) {
super(DiagramType.UML); super(type);
} }
@Override @Override
protected List<Command> createCommands() { protected List<Command> createCommands() {
final List<Command> cmds = new ArrayList<Command>(); final List<Command> cmds = new ArrayList<Command>();
//addCommonCommands(cmds);
cmds.add(new CommandNope()); cmds.add(new CommandNope());
cmds.add(new CommandComment()); cmds.add(new CommandComment());
cmds.add(new CommandMultilinesComment()); cmds.add(new CommandMultilinesComment());
for (Command cmd : getLanguageCommands()) { for (Command cmd : getLanguageCommands()) {
cmds.add(cmd); cmds.add(cmd);
} }
cmds.add(new CommandGanttArrow());
return cmds; return cmds;
} }

View File

@ -45,8 +45,8 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
public class SubjectTask implements SubjectPattern { public class SubjectTask implements SubjectPattern {
public Collection<VerbPattern> getVerbs() { public Collection<VerbPattern> getVerbs() {
return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbStarts(), new VerbHappens(), new VerbEnds(), return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
new VerbIsColored()); new VerbHappens(), new VerbEnds(), new VerbIsColored());
} }
public IRegex toRegex() { public IRegex toRegex() {

View File

@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.command.regex.RegexResult;
public class VerbStarts implements VerbPattern { public class VerbTaskStarts implements VerbPattern {
public Collection<ComplementPattern> getComplements() { public Collection<ComplementPattern> getComplements() {
return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd());

View File

@ -0,0 +1,67 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project3;
import java.util.Arrays;
import java.util.Collection;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class VerbTaskStartsAbsolute implements VerbPattern {
public Collection<ComplementPattern> getComplements() {
return Arrays.<ComplementPattern> asList(new ComplementDate());
}
public IRegex toRegex() {
return new RegexLeaf("starts[%s]*(the[%s]*|on[%s]*)*");
}
public Verb getVerb(final GanttDiagram project, RegexResult arg) {
return new Verb() {
public CommandExecutionResult execute(Subject subject, Complement complement) {
final Task task = (Task) subject;
final DayAsDate start = (DayAsDate) complement;
task.setStart(start.asInstantDay(project.getStartingDate()));
return CommandExecutionResult.ok();
}
};
}
}

View File

@ -158,8 +158,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
final Dimension2D dimTitle = compTitle.calculateDimension(stringBounder); final Dimension2D dimTitle = compTitle.calculateDimension(stringBounder);
area.setTitleArea(dimTitle.getWidth(), dimTitle.getHeight()); area.setTitleArea(dimTitle.getWidth(), dimTitle.getHeight());
} }
area.initFooter(getPngTitler(FontParam.FOOTER), stringBounder); area.initFooter(getPngTitler(FontParam.FOOTER, index), stringBounder);
area.initHeader(getPngTitler(FontParam.HEADER), stringBounder); area.initHeader(getPngTitler(FontParam.HEADER, index), stringBounder);
final DisplayPositionned legend = diagram.getLegend(); final DisplayPositionned legend = diagram.getLegend();
final TextBlock legendBlock; final TextBlock legendBlock;
@ -178,8 +178,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
final String metadata = fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null; final String metadata = fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null;
final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam(), oneOf(scale, dpiFactor), metadata, null, 3, final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam(), oneOf(scale, dpiFactor), metadata,
10, diagram.getAnimation()); null, 3, 10, diagram.getAnimation());
imageBuilder.setUDrawable(new UDrawable() { imageBuilder.setUDrawable(new UDrawable() {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
@ -213,8 +213,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
drawableSet.drawU22(ug.apply(new UTranslate(area.getSequenceAreaX() + delta1 / 2, sequenceAreaY)), drawableSet.drawU22(ug.apply(new UTranslate(area.getSequenceAreaX() + delta1 / 2, sequenceAreaY)),
delta, fullDimension.getWidth(), page, diagram.isShowFootbox()); delta, fullDimension.getWidth(), page, diagram.isShowFootbox());
drawHeader(area, ug); drawHeader(area, ug, index);
drawFooter(area, ug); drawFooter(area, ug, index);
if (DisplayPositionned.isNull(legend) == false) { if (DisplayPositionned.isNull(legend) == false) {
final double delta2; final double delta2;
@ -234,8 +234,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os);
} }
private void drawFooter(SequenceDiagramArea area, UGraphic ug) { private void drawFooter(SequenceDiagramArea area, UGraphic ug, int page) {
final PngTitler pngTitler = getPngTitler(FontParam.FOOTER); final PngTitler pngTitler = getPngTitler(FontParam.FOOTER, page);
final TextBlock text = pngTitler.getTextBlock(); final TextBlock text = pngTitler.getTextBlock();
if (text == null) { if (text == null) {
return; return;
@ -244,8 +244,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
.getFooterY()))); .getFooterY())));
} }
private void drawHeader(SequenceDiagramArea area, UGraphic ug) { private void drawHeader(SequenceDiagramArea area, UGraphic ug, int page) {
final PngTitler pngTitler = getPngTitler(FontParam.HEADER); final PngTitler pngTitler = getPngTitler(FontParam.HEADER, page);
final TextBlock text = pngTitler.getTextBlock(); final TextBlock text = pngTitler.getTextBlock();
if (text == null) { if (text == null) {
return; return;
@ -281,14 +281,14 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
return diagram.getScale().getScale(width, height); return diagram.getScale().getScale(width, height);
} }
private PngTitler getPngTitler(final FontParam fontParam) { private PngTitler getPngTitler(final FontParam fontParam, int page) {
final HtmlColor hyperlinkColor = diagram.getSkinParam().getHyperlinkColor(); final HtmlColor hyperlinkColor = diagram.getSkinParam().getHyperlinkColor();
final HtmlColor titleColor = diagram.getSkinParam().getFontHtmlColor(null, fontParam); final HtmlColor titleColor = diagram.getSkinParam().getFontHtmlColor(null, fontParam);
final String fontFamily = diagram.getSkinParam().getFont(null, false, fontParam).getFamily(null); final String fontFamily = diagram.getSkinParam().getFont(null, false, fontParam).getFamily(null);
final int fontSize = diagram.getSkinParam().getFont(null, false, fontParam).getSize(); final int fontSize = diagram.getSkinParam().getFont(null, false, fontParam).getSize();
return new PngTitler(titleColor, diagram.getFooterOrHeaderTeoz(fontParam).getDisplay(), fontSize, fontFamily, final Display display = diagram.getFooterOrHeaderTeoz(fontParam).getDisplay().withPage(page + 1, pages.size());
diagram.getFooterOrHeaderTeoz(fontParam).getHorizontalAlignment(), hyperlinkColor, diagram return new PngTitler(titleColor, display, fontSize, fontFamily, diagram.getFooterOrHeaderTeoz(fontParam)
.getSkinParam().useUnderlineForHyperlink()); .getHorizontalAlignment(), hyperlinkColor, diagram.getSkinParam().useUnderlineForHyperlink());
} }
} }

View File

@ -54,15 +54,17 @@ public class ComponentRoseEnglober extends AbstractTextualComponent {
private final SymbolContext symbolContext; private final SymbolContext symbolContext;
public ComponentRoseEnglober(SymbolContext symbolContext, Display strings, FontConfiguration font, ISkinSimple spriteContainer) { public ComponentRoseEnglober(SymbolContext symbolContext, Display strings, FontConfiguration font,
super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.CENTER, 3, 3, 1, spriteContainer, false, null, null); ISkinSimple spriteContainer) {
super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.CENTER, 3, 3, 1, spriteContainer, false, null,
null);
this.symbolContext = symbolContext; this.symbolContext = symbolContext;
} }
@Override @Override
protected void drawBackgroundInternalU(UGraphic ug, Area area) { protected void drawBackgroundInternalU(UGraphic ug, Area area) {
final Dimension2D dimensionToUse = area.getDimensionToUse(); final Dimension2D dimensionToUse = area.getDimensionToUse();
ug = symbolContext.apply(ug); ug = symbolContext.transparentBackColorToNull().apply(ug);
ug.draw(new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight())); ug.draw(new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight()));
final double xpos = (dimensionToUse.getWidth() - getPureTextWidth(ug.getStringBounder())) / 2; final double xpos = (dimensionToUse.getWidth() - getPureTextWidth(ug.getStringBounder())) / 2;
getTextBlock().drawU(ug.apply(new UTranslate(xpos, 0))); getTextBlock().drawU(ug.apply(new UTranslate(xpos, 0)));

View File

@ -44,6 +44,7 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.graphic.VerticalAlignment;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -141,6 +142,11 @@ public class DecorateEntityImage extends AbstractTextBlock implements TextBlockB
return Dimension2DDouble.mergeTB(dimOriginal, dimText); return Dimension2DDouble.mergeTB(dimOriginal, dimText);
} }
@Override
public MinMax getMinMax(StringBounder stringBounder) {
return MinMax.fromDim(calculateDimension(stringBounder));
}
public final double getDeltaX() { public final double getDeltaX() {
if (original instanceof DecorateEntityImage) { if (original instanceof DecorateEntityImage) {
return deltaX + ((DecorateEntityImage) original).deltaX; return deltaX + ((DecorateEntityImage) original).deltaX;

View File

@ -47,4 +47,10 @@ public class ExtremityFactoryCrowfoot extends AbstractExtremityFactory implement
final double ortho = atan2(p0, p2); final double ortho = atan2(p0, p2);
return new ExtremityCrowfoot(p1, ortho, side); return new ExtremityCrowfoot(p1, ortho, side);
} }
@Override
public UDrawable createUDrawable(Point2D p0, double angle, Side side) {
throw new UnsupportedOperationException(getClass().toString());
}
} }

View File

@ -145,7 +145,6 @@ public class ImageHelper {
* dimensions of the area the image is to be drawn in. * dimensions of the area the image is to be drawn in.
*/ */
public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) { public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
final int originalWidth = imgSize.width; final int originalWidth = imgSize.width;
final int originaHeight = imgSize.height; final int originaHeight = imgSize.height;
final int boundWidth = boundary.width; final int boundWidth = boundary.width;
@ -172,6 +171,25 @@ public class ImageHelper {
return new Dimension(newWidth, newHeight); return new Dimension(newWidth, newHeight);
} }
public static Dimension getScaledDimensionWidthFit(Dimension imgSize, Dimension boundary) {
final int originalWidth = imgSize.width;
final int originaHeight = imgSize.height;
final int boundWidth = boundary.width;
final int boundHeight = boundary.height;
int newWidth = originalWidth;
int newHeight = originaHeight;
// first check if we need to scale width
if (originalWidth != boundWidth) {
// scale width to fit
newWidth = boundWidth;
// scale height to maintain aspect ratio
newHeight = (newWidth * originaHeight) / originalWidth;
}
return new Dimension(newWidth, newHeight);
}
public static Dimension getScaledDimension(Dimension dim, double zoom) { public static Dimension getScaledDimension(Dimension dim, double zoom) {
return new Dimension((int) (dim.getWidth() * zoom), (int) (dim.getHeight() * zoom)); return new Dimension((int) (dim.getWidth() * zoom), (int) (dim.getHeight() * zoom));
} }

View File

@ -85,6 +85,7 @@ class ImageWindow2 extends JFrame {
private final static Preferences prefs = Preferences.userNodeForPackage(ImageWindow2.class); private final static Preferences prefs = Preferences.userNodeForPackage(ImageWindow2.class);
private final static String KEY_ZOOM_FIT = "zoomfit"; private final static String KEY_ZOOM_FIT = "zoomfit";
private final static String KEY_WIDTH_FIT = "widthfit";
private SimpleLine2 simpleLine2; private SimpleLine2 simpleLine2;
private final JScrollPane scrollPane; private final JScrollPane scrollPane;
@ -92,6 +93,7 @@ class ImageWindow2 extends JFrame {
private final JButton copy = new JButton("Copy"); private final JButton copy = new JButton("Copy");
private final JButton previous = new JButton("Previous"); private final JButton previous = new JButton("Previous");
private final JCheckBox zoomFitButt = new JCheckBox("Zoom fit"); private final JCheckBox zoomFitButt = new JCheckBox("Zoom fit");
private final JCheckBox widthFitButt = new JCheckBox("Width fit");
private final JButton zoomMore = new JButton("+"); private final JButton zoomMore = new JButton("+");
private final JButton zoomLess = new JButton("-"); private final JButton zoomLess = new JButton("-");
private final MainWindow2 main; private final MainWindow2 main;
@ -101,7 +103,7 @@ class ImageWindow2 extends JFrame {
private int zoomFactor = 0; private int zoomFactor = 0;
private enum SizeMode { private enum SizeMode {
FULL_SIZE, ZOOM_FIT FULL_SIZE, ZOOM_FIT, WIDTH_FIT
}; };
private SizeMode sizeMode = SizeMode.FULL_SIZE; private SizeMode sizeMode = SizeMode.FULL_SIZE;
@ -121,6 +123,7 @@ class ImageWindow2 extends JFrame {
north.add(copy); north.add(copy);
north.add(next); north.add(next);
north.add(zoomFitButt); north.add(zoomFitButt);
north.add(widthFitButt);
north.add(zoomMore); north.add(zoomMore);
north.add(zoomLess); north.add(zoomLess);
copy.setFocusable(false); copy.setFocusable(false);
@ -144,6 +147,14 @@ class ImageWindow2 extends JFrame {
zoomFitButt.setFocusable(false); zoomFitButt.setFocusable(false);
zoomFitButt.addActionListener(new ActionListener() { zoomFitButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
widthFitButt.setSelected(false);
zoomFit();
}
});
widthFitButt.setFocusable(false);
widthFitButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
zoomFitButt.setSelected(false);
zoomFit(); zoomFit();
} }
}); });
@ -189,6 +200,11 @@ class ImageWindow2 extends JFrame {
if (zoomChecked) { if (zoomChecked) {
sizeMode = SizeMode.ZOOM_FIT; sizeMode = SizeMode.ZOOM_FIT;
} }
final boolean widthZoomChecked = prefs.getBoolean(KEY_WIDTH_FIT, false);
widthFitButt.setSelected(widthZoomChecked);
if (widthZoomChecked) {
sizeMode = SizeMode.WIDTH_FIT;
}
this.setFocusable(true); this.setFocusable(true);
this.addKeyListener(new KeyAdapter() { this.addKeyListener(new KeyAdapter() {
@ -251,11 +267,15 @@ class ImageWindow2 extends JFrame {
} }
private void zoomFit() { private void zoomFit() {
final boolean selected = zoomFitButt.isSelected(); final boolean selectedZoom = zoomFitButt.isSelected();
prefs.putBoolean(KEY_ZOOM_FIT, selected); final boolean selectedWidth = widthFitButt.isSelected();
prefs.putBoolean(KEY_ZOOM_FIT, selectedZoom);
prefs.putBoolean(KEY_WIDTH_FIT, selectedWidth);
zoomFactor = 0; zoomFactor = 0;
if (selected) { if (selectedZoom) {
sizeMode = SizeMode.ZOOM_FIT; sizeMode = SizeMode.ZOOM_FIT;
} else if (selectedWidth) {
sizeMode = SizeMode.WIDTH_FIT;
} else { } else {
sizeMode = SizeMode.FULL_SIZE; sizeMode = SizeMode.FULL_SIZE;
} }
@ -297,6 +317,11 @@ class ImageWindow2 extends JFrame {
final Dimension newImgDim = ImageHelper final Dimension newImgDim = ImageHelper
.getScaledDimension(imageDim, scrollPane.getViewport().getSize()); .getScaledDimension(imageDim, scrollPane.getViewport().getSize());
image = ImageHelper.getScaledInstance(image, newImgDim, getHints(), true); image = ImageHelper.getScaledInstance(image, newImgDim, getHints(), true);
} else if (sizeMode == SizeMode.WIDTH_FIT) {
final Dimension imageDim = new Dimension(image.getWidth(), image.getHeight());
final Dimension newImgDim = ImageHelper.getScaledDimensionWidthFit(imageDim, scrollPane.getViewport()
.getSize());
image = ImageHelper.getScaledInstance(image, newImgDim, getHints(), false);
} else if (zoomFactor != 0) { } else if (zoomFactor != 0) {
final Dimension imageDim = new Dimension(image.getWidth(), image.getHeight()); final Dimension imageDim = new Dimension(image.getWidth(), image.getHeight());
final Dimension newImgDim = ImageHelper.getScaledDimension(imageDim, getZoom()); final Dimension newImgDim = ImageHelper.getScaledDimension(imageDim, getZoom());

View File

@ -289,7 +289,6 @@ public class MainWindow2 extends JFrame {
final JFileChooser chooser = new JFileChooser(); final JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.CUSTOM_DIALOG); chooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
chooser.setDialogTitle("Directory to watch:"); chooser.setDialogTitle("Directory to watch:");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false); chooser.setAcceptAllFileFilterUsed(false);
final String currentPath = prefs.get(KEY_DIR, "."); final String currentPath = prefs.get(KEY_DIR, ".");
chooser.setCurrentDirectory(new File(currentPath)); chooser.setCurrentDirectory(new File(currentPath));
@ -298,7 +297,11 @@ public class MainWindow2 extends JFrame {
Log.info("Closing OpenDialog"); Log.info("Closing OpenDialog");
if (returnVal == JFileChooser.APPROVE_OPTION) { if (returnVal == JFileChooser.APPROVE_OPTION) {
final File dir = chooser.getSelectedFile(); final File dir = chooser.getSelectedFile();
changeDir(dir); if (dir.isDirectory()) {
changeDir(dir);
} else {
changeDir(dir.getParentFile());
}
} }
} }

View File

@ -40,11 +40,14 @@ import java.awt.geom.PathIterator;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.SignatureUtils;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.eps.EpsGraphics;
import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.UPath;
@ -75,6 +78,29 @@ public class TikzGraphics {
this.scale = scale; this.scale = scale;
} }
private final Map<String, Integer> styles = new LinkedHashMap<String, Integer>();
private final Map<String, String> stylesID = new HashMap<String, String>();
private void addCommand(final StringBuilder sb) {
final String s = sb.toString();
cmd.add(s);
if (s.startsWith("\\draw[") || s.startsWith("\\shade[")) {
final int end = s.indexOf(']');
if (end != -1) {
final int start = s.indexOf('[');
final String style = s.substring(start + 1, end);
Integer count = styles.get(style);
if (count == null) {
count = 1;
stylesID.put(style, "pstyle" + stylesID.size());
} else {
count++;
}
styles.put(style, count);
}
}
}
private String getColorName(Color c) { private String getColorName(Color c) {
if (c.equals(Color.WHITE)) { if (c.equals(Color.WHITE)) {
return "white"; return "white";
@ -142,9 +168,14 @@ public class TikzGraphics {
if (scale != 1) { if (scale != 1) {
out(os, "\\scalebox{" + format(scale) + "}{"); out(os, "\\scalebox{" + format(scale) + "}{");
} }
out(os, "\\begin{tikzpicture}[yscale=-1]"); out(os, "\\begin{tikzpicture}[yscale=-1");
purgeStyles();
for (String style : styles.keySet()) {
out(os, "," + stylesID.get(style) + "/.style={" + style + "}");
}
out(os, "]");
for (String s : cmd) { for (String s : cmd) {
out(os, s); out(os, useStyle(s));
} }
out(os, "\\end{tikzpicture}"); out(os, "\\end{tikzpicture}");
if (scale != 1) { if (scale != 1) {
@ -155,6 +186,31 @@ public class TikzGraphics {
} }
} }
private String useStyle(String s) {
for (String style : styles.keySet()) {
final String start1 = "\\draw[" + style + "]";
if (s.startsWith(start1)) {
final String newStart = "\\draw[" + stylesID.get(style) + "]";
return newStart + s.substring(start1.length());
}
final String start2 = "\\shade[" + style + "]";
if (s.startsWith(start2)) {
final String newStart = "\\shade[" + stylesID.get(style) + "]";
return newStart + s.substring(start2.length());
}
}
return s;
}
private void purgeStyles() {
for (Iterator<Map.Entry<String, Integer>> it = styles.entrySet().iterator(); it.hasNext();) {
final Map.Entry<String, Integer> ent = it.next();
if (ent.getValue().intValue() == 1) {
it.remove();
}
}
}
private String definecolor(String name, Color color) { private String definecolor(String name, Color color) {
return "\\definecolor{" + name + "}{RGB}{" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() return "\\definecolor{" + name + "}{RGB}{" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
+ "}"; + "}";
@ -162,23 +218,8 @@ public class TikzGraphics {
public void rectangle(double x, double y, double width, double height) { public void rectangle(double x, double y, double width, double height) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final boolean gradient = this.fillcolorGradient2 != null;
if (pendingUrl == null) { if (pendingUrl == null) {
sb.append(gradient ? "\\shade[" : "\\draw["); appendShadeOrDraw(sb);
if (color != null) {
sb.append(gradient ? "draw=" : "color=");
sb.append(getColorName(color) + ",");
}
if (gradient) {
sb.append("top color=" + getColorName(fillcolor) + ",");
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
} else if (fillcolor != null) {
sb.append("fill=" + getColorName(fillcolor) + ",");
if (color == null) {
sb.append("color=" + getColorName(fillcolor) + ",");
}
}
sb.append("line width=" + thickness + "pt] "); sb.append("line width=" + thickness + "pt] ");
sb.append(couple(x, y) + " rectangle " + couple(x + width, y + height)); sb.append(couple(x, y) + " rectangle " + couple(x + width, y + height));
sb.append(";"); sb.append(";");
@ -207,7 +248,7 @@ public class TikzGraphics {
sb.append(" {};"); sb.append(" {};");
urlIgnoreText = true; urlIgnoreText = true;
} }
cmd.add(sb.toString()); addCommand(sb);
} }
private String getAngleFromGradientPolicy() { private String getAngleFromGradientPolicy() {
@ -235,11 +276,11 @@ public class TikzGraphics {
} }
private void out(OutputStream os, String s) throws IOException { private void out(OutputStream os, String s) throws IOException {
os.write(s.getBytes()); os.write(s.getBytes("UTF-8"));
os.write("\n".getBytes()); os.write("\n".getBytes("UTF-8"));
} }
public void text(double x, double y, String text) { public void text(double x, double y, String text, boolean underline, boolean italic, boolean bold) {
final StringBuilder sb = new StringBuilder("\\node at " + couple(x, y)); final StringBuilder sb = new StringBuilder("\\node at " + couple(x, y));
sb.append("[below right"); sb.append("[below right");
if (color != null) { if (color != null) {
@ -248,7 +289,25 @@ public class TikzGraphics {
} }
sb.append("]{"); sb.append("]{");
if (pendingUrl == null || urlIgnoreText) { if (pendingUrl == null || urlIgnoreText) {
if (underline) {
sb.append("\\underline{");
}
if (italic) {
sb.append("\\textit{");
}
if (bold) {
sb.append("\\textbf{");
}
sb.append(protectText(text)); sb.append(protectText(text));
if (bold) {
sb.append("}");
}
if (italic) {
sb.append("}");
}
if (underline) {
sb.append("}");
}
} else { } else {
appendPendingUrl(sb); appendPendingUrl(sb);
sb.append("{"); sb.append("{");
@ -256,7 +315,7 @@ public class TikzGraphics {
sb.append("}"); sb.append("}");
} }
sb.append("};"); sb.append("};");
cmd.add(sb.toString()); addCommand(sb);
} }
private void appendPendingUrl(final StringBuilder sb) { private void appendPendingUrl(final StringBuilder sb) {
@ -279,11 +338,14 @@ public class TikzGraphics {
} }
private String protectText(String text) { private String protectText(String text) {
text = text.replaceAll("\\\\", "\\\\\\\\");
text = text.replaceAll("_", "\\\\_"); text = text.replaceAll("_", "\\\\_");
text = text.replaceAll("\u00AB", "\\\\guillemotleft "); text = text.replaceAll("\u00AB", "\\\\guillemotleft ");
text = text.replaceAll("\u00BB", "\\\\guillemotright "); text = text.replaceAll("\u00BB", "\\\\guillemotright ");
text = text.replaceAll("<", "\\\\textless "); text = text.replaceAll("<", "\\\\textless ");
text = text.replaceAll(">", "\\\\textgreater "); text = text.replaceAll(">", "\\\\textgreater ");
text = text.replaceAll("&", "\\\\&");
text = text.replaceAll("~", "\\\\~{}");
return text; return text;
} }
@ -302,17 +364,13 @@ public class TikzGraphics {
sb.append(" -- "); sb.append(" -- ");
sb.append(couple(x2, y2)); sb.append(couple(x2, y2));
sb.append(";"); sb.append(";");
cmd.add(sb.toString()); addCommand(sb);
} }
public void polygon(double[] points) { public void polygon(double[] points) {
final StringBuilder sb = new StringBuilder("\\draw[");
if (color != null) { final StringBuilder sb = new StringBuilder();
sb.append("color=" + getColorName(color) + ","); appendShadeOrDraw(sb);
}
if (fillcolor != null) {
sb.append("fill=" + getColorName(fillcolor) + ",");
}
sb.append("line width=" + thickness + "pt]"); sb.append("line width=" + thickness + "pt]");
sb.append(" "); sb.append(" ");
for (int i = 0; i < points.length; i += 2) { for (int i = 0; i < points.length; i += 2) {
@ -320,17 +378,12 @@ public class TikzGraphics {
sb.append(" -- "); sb.append(" -- ");
} }
sb.append("cycle;"); sb.append("cycle;");
cmd.add(sb.toString()); addCommand(sb);
} }
private void round(double r, double[] points) { private void round(double r, double[] points) {
final StringBuilder sb = new StringBuilder("\\draw["); final StringBuilder sb = new StringBuilder();
if (color != null) { appendShadeOrDraw(sb);
sb.append("color=" + getColorName(color) + ",");
}
if (fillcolor != null) {
sb.append("fill=" + getColorName(fillcolor) + ",");
}
sb.append("line width=" + thickness + "pt]"); sb.append("line width=" + thickness + "pt]");
sb.append(" "); sb.append(" ");
int i = 0; int i = 0;
@ -351,7 +404,26 @@ public class TikzGraphics {
sb.append(couple(points[i++], points[i++])); sb.append(couple(points[i++], points[i++]));
sb.append(" -- "); sb.append(" -- ");
sb.append("cycle;"); sb.append("cycle;");
cmd.add(sb.toString()); addCommand(sb);
}
private void appendShadeOrDraw(final StringBuilder sb) {
final boolean gradient = this.fillcolorGradient2 != null;
sb.append(gradient ? "\\shade[" : "\\draw[");
if (color != null) {
sb.append(gradient ? "draw=" : "color=");
sb.append(getColorName(color) + ",");
}
if (gradient) {
sb.append("top color=" + getColorName(fillcolor) + ",");
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
} else if (fillcolor != null) {
sb.append("fill=" + getColorName(fillcolor) + ",");
if (color == null) {
sb.append("color=" + getColorName(fillcolor) + ",");
}
}
} }
public void rectangleRound(double x, double y, double width, double height, double r) { public void rectangleRound(double x, double y, double width, double height, double r) {
@ -381,23 +453,12 @@ public class TikzGraphics {
public void upath(double x, double y, UPath path) { public void upath(double x, double y, UPath path) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final boolean gradient = this.fillcolorGradient2 != null; appendShadeOrDraw(sb);
sb.append(gradient ? "\\shade[" : "\\draw["); sb.append("line width=" + thickness + "pt");
if (color != null) { if (dash != null) {
sb.append(gradient ? "draw=" : "color="); sb.append(",dash pattern=" + dash);
sb.append(getColorName(color) + ",");
} }
if (gradient) { sb.append("] ");
sb.append("top color=" + getColorName(fillcolor) + ",");
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
} else if (fillcolor != null) {
sb.append("fill=" + getColorName(fillcolor) + ",");
if (color == null) {
sb.append("color=" + getColorName(fillcolor) + ",");
}
}
sb.append("line width=" + thickness + "pt] ");
for (USegment seg : path) { for (USegment seg : path) {
final USegmentType type = seg.getSegmentType(); final USegmentType type = seg.getSegmentType();
final double coord[] = seg.getCoord(); final double coord[] = seg.getCoord();
@ -423,7 +484,7 @@ public class TikzGraphics {
} }
} }
sb.append(";"); sb.append(";");
cmd.add(sb.toString()); addCommand(sb);
} }
public void ellipse(double x, double y, double width, double height) { public void ellipse(double x, double y, double width, double height) {
@ -437,7 +498,7 @@ public class TikzGraphics {
} }
sb.append("line width=" + thickness + "pt] " + couple(x, y) + " ellipse (" + format(width) + "pt and " sb.append("line width=" + thickness + "pt] " + couple(x, y) + " ellipse (" + format(width) + "pt and "
+ format(height) + "pt);"); + format(height) + "pt);");
cmd.add(sb.toString()); addCommand(sb);
} }
public void drawSingleCharacter(double x, double y, char c) { public void drawSingleCharacter(double x, double y, char c) {
@ -445,7 +506,7 @@ public class TikzGraphics {
sb.append("\\node at "); sb.append("\\node at ");
sb.append(couple(x, y)); sb.append(couple(x, y));
sb.append("[]{\\textbf{\\Large " + c + "}};"); sb.append("[]{\\textbf{\\Large " + c + "}};");
cmd.add(sb.toString()); addCommand(sb);
} }
public void drawPathIterator(double x, double y, PathIterator path) { public void drawPathIterator(double x, double y, PathIterator path) {
@ -461,7 +522,7 @@ public class TikzGraphics {
sb.append(couple(coord[0] + x, coord[1] + y)); sb.append(couple(coord[0] + x, coord[1] + y));
} else if (code == PathIterator.SEG_CLOSE) { } else if (code == PathIterator.SEG_CLOSE) {
sb.append(";"); sb.append(";");
cmd.add(sb.toString()); addCommand(sb);
sb.setLength(0); sb.setLength(0);
sb.append("\\draw "); sb.append("\\draw ");
} else if (code == PathIterator.SEG_CUBICTO) { } else if (code == PathIterator.SEG_CUBICTO) {

View File

@ -66,7 +66,13 @@ public class CommandTimeMessage extends SingleLineCommand2<TimingDiagram> {
@Override @Override
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
final Player player1 = diagram.getPlayer(arg.get("PART1", 0)); final Player player1 = diagram.getPlayer(arg.get("PART1", 0));
if (player1 == null) {
return CommandExecutionResult.error("No such element: " + arg.get("PART1", 0));
}
final Player player2 = diagram.getPlayer(arg.get("PART2", 0)); final Player player2 = diagram.getPlayer(arg.get("PART2", 0));
if (player2 == null) {
return CommandExecutionResult.error("No such element: " + arg.get("PART2", 0));
}
final TimeTick tick1 = TimeTickBuilder.parseTimeTick("TIME1", arg, diagram); final TimeTick tick1 = TimeTickBuilder.parseTimeTick("TIME1", arg, diagram);
final TimeTick tick2 = TimeTickBuilder.parseTimeTick("TIME2", arg, diagram); final TimeTick tick2 = TimeTickBuilder.parseTimeTick("TIME2", arg, diagram);
diagram.createTimeMessage(player1, tick1, player2, tick2, arg.get("MESSAGE", 0)); diagram.createTimeMessage(player1, tick1, player2, tick2, arg.get("MESSAGE", 0));

View File

@ -55,6 +55,7 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.SymbolContext; import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UStroke;
@ -254,6 +255,10 @@ public class Histogram implements TimeDrawing {
return new Dimension2DDouble(width, getFullDeltaY()); return new Dimension2DDouble(width, getFullDeltaY());
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
return null; return null;
} }

View File

@ -52,6 +52,7 @@ import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
@ -161,6 +162,11 @@ public class Player implements TextBlock, TimeProjected {
return new Dimension2DDouble(width, title.calculateDimension(stringBounder).getHeight() * 2 + zoneHeight); return new Dimension2DDouble(width, title.calculateDimension(stringBounder).getHeight() * 2 + zoneHeight);
} }
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
private double getZoneHeight() { private double getZoneHeight() {
return getTimeDrawing().getHeight(); return getTimeDrawing().getHeight();
} }

Some files were not shown because too many files have changed in this diff Show More