1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00

Import version 1.2020.17

This commit is contained in:
Arnaud Roques 2020-09-19 17:43:24 +02:00
parent 2184f18c50
commit b27fa50b50
67 changed files with 1765 additions and 327 deletions

View File

@ -30,13 +30,12 @@
Script Author: Julien Eluard
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2020.16-SNAPSHOT</version>
<version>1.2020.18-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>

View File

@ -55,7 +55,7 @@ public class StdrptNull implements Stdrpt {
}
public void errorLine(int lineError, File file) {
Log.error("Error line " + lineError + " in file: " + file.getPath());
Log.error("Error line " + (lineError + 1) + " in file: " + file.getPath());
}
}

View File

@ -65,7 +65,7 @@ public class StdrptPipe0 implements Stdrpt {
}
public void errorLine(int lineError, File file) {
Log.error("Error line " + lineError + " in file: " + file.getPath());
Log.error("Error line " + (lineError + 1) + " in file: " + file.getPath());
}
}

View File

@ -55,7 +55,7 @@ public class StdrptV1 implements Stdrpt {
}
public void errorLine(int lineError, File file) {
Log.error("Error line " + lineError + " in file: " + file.getPath());
Log.error("Error line " + (lineError + 1) + " in file: " + file.getPath());
}
private void out(final PrintStream output, final PSystemError err) {
@ -64,7 +64,7 @@ public class StdrptV1 implements Stdrpt {
output.println("status=NO_DATA");
} else {
output.println("status=ERROR");
output.println("lineNumber=" + err.getLineLocation().getPosition());
output.println("lineNumber=" + (err.getLineLocation().getPosition() + 1));
for (ErrorUml er : err.getErrorsUml()) {
output.println("label=" + er.getError());
}

View File

@ -69,7 +69,7 @@ public class StdrptV2 implements Stdrpt {
} else {
line.append(err.getLineLocation().getDescription());
line.append(":");
line.append(err.getLineLocation().getPosition());
line.append(err.getLineLocation().getPosition() + 1);
line.append(":");
line.append("error");
line.append(":");

View File

@ -111,16 +111,15 @@ class FtileRepeat extends AbstractFtile {
}
public static Ftile create(LinkRendering backRepeatLinkRendering, Swimlane swimlane, Swimlane swimlaneOut,
Ftile entry, Ftile repeat, Display test, Display yes, Display out, HColor borderColor,
HColor diamondColor, Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle,
ISkinSimple spriteContainer, FontConfiguration fcDiamond, FontConfiguration fcArrow, Ftile backward,
boolean noOut) {
Ftile entry, Ftile repeat, Display test, Display yes, Display out, HColor borderColor, HColor diamondColor,
Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle, ISkinSimple spriteContainer,
FontConfiguration fcDiamond, FontConfiguration fcArrow, Ftile backward, boolean noOut) {
final FontConfiguration fontConfiguration1 = conditionStyle == ConditionStyle.INSIDE ? fcDiamond : fcArrow;
final TextBlock tbTest = (Display.isNull(test) || test.isWhite()) ? TextBlockUtils.empty(0, 0) : test.create(
fontConfiguration1, repeat.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT),
spriteContainer);
final TextBlock tbTest = (Display.isNull(test) || test.isWhite()) ? TextBlockUtils.empty(0, 0)
: test.create(fontConfiguration1, repeat.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT),
spriteContainer);
final TextBlock yesTb = yes.create(fcArrow, HorizontalAlignment.LEFT, spriteContainer);
final TextBlock outTb = out.create(fcArrow, HorizontalAlignment.LEFT, spriteContainer);
@ -146,7 +145,8 @@ class FtileRepeat extends AbstractFtile {
.withEast(tbTest);
result = new FtileRepeat(repeat, diamond1, diamond2, tbTest, backward);
} else if (conditionStyle == ConditionStyle.FOO1) {
final Ftile diamond2 = new FtileDiamondFoo1(repeat.skinParam(), diamondColor, borderColor, swimlane, tbTest);
final Ftile diamond2 = new FtileDiamondFoo1(repeat.skinParam(), diamondColor, borderColor, swimlane,
tbTest);
result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward);
} else {
throw new IllegalStateException();
@ -154,14 +154,14 @@ class FtileRepeat extends AbstractFtile {
final List<Connection> conns = new ArrayList<Connection>();
final Display in1 = repeat.getInLinkRendering().getDisplay();
final TextBlock tbin1 = in1 == null ? null : in1.create7(fcArrow, HorizontalAlignment.LEFT, spriteContainer,
CreoleMode.SIMPLE_LINE);
final TextBlock tbin1 = in1 == null ? null
: in1.create7(fcArrow, HorizontalAlignment.LEFT, spriteContainer, CreoleMode.SIMPLE_LINE);
conns.add(result.new ConnectionIn(repeat.getInLinkRendering().getRainbow(arrowColor), tbin1));
final Display backLink1 = backRepeatLinkRendering.getDisplay();
final TextBlock tbbackLink1 = backLink1 == null ? null : backLink1.create7(fcArrow, HorizontalAlignment.LEFT,
spriteContainer, CreoleMode.SIMPLE_LINE);
if (repeat.getSwimlaneIn() == swimlaneOut) {
final TextBlock tbbackLink1 = backLink1 == null ? null
: backLink1.create7(fcArrow, HorizontalAlignment.LEFT, spriteContainer, CreoleMode.SIMPLE_LINE);
if (repeat.getSwimlaneIn() == null || repeat.getSwimlaneIn() == swimlaneOut) {
if (backward == null) {
conns.add(result.new ConnectionBackSimple(backRepeatLinkRendering.getRainbow(arrowColor), tbbackLink1));
} else {
@ -176,8 +176,8 @@ class FtileRepeat extends AbstractFtile {
}
final Display out1 = repeat.getOutLinkRendering().getDisplay();
final TextBlock tbout1 = out1 == null ? null : out1.create7(fcArrow, HorizontalAlignment.LEFT, spriteContainer,
CreoleMode.SIMPLE_LINE);
final TextBlock tbout1 = out1 == null ? null
: out1.create7(fcArrow, HorizontalAlignment.LEFT, spriteContainer, CreoleMode.SIMPLE_LINE);
final Rainbow tmpColor = endRepeatLinkColor.withDefault(arrowColor);
conns.add(result.new ConnectionOut(tmpColor, tbout1));
@ -227,13 +227,13 @@ class FtileRepeat extends AbstractFtile {
}
private Point2D getP1(final StringBounder stringBounder) {
return getTranslateForRepeat(stringBounder).getTranslated(
getFtile1().calculateDimension(stringBounder).getPointOut());
return getTranslateForRepeat(stringBounder)
.getTranslated(getFtile1().calculateDimension(stringBounder).getPointOut());
}
private Point2D getP2(final StringBounder stringBounder) {
return getTranslateDiamond2(stringBounder).getTranslated(
getFtile2().calculateDimension(stringBounder).getPointIn());
return getTranslateDiamond2(stringBounder)
.getTranslated(getFtile2().calculateDimension(stringBounder).getPointIn());
}
public void drawU(UGraphic ug) {
@ -545,8 +545,8 @@ class FtileRepeat extends AbstractFtile {
if (backward != null) {
width += backward.calculateDimension(stringBounder).getWidth();
}
final double height = dimDiamond1.getHeight() + dimRepeat.getHeight() + dimDiamond2.getHeight() + 8
* Diamond.diamondHalfSize;
final double height = dimDiamond1.getHeight() + dimRepeat.getHeight() + dimDiamond2.getHeight()
+ 8 * Diamond.diamondHalfSize;
return new Dimension2DDouble(width + 2 * Diamond.diamondHalfSize, height);
}

View File

@ -170,12 +170,8 @@ public class FtileBox extends AbstractFtile {
public static FtileBox createMindMap(StyleBuilder styleBuilder, ISkinParam skinParam, Display label,
StyleSignature styleDefinition) {
Style style = null;
Style styleArrow = null;
if (SkinParam.USE_STYLES()) {
style = styleDefinition.getMergedStyle(styleBuilder);
styleArrow = style;
}
final Style style = styleDefinition.getMergedStyle(styleBuilder);
final Style styleArrow = style;
return new FtileBox(skinParam, label, null, BoxStyle.PLAIN, style, styleArrow);
}

View File

@ -160,15 +160,28 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
String port2 = null;
if (diagram.V1972()) {
if (removeMemberPartIdent(diagram, ident1) != null) {
port1 = ident1.getPortMember();
ident1 = removeMemberPartIdent(diagram, ident1);
code1 = ident1;
}
if (removeMemberPartIdent(diagram, ident2) != null) {
port2 = ident2.getPortMember();
ident2 = removeMemberPartIdent(diagram, ident2);
code2 = ident2;
if ("::".equals(diagram.getNamespaceSeparator())) {
if (removeMemberPartIdentSpecial(diagram, ident1) != null) {
port1 = ident1.getLast();
ident1 = removeMemberPartIdentSpecial(diagram, ident1);
code1 = ident1;
}
if (removeMemberPartIdentSpecial(diagram, ident2) != null) {
port2 = ident2.getLast();
ident2 = removeMemberPartIdentSpecial(diagram, ident2);
code2 = ident1;
}
} else {
if (removeMemberPartIdent(diagram, ident1) != null) {
port1 = ident1.getPortMember();
ident1 = removeMemberPartIdent(diagram, ident1);
code1 = ident1;
}
if (removeMemberPartIdent(diagram, ident2) != null) {
port2 = ident2.getPortMember();
ident2 = removeMemberPartIdent(diagram, ident2);
code2 = ident2;
}
}
} else {
if (removeMemberPartLegacy1972(diagram, ident1) != null) {
@ -251,6 +264,20 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
}
}
private Ident removeMemberPartIdentSpecial(AbstractClassOrObjectDiagram diagram, Ident ident) {
if (diagram.leafExistSmart(ident)) {
return null;
}
final Ident before = ident.parent();
if (before == null) {
return null;
}
if (diagram.leafExistSmart(before) == false) {
return null;
}
return before;
}
private Ident removeMemberPartIdent(AbstractClassOrObjectDiagram diagram, Ident ident) {
if (diagram.leafExistSmart(ident)) {
return null;

View File

@ -161,10 +161,14 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo
char separator = lineFirst ? '_' : 0;
TextBlock title = null;
List<Member> members = new ArrayList<Member>();
// final LineBreakStrategy lineBreakStrategy = skinParam.wrapWidth();
for (ListIterator<CharSequence> it = rawBody.listIterator(); it.hasNext();) {
final CharSequence s2 = it.next();
if (s2 instanceof EmbeddedDiagram) {
if (members.size() > 0) {
blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align,
stereotype, entity, diagramType), separator, title));
members = new ArrayList<Member>();
}
blocks.add(((EmbeddedDiagram) s2).asDraw(skinParam));
} else {
final String s = s2.toString();

View File

@ -40,12 +40,14 @@ import java.io.OutputStream;
public interface Graphviz {
ProcessState createFile3(OutputStream os);
public ProcessState createFile3(OutputStream os);
File getDotExe();
public File getDotExe();
String dotVersion();
public String dotVersion();
ExeState getExeState();
public ExeState getExeState();
public boolean graphviz244onWindows();
}

View File

@ -64,4 +64,8 @@ class GraphvizLinux extends AbstractGraphviz {
return "dot";
}
public boolean graphviz244onWindows() {
return false;
}
}

View File

@ -163,6 +163,15 @@ public class GraphvizUtils {
return dotVersion;
}
public static boolean graphviz244onWindows() {
try {
return create(null, "png").graphviz244onWindows();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static int retrieveVersion(String s) {
if (s == null) {
return -1;

View File

@ -58,6 +58,15 @@ class GraphvizWindows extends AbstractGraphviz {
}
}
public boolean graphviz244onWindows() {
try {
return GraphvizUtils.getDotVersion() == 244;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private File specificDotExeSlow() {
for (File tmp : new File("c:/").listFiles(new FileFilter() {
public boolean accept(java.io.File pathname) {

View File

@ -785,7 +785,6 @@ final public class EntityImpl implements ILeaf, IGroup {
}
public DisplayPositionned getLegend() {
checkGroup();
return legend;
}
@ -800,6 +799,7 @@ final public class EntityImpl implements ILeaf, IGroup {
public void setOriginalGroup(IGroup originalGroup) {
this.originalGroup = originalGroup;
this.legend = originalGroup.getLegend();
}
public IGroup getOriginalGroup() {

View File

@ -74,26 +74,26 @@ public class PSystemDonors extends AbstractPSystem {
private static final int COLS = 6;
private static final int FREE_LINES = 6;
public static final String DONORS = "6omC02mFkBap0p4nqLYNlhbPJVbOScQJ29Rd2SLXO15FTmFY3t3lzBZVI7yHNUdUDys8jcnDSPung1O4"
+ "FPwQQuPjxks1q5RAY-189RY0513Vnibv7ploFdrIPKW9Ogde_il4xUdMSQ4oJbGZb0F5hGtlEsFpx3I-"
+ "UFLeWZO2FmRsrVzTqygwUrKLXdHPrPWQTRh28Oo87E7_KRUfMzJ6oTIcqGCwbNC5DzMfYDFX0Gjea1Ku"
+ "P6qTvwLPawgOI1Cfdjf8mIC6CxJdPFLvyaCVT7wf5z2bjRg6UEw0uZ5JUdJTDjg_xs3x5H8l4ixW2pOB"
+ "pA6Kmtg2ukUc6nqd3n9QTv6DhRxoboSc6FpGGj_yeKYkz1uIsML8qN6fWGAFjp50CYQrQyBPeJy3gkh1"
+ "5lqQXEfolt5thSFoL38R3RU0XOi5jO0QWlmFUi9dz9MNJEwvAM89UPh4Sza6rA-Izz4s5NqphoQ1yBRz"
+ "qCpWLvcozP36bTSn_-hea7SDMRdwpLYZa4SmbvUv5CmlBL0_0Zqq9oA9hob_B2GWN5VgHUywDvtKBC8f"
+ "7L8grkcNsF9QyWzTWSN6HNCwMABFng_BJObW2rsPL4DlQ5MbMUSJ9QcX_dx8ewNpNN1DbTgzGxGUQNEU"
+ "_TzrIpD3SO2EJp4BkXOG2AjfrLTi88B3GfU7t0J81fHFarl-j7o8FV83WZUN2Bh2Hae7-FDDo4CEBin0"
+ "bsvEKG7CdbBgISVjW8Sw7O9kHPLyUfcxVeP9oxPbOsQPjC5rky4O-J6TK9ouN-O2Zp2iKelcv6xj8-mI"
+ "FCxBQLvrhy6yYcvx2-zf5w7zGmRy37D6H2fDL-nxsYNkeOx0BDg2fxhOdcu71m_TjU0KYrOmeqqxP0cO"
+ "N4X6JRr5wKE3uUyWP1DsRohg2smDrwd1pOmqUBuqkQKcHtISjhCS6ri0lERY5Rk2mYb2j2qjcQjh2PCZ"
+ "Laz2XlnEzGaibNLXQSEExQx6Cr6FWZoSzyYgexvDAMuBg3wc2VBIGfWpfCZ3rW8PM2lfMMu3x7vgnuAw"
+ "pKyk77CelcsYxSODCKo1wIdS6maYCJgHbEWb9ea2lklZL-f5SnriV7TFAyP1qa8I0rL4brD_C5OQgbje"
+ "6kir-h-jjPTbvy-_rv5DJXr-xsiAekSWBW0HNg2Zd404JmDVR_cYvAs4bQnG3Z9SkLRfQI1XmIvwvrVK"
+ "WsL6zOuNoytAHIjl7whgkxjo39pr3IikyYdosPSOQUsb7bH1stUziLZa8FWFKMLI9bUZoMgCXCuWYtCt"
+ "TfkfcEV69h1WTamcqFQhpvffF6NCVKTIQNW4oFTxP4WoUcXXJKthuaHWatH-trlOXaH6_mr6z0jgdJmU"
+ "rKFxGUvkj0WqVEj36XT4Wk4Y-K21t9npea4ttoZ8YsgX32pjc67d25ReR_n7H27Xc6ry8CWn5yjfB-IG"
+ "BMGVdusY5-GrXGQoi5YlPn8BfHmFf4WAvioMyJpI3jg6VRq3w1G5u_zz6y8b4yqloAmopzv8vjBFlJY3"
+ "I8VxiqbichAr8Hls8osNRLsHspyNwR1J_vtOSRxp4PMuY55oBX4yeGIViVncv3Wkqt4m-Ka0";
public static final String DONORS = "6peC02mFU3XMJbc44wzsvvsjcZxOY0eHBCyJYiF08fxk1iGVuDxfSR-H_YAwqhrlcX5jsPhYF6DGBGXw"
+ "F3NN3DlSsmFFQdxwAlbcQdI5gJ0auIuaB6JOJp-fCgG4ptAz-MSKutlkfA5Pjis5a1j8l_2-CpRFJkEB"
+ "LuycQ2FmOs1V_TyrhQoxLrLXI9TLZQbHfoiSmeZ84VuVTPkwHMsSJ6qQFQ1JELTmKvsAj0LlUgALD1Da"
+ "NEiu7ysQLCL4caZnr4OA7ZcPeRqcgy-JAttG-QL-W3QjtJN4SmOKnqhfqVsrqVxp1DklaFYGS8POi5bW"
+ "3fKSrYSeVcswqN6A8A5r5jdOwYktF371u8SM-kOFPNB5UqXabY55n-KA57WynW39dDIk2MU7RWPKrOCj"
+ "-ZK8rULnu-uQX-MfP3OQRW4B5mjg1se8yZ_e4pwjx_p8v5o78fQGfqdSbcr0_LdoFkvDHT_CgqaWV6qV"
+ "cXdYAbEr7jBOyZFMgqQ7t3LarUXVnXg57C6ytysbOFxH0laHwA4-4KdyBFkDXGI4QqlzqBlEJITN5k6K"
+ "3YaLw_HRR7aj-K9NOB5nqQmEbkYxyUjoKoBOGbScbw47MbMvhVE9aj9G_x_8ew7hl-2QAhLxXsWzq-Oy"
+ "-x_hbcQ6uW0Txs8MT2qW44RJgg_OG0I7XIuFkGcG0wXk9hVYPdaHU-G716yk6NI5ZPGEYEUNa9iSGfY6"
+ "BjrSeWAOFQNKHSTjWOSwdO9kHPLyUfcxFgP9oxHjO-O-QOFdxGPZ5CTqGld4_JONk8LXbLeq9qzh7s6M"
+ "u74-JlEg-npCg-Ysj_2UzY4qhsJ0hp1dHAJITELvfdt4tTGHc4LRy58NszrjSF3GNGjEiMW5CzgqGvQ0"
+ "oOLarDAlA3ur6FuEGZPXhqr5li3MS9qQmin8WzTBarjgSaJ7QJhBiR4DmAilNh4hA9mYHDlIajcwbZ0r"
+ "O_KaLCZlb4zWgQmBInisjhiApyGy2l9mtYEhB_LZIN5RGFMnJ92N5a9V8KKHjZV8m5X9ptAROFjJEnRK"
+ "RJrouPX3yMqJRJTkY64AJ4_XVf4W4gCJIOLUOf8eu7j-_4gzQAw3ZU_iQSKuI5f88g2As7Bg1yPAG_L8"
+ "JMEzHlzVQ-rksVdpxtLaarE7t_Cp1T5pK3J-ZHJ0KKuWWwU1hoPVbBoLi98LoY33bMkLdWOI5kp2ErTH"
+ "3vOPrJjHB3Uh5gsYVQYgt-xACN0sDgouoASeLjzYbBMxUb05RT_rncAHW-0_H9L9cLoD9gin4Zg3BCxT"
+ "sFTAnJmtDe45lMCoWRPVVNQQnat6dAz8AWsF0Fb-Zqn9MWyjhAbfNJuHs2ITwtiBsvH8wt_1Y7v1hPFZ"
+ "KJsq3t9texj0mxS-f7P19XWkaayKoBTpJZHmyus2kgWMoiJIZXbsZc25_iP_H1GIZjd61u8iSx6iTaSE"
+ "sKBsyTue-a1HKsWW6ulr-anYePJZWHH9mPhPCfv7sg1jsDSJW5CKpFVtDeHB9ffVa5dxUlP6CfT-xiKP"
+ "H3gSdqrYqvIj3Jcm7scvREkEtFw-I8UT-k_4ZlETZwXR1n740Z7I25wF2UlcncxL5ZuZpwqQ7CTbEWuc" + "FuoJc9O0";
/*
* Special thanks to our sponsors and donors:

View File

@ -163,6 +163,13 @@ public class TextBlockUtils {
return new TextBlockVertical2(b1, b2, horizontalAlignment);
}
public static TextBlock mergeTB(TextBlock b1, UImage image, HorizontalAlignment horizontalAlignment) {
if (b1 == EMPTY_TEXT_BLOCK) {
throw new IllegalArgumentException();
}
return new TextBlockVertical2(b1, image, horizontalAlignment);
}
// public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1,
// TextBlockBackcolored b2,
// HorizontalAlignment horizontalAlignment) {

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.svek.Ports;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.svek.WithPorts;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
@ -60,6 +61,23 @@ public class TextBlockVertical2 extends AbstractTextBlock implements TextBlock,
this.horizontalAlignment = horizontalAlignment;
}
TextBlockVertical2(TextBlock b1, final UImage image, HorizontalAlignment horizontalAlignment) {
this(b1, convertImage(image), horizontalAlignment);
}
static private AbstractTextBlock convertImage(final UImage image) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
ug.draw(image);
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return new Dimension2DDouble(image.getWidth(), image.getHeight());
}
};
}
public TextBlockVertical2(List<TextBlock> all, HorizontalAlignment horizontalAlignment) {
if (all.size() < 2) {
throw new IllegalArgumentException();

View File

@ -163,21 +163,13 @@ public class FingerImpl implements Finger, UDrawable {
}
private HColor getLinkColor() {
if (SkinParam.USE_STYLES()) {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(styleBuilder);
return styleArrow.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
}
return ColorParam.activityBorder.getDefaultValue();
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(styleBuilder);
return styleArrow.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
}
private UStroke getUStroke() {
if (SkinParam.USE_STYLES()) {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(styleBuilder);
return styleArrow.getStroke();
}
return new UStroke();
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(styleBuilder);
return styleArrow.getStroke();
}
private void drawLine(UGraphic ug, Point2D p1, Point2D p2) {
@ -239,22 +231,16 @@ public class FingerImpl implements Finger, UDrawable {
if (drawPhalanx == false) {
return TextBlockUtils.empty(0, 0);
}
final UFont font;
if (SkinParam.USE_STYLES()) {
final Style styleNode = getDefaultStyleDefinitionNode().getMergedStyle(styleBuilder);
font = styleNode.getUFont();
} else {
font = skinParam.getFont(null, false, FontParam.ACTIVITY);
}
if (shape == IdeaShape.BOX) {
// final ISkinParam foo = new
// SkinParamBackcolored(Colors.empty().mute(skinParam), backColor);
final ISkinParam foo = new SkinParamColors(skinParam, Colors.empty().add(ColorType.BACK, backColor));
final FtileBox box = FtileBox.createMindMap(styleBuilder, foo, label, getDefaultStyleDefinitionNode());
return TextBlockUtils.withMargin(box, 0, 0, marginTop, marginBottom);
}
final TextBlock text = label.create(FontConfiguration.blackBlueTrue(font), HorizontalAlignment.LEFT, skinParam);
assert shape == IdeaShape.NONE;
final Style styleNode = getDefaultStyleDefinitionNode().getMergedStyle(styleBuilder);
final TextBlock text = label.create(styleNode.getFontConfiguration(skinParam.getIHtmlColorSet()),
HorizontalAlignment.LEFT, skinParam);
if (direction == Direction.RIGHT) {
return TextBlockUtils.withMargin(text, 3, 0, 1, 1);
}

View File

@ -99,17 +99,11 @@ public class MindMapDiagram extends UmlDiagram {
final int margin1;
final int margin2;
final HColor backgroundColor;
if (SkinParam.USE_STYLES()) {
margin1 = SkinParam.zeroMargin(10);
margin2 = SkinParam.zeroMargin(10);
final Style style = StyleSignature.of(SName.root, SName.document, SName.mindmapDiagram)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
backgroundColor = style.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet());
} else {
margin1 = 10;
margin2 = 10;
backgroundColor = skinParam.getBackgroundColor(false);
}
margin1 = SkinParam.zeroMargin(10);
margin2 = SkinParam.zeroMargin(10);
final Style style = StyleSignature.of(SName.root, SName.document, SName.mindmapDiagram)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
backgroundColor = style.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet());
final ImageBuilder imageBuilder = ImageBuilder.buildBB(skinParam.getColorMapper(), skinParam.handwritten(),
ClockwiseTopRightBottomLeft.margin1margin2(margin1, margin2), null,
fileFormatOption.isWithMetadata() ? getMetadata() : null, "", dpiFactor, backgroundColor);

View File

@ -52,18 +52,20 @@ public class CommandLink extends SingleLineCommand2<NwDiagram> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandLink.class.getName(), RegexLeaf.start(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NAME1", "[\\p{L}0-9_]+"), //
new RegexLeaf("NAME1", "([\\p{L}0-9_]+)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("--"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NAME2", "[\\p{L}0-9_]+"), //
new RegexLeaf("NAME2", "([\\p{L}0-9_]+)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf(";?"), RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) {
return diagram.link();
final String name1 = arg.get("NAME1", 0);
final String name2 = arg.get("NAME2", 0);
return diagram.link(name1, name2);
}
}

View File

@ -52,13 +52,13 @@ public class CommandProperty extends SingleLineCommand2<NwDiagram> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandProperty.class.getName(), RegexLeaf.start(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NAME", "(address|color)"), //
new RegexLeaf("NAME", "(address|color|width)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("="), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("\""), //
new RegexLeaf("VALUE", "(.*)"), //
new RegexLeaf("\""), //
new RegexLeaf("\"?"), //
new RegexLeaf("VALUE", "([^\"]*)"), //
new RegexLeaf("\"?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf(";?"), //
RegexLeaf.end());

View File

@ -60,6 +60,7 @@ public class DiagElement {
private String description;
private final Network mainNetwork;
private final ISkinSimple spriteContainer;
private boolean hasItsOwnColumn = true;
@Override
public String toString() {
@ -126,4 +127,12 @@ public class DiagElement {
}
}
public void doNotHaveItsOwnColumn() {
this.hasItsOwnColumn = false;
}
public final boolean hasItsOwnColumn() {
return hasItsOwnColumn;
}
}

View File

@ -134,7 +134,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
for (int i = 0; i < data.length; i++) {
final Network network = getNetwork(i);
double x = 0;
double xmin = -1;
double xmin = network.isFullWidth() ? 0 : -1;
double xmax = 0;
for (int j = 0; j < data[i].length; j++) {
final boolean hline = isThereALink(j, network);
@ -142,10 +142,11 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
xmin = x;
}
x += colWidth(stringBounder, j);
if (hline) {
if (hline || network.isFullWidth()) {
xmax = x;
}
}
final URectangle rect = new URectangle(xmax - xmin, NETWORK_THIN);
rect.setDeltaShadow(1.0);
UGraphic ug2 = ug.apply(new UTranslate(xmin, y));
@ -155,7 +156,9 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
if (network != null) {
pos.put(network, y);
}
ug2.draw(rect);
if (network.isVisible()) {
ug2.draw(rect);
}
y += lineHeight(stringBounder, i);
}
return pos;

View File

@ -35,6 +35,7 @@
package net.sourceforge.plantuml.nwdiag;
import java.awt.geom.Dimension2D;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeSet;
@ -105,8 +106,15 @@ public class LinkedElement {
final double xMiddle = width / 2;
final TreeSet<Double> skip = new TreeSet<Double>(pos.values());
new VerticalLine(ynet1 + GridTextBlockDecorated.NETWORK_THIN, ynet1 + alpha, skip)
.drawU(ug.apply(UTranslate.dx(xMiddle)));
if (element.hasItsOwnColumn()) {
if (element.getMainNetwork().isVisible()) {
new VerticalLine(ynet1 + GridTextBlockDecorated.NETWORK_THIN, ynet1 + alpha, skip)
.drawU(ug.apply(UTranslate.dx(xMiddle)));
} else {
new VerticalLine(ynet1, ynet1 + alpha, Collections.<Double>emptySet())
.drawU(ug.apply(UTranslate.dx(xMiddle)));
}
}
drawCenter(ug, link1(), xMiddle, ynet1 + alpha / 2);
final double seven = 7.0;
@ -144,13 +152,17 @@ public class LinkedElement {
}
private void drawCenter(UGraphic ug, TextBlock block, double x, double y) {
if (block == null) {
return;
}
final Dimension2D dim = block.calculateDimension(ug.getStringBounder());
block.drawU(ug.apply(new UTranslate(x - dim.getWidth() / 2, y - dim.getHeight() / 2)));
}
public Dimension2D naturalDimension(StringBounder stringBounder) {
final Dimension2D dim1 = link1().calculateDimension(stringBounder);
final Dimension2D dim1 = link1() == null ? new Dimension2DDouble(0, 0)
: link1().calculateDimension(stringBounder);
final Dimension2D dimBox = box.calculateDimension(stringBounder);
final Dimension2D dim2 = link2() == null ? new Dimension2DDouble(0, 0)
: link2().calculateDimension(stringBounder);

View File

@ -44,8 +44,9 @@ public class Network {
private final String name;
private final Map<DiagElement, String> localElements = new LinkedHashMap<DiagElement, String>();
private HColor color;
private boolean visible = true;
private String ownAdress;
private boolean fullWidth;
@Override
public String toString() {
@ -100,4 +101,20 @@ public class Network {
this.color = color;
}
public void goInvisible() {
this.visible = false;
}
public final boolean isVisible() {
return visible;
}
public void setFullWidth(boolean fullWidth) {
this.fullWidth = fullWidth;
}
public final boolean isFullWidth() {
return fullWidth;
}
}

View File

@ -124,6 +124,45 @@ public class NwDiagram extends UmlDiagram {
return CommandExecutionResult.ok();
}
public CommandExecutionResult link(String name1, String name2) {
if (initDone == false) {
return error();
}
if (currentNetwork() == null) {
final Network network1 = new Network(name1);
networks.add(network1);
addElement(null, name2, toSet(null));
return CommandExecutionResult.ok();
} else {
final DiagElement already = elements.get(name1);
final Network network1 = new Network("");
network1.goInvisible();
networks.add(network1);
if (already != null) {
currentNetwork().addElement(already, toSet(null));
}
addElement(null, name2, toSet(null));
return CommandExecutionResult.ok();
}
}
private DiagElement addElement(DiagElement element, String name, Map<String, String> props) {
if (element == null) {
element = new DiagElement(name, currentNetwork(), this.getSkinParam());
elements.put(name, element);
}
currentNetwork().addElement(element, props);
final String description = props.get("description");
if (description != null) {
element.setDescription(description);
}
final String shape = props.get("shape");
if (shape != null) {
element.setShape(shape);
}
return element;
}
public CommandExecutionResult endSomething() {
if (initDone == false) {
return error();
@ -139,22 +178,17 @@ public class NwDiagram extends UmlDiagram {
if (currentGroup != null) {
currentGroup.addElement(name);
}
if (currentNetwork() != null) {
DiagElement element = elements.get(name);
if (element == null) {
element = new DiagElement(name, currentNetwork(), this.getSkinParam());
elements.put(name, element);
if (currentNetwork() == null) {
if (currentGroup == null) {
final Network network1 = new Network("");
network1.goInvisible();
networks.add(network1);
final DiagElement first = addElement(null, name, toSet(definition));
first.doNotHaveItsOwnColumn();
}
final Map<String, String> props = toSet(definition);
final String description = props.get("description");
if (description != null) {
element.setDescription(description);
}
final String shape = props.get("shape");
if (shape != null) {
element.setShape(shape);
}
currentNetwork().addElement(element, props);
} else {
final DiagElement element = elements.get(name);
addElement(element, name, toSet(definition));
}
return CommandExecutionResult.ok();
}
@ -303,7 +337,8 @@ public class NwDiagram extends UmlDiagram {
}
private GridTextBlockDecorated buildGrid() {
final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), elements.size(), groups, networks);
final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), elements.size(), groups,
networks);
for (int i = 0; i < networks.size(); i++) {
final Network current = networks.get(i);
@ -315,7 +350,9 @@ public class NwDiagram extends UmlDiagram {
final Map<Network, String> conns = getLinks(element);
grid.add(i, j, element.asTextBlock(conns, next));
}
j++;
if (element.hasItsOwnColumn()) {
j++;
}
}
}
return grid;
@ -328,6 +365,9 @@ public class NwDiagram extends UmlDiagram {
if ("address".equalsIgnoreCase(property) && currentNetwork() != null) {
currentNetwork().setOwnAdress(value);
}
if ("width".equalsIgnoreCase(property) && currentNetwork() != null) {
currentNetwork().setFullWidth("full".equalsIgnoreCase(value));
}
if ("color".equalsIgnoreCase(property)) {
final HColor color = GridTextBlockDecorated.colors.getColorIfValid(value);
if (currentGroup != null) {
@ -339,11 +379,4 @@ public class NwDiagram extends UmlDiagram {
return CommandExecutionResult.ok();
}
public CommandExecutionResult link() {
if (initDone == false) {
return error();
}
return CommandExecutionResult.ok();
}
}

View File

@ -34,29 +34,31 @@
*/
package net.sourceforge.plantuml.nwdiag;
import java.util.TreeSet;
import java.util.Set;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.color.HColorNone;
public class VerticalLine implements UDrawable {
private final double y1;
private final double y2;
private final TreeSet<Double> skip;
private final Set<Double> skip;
public VerticalLine(double y1, double y2, TreeSet<Double> skip) {
public VerticalLine(double y1, double y2, Set<Double> skip) {
this.y1 = Math.min(y1, y2);
this.y2 = Math.max(y1, y2);
this.skip = skip;
}
public void drawU(UGraphic ug) {
ug = ug.apply(new HColorNone().bg());
boolean drawn = false;
double current = y1;
UPath path = new UPath();
path.moveTo(0, current);
for (Double step : skip) {
if (step < y1) {
continue;
@ -64,33 +66,27 @@ public class VerticalLine implements UDrawable {
assert step >= y1;
drawn = true;
if (step == y2) {
drawVLine(ug, current, y2);
path.lineTo(0, y2);
} else {
drawVLine(ug, current, Math.min(y2, step - 3));
path.lineTo(0, Math.min(y2, step - 3));
if (y2 > step) {
drawArc(ug, step - 3);
path.arcTo(4, 4, 0, 0, 1, 0, step + 9);
continue;
}
}
ug.draw(path);
path = new UPath();
current = step + 9;
path.moveTo(0, current);
if (current >= y2) {
break;
}
}
if (drawn == false) {
drawVLine(ug, y1, y2);
path.lineTo(0, y2);
ug.draw(path);
}
}
private void drawArc(UGraphic ug, double y) {
final UEllipse arc = new UEllipse(11, 11, 90, -180);
ug.apply(new UTranslate(-5, y)).draw(arc);
}
private void drawVLine(UGraphic ug, double start, double end) {
final ULine line = ULine.vline(end - start);
ug.apply(UTranslate.dy(start)).draw(line);
}
}

View File

@ -0,0 +1,97 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
import java.util.Set;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColorNone;
public class VerticalLine2 implements UDrawable {
private final double y1;
private final double y2;
private final Set<Double> skip;
public VerticalLine2(double y1, double y2, Set<Double> skip) {
this.y1 = Math.min(y1, y2);
this.y2 = Math.max(y1, y2);
this.skip = skip;
}
public void drawU(UGraphic ug) {
boolean drawn = false;
double current = y1;
for (Double step : skip) {
if (step < y1) {
continue;
}
assert step >= y1;
drawn = true;
if (step == y2) {
drawVLine(ug, current, y2);
} else {
drawVLine(ug, current, Math.min(y2, step - 3));
if (y2 > step) {
drawArc(ug, step - 3);
}
}
current = step + 9;
if (current >= y2) {
break;
}
}
if (drawn == false) {
drawVLine(ug, y1, y2);
}
}
private void drawArc(UGraphic ug, double y) {
final UEllipse arc = new UEllipse(11, 11, 90, -180);
ug.apply(new HColorNone().bg()).apply(new UTranslate(-5, y)).draw(arc);
}
private void drawVLine(UGraphic ug, double start, double end) {
final ULine line = ULine.vline(end - start);
ug.apply(UTranslate.dy(start)).draw(line);
}
}

View File

@ -98,13 +98,13 @@ public class GanttArrow implements UDrawable {
ug = ug.apply(color.bg()).apply(color).apply(style.getStroke3(new UStroke(1.5)));
double x1 = getX(source.withDelta(0), atStart);
double y1 = getSource().getY(atStart);
double y1 = getSource().getY(atStart).getValue();
final double x2 = getX(dest, atEnd.getInv());
final double y2 = getDestination().getY(atEnd);
final double y2 = getDestination().getY(atEnd).getValue();
if (atStart == Direction.DOWN && y2 < y1) {
y1 = getSource().getY(atStart.getInv());
y1 = getSource().getY(atStart.getInv()).getValue();
}
if (this.atStart == Direction.DOWN && this.atEnd == Direction.RIGHT) {
@ -115,7 +115,7 @@ public class GanttArrow implements UDrawable {
drawLine(ug, x1, y1, x1, y2, x2, y2);
} else {
x1 = getX(source.withDelta(0), Direction.RIGHT);
y1 = getSource().getY(Direction.RIGHT);
y1 = getSource().getY(Direction.RIGHT).getValue();
drawLine(ug, x1, y1, x1 + 6, y1, x1 + 6, y1 + 8, x2 - 8, y1 + 8, x2 - 8, y2, x2, y2);
}
} else if (this.atStart == Direction.RIGHT && this.atEnd == Direction.LEFT) {

View File

@ -74,6 +74,7 @@ import net.sourceforge.plantuml.project.core.TaskCode;
import net.sourceforge.plantuml.project.core.TaskImpl;
import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.core.TaskSeparator;
import net.sourceforge.plantuml.project.draw.FingerPrint;
import net.sourceforge.plantuml.project.draw.ResourceDraw;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
@ -84,6 +85,7 @@ import net.sourceforge.plantuml.project.draw.TimeHeaderDaily;
import net.sourceforge.plantuml.project.draw.TimeHeaderMonthly;
import net.sourceforge.plantuml.project.draw.TimeHeaderSimple;
import net.sourceforge.plantuml.project.draw.TimeHeaderWeekly;
import net.sourceforge.plantuml.project.draw.YMovable;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
@ -183,7 +185,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
final ImageBuilder imageBuilder = ImageBuilder.buildB(new ColorMapperIdentity(), false,
ClockwiseTopRightBottomLeft.margin1margin2(margin1, margin2), null, getMetadata(), "", dpiFactor, null);
TextBlock result = getTextBlock();
TextBlock result = getTextBlock(fileFormatOption.getDefaultStringBounder());
result = new AnnotatedWorker(this, getSkinParam(), fileFormatOption.getDefaultStringBounder()).addAdd(result);
imageBuilder.setUDrawable(result);
@ -207,7 +209,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
return false;
}
private TextBlockBackcolored getTextBlock() {
private TextBlockBackcolored getTextBlock(StringBounder stringBounder) {
if (printStart == null) {
initMinMax();
} else {
@ -226,7 +228,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
timeHeader = new TimeHeaderDaily(calendar, min, max, getDefaultPlan(), colorDays, nameDays, printStart,
printEnd);
}
initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight());
initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight(), stringBounder);
return new TextBlockBackcolored() {
public void drawU(UGraphic ug) {
@ -260,7 +262,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
private void drawTasksRect(UGraphic ug) {
for (Task task : tasks.values()) {
final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY());
final UTranslate move = UTranslate.dy(draw.getY().getValue());
draw.drawU(ug.apply(move));
}
}
@ -280,7 +282,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
continue;
}
final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY());
final UTranslate move = UTranslate.dy(draw.getY().getValue());
draw.drawTitle(ug1.apply(move));
}
}
@ -330,20 +332,8 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
private final Map<Task, TaskDraw> draws = new LinkedHashMap<Task, TaskDraw>();
private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight) {
double y = headerHeight;
// for (Task task : tasks.values()) {
// if (task instanceof TaskImpl) {
// final TaskImpl taskImpl = (TaskImpl) task;
// if (taskImpl.getRow() != null) {
// continue;
// }
// }
// task.setY5757(y);
// y += task.getHeight();
//
// }
// double y2 = headerHeight;
private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight, StringBounder stringBounder) {
YMovable y = new YMovable(headerHeight);
for (Task task : tasks.values()) {
final TaskDraw draw;
if (task instanceof TaskSeparator) {
@ -362,17 +352,60 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw {
draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote());
}
if (task.getRow() == null) {
y += draw.getHeight();
y = y.add(draw.getHeightTask());
}
draws.put(task, draw);
}
magicPush(stringBounder);
y = lastY(stringBounder);
for (Resource res : resources.values()) {
final ResourceDraw draw = new ResourceDraw(this, res, timeScale, y, min, max);
res.setTaskDraw(draw);
y += draw.getHeight();
y = y.add(draw.getHeight());
}
this.totalHeight = y;
this.totalHeight = y.getValue();
}
private YMovable lastY(StringBounder stringBounder) {
TaskDraw last = null;
for (TaskDraw td : draws.values()) {
last = td;
}
return last.getY().add(last.getHeightMax(stringBounder));
}
private boolean magicPush(StringBounder stringBounder) {
final List<FingerPrint> notes = new ArrayList<FingerPrint>();
for (TaskDraw td : draws.values()) {
final FingerPrint taskPrint = td.getFingerPrint();
for (FingerPrint note : notes) {
final double deltaY = note.overlap(taskPrint);
if (deltaY > 0) {
pushIncluding(td, deltaY);
return true;
}
}
final FingerPrint fingerPrintNote = td.getFingerPrintNote(stringBounder);
if (fingerPrintNote != null) {
notes.add(fingerPrintNote);
}
}
return false;
}
private void pushIncluding(TaskDraw first, double deltaY) {
boolean skipping = true;
for (TaskDraw td : draws.values()) {
if (td == first)
skipping = false;
if (skipping)
continue;
td.getY().pushMe(deltaY + 1);
}
}
private Wink getStart(final TaskImpl tmp) {

View File

@ -0,0 +1,63 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
public class Hole implements Comparable<Hole> {
private final long start;
private final long end;
public Hole(long start, long end) {
if (end <= start) {
throw new IllegalArgumentException();
}
this.start = start;
this.end = end;
}
public final long getStart() {
return start;
}
public final long getEnd() {
return end;
}
public int compareTo(Hole other) {
return Long.compare(this.start, other.start);
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,96 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.project.time.DayOfWeek;
public class Slice {
private final long start;
private final long end;
private final int workLoad;
public Slice(long start, long end, int workLoad) {
if (end <= start) {
throw new IllegalArgumentException();
}
this.start = start;
this.end = end;
this.workLoad = workLoad;
}
@Override
public String toString() {
return DayOfWeek.timeToString(start) + " --> " + DayOfWeek.timeToString(end) + " <" + workLoad + ">";
}
public boolean containsTime(long time) {
return time >= start && time <= end;
}
public final long getStart() {
return start;
}
public final long getEnd() {
return end;
}
public final int getWorkLoad() {
return workLoad;
}
public List<Slice> intersectWith(HolesList holes) {
final List<Slice> result = new ArrayList<Slice>();
for (Hole hole : holes) {
final Slice inter = intersectWith(hole);
}
return Collections.unmodifiableList(result);
}
private Slice intersectWith(Hole hole) {
if (hole.getEnd() <= start || hole.getStart() <= end) {
return null;
}
return new Slice(Math.max(start, hole.getStart()), Math.min(end, hole.getEnd()), workLoad);
}
}

View File

@ -0,0 +1,69 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
public class Solver1 {
private final WorkLoad workLoad;
public Solver1(WorkLoad workLoad) {
this.workLoad = workLoad;
}
public TeethRange solveEnd(long start, long fullLoad) {
final IteratorSlice slices = workLoad.slices(start);
final TeethRange result = new TeethRange();
while (true) {
final Slice current = slices.next();
assert current.getEnd() >= start;
start = Math.max(start, current.getStart());
final long sliceLoad = 1L * (current.getEnd() - start) * current.getWorkLoad();
if (sliceLoad >= fullLoad) {
final long theoricalEnd = start + fullLoad / current.getWorkLoad();
result.add(new Tooth(start, theoricalEnd, fullLoad));
return result;
}
assert sliceLoad < fullLoad;
result.add(new Tooth(start, current.getEnd(), sliceLoad));
fullLoad -= sliceLoad;
}
}
}

View File

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

View File

@ -0,0 +1,72 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import net.sourceforge.plantuml.project.time.DayOfWeek;
public class Tooth {
private final long start;
private final long end;
private final long volume;
public Tooth(long start, long end, long volume) {
if (end <= start) {
throw new IllegalArgumentException();
}
this.start = start;
this.end = end;
this.volume = volume;
}
@Override
public String toString() {
return DayOfWeek.timeToString(start) + " --> " + DayOfWeek.timeToString(end) + " {" + volume + "}";
}
public final long getStart() {
return start;
}
public final long getEnd() {
return end;
}
public final long getVolume() {
return volume;
}
}

View File

@ -0,0 +1,42 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
public interface WorkLoad {
public IteratorSlice slices(long timeBiggerThan);
}

View File

@ -0,0 +1,53 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import java.util.Collections;
public class WorkLoadConstant implements WorkLoad {
private final int value;
public WorkLoadConstant(int value) {
this.value = value;
}
public IteratorSlice slices(long timeBiggerThan) {
return new ListIteratorSlice(
Collections.singletonList(new Slice(timeBiggerThan, 1000L * Integer.MAX_VALUE, value)));
}
}

View File

@ -0,0 +1,103 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Set;
import net.sourceforge.plantuml.project.time.DayOfWeek;
public class WorkLoadConstantButWeekDay implements WorkLoad {
private final int value;
private final Set<DayOfWeek> excepts = EnumSet.noneOf(DayOfWeek.class);
public WorkLoadConstantButWeekDay(int value, DayOfWeek... butThisDays) {
this.value = value;
this.excepts.addAll(Arrays.asList(butThisDays));
}
private static final long dayDuration = 1000L * 24 * 3600;
public IteratorSlice slices(final long timeBiggerThan) {
final Slice first = getNext(timeBiggerThan);
return new MyIterator(first);
}
class MyIterator implements IteratorSlice {
private Slice current;
public MyIterator(Slice first) {
this.current = first;
}
public Slice next() {
final Slice result = current;
current = getNext(current.getEnd());
return result;
}
}
private Slice getNext(final long limit) {
long start = limit;
long end;
if (isClose(start)) {
start = round(start);
while (isClose(start))
start += dayDuration;
end = start + dayDuration;
} else {
end = round(start) + dayDuration;
}
assert !isClose(start);
while (isClose(end) == false)
end += dayDuration;
assert isClose(end);
return new Slice(start, end, value);
}
private boolean isClose(long start) {
return excepts.contains(DayOfWeek.fromTime(start));
}
private long round(long start) {
return dayDuration * (start / dayDuration);
}
}

View File

@ -0,0 +1,70 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import java.util.ArrayList;
import java.util.List;
public class WorkLoadVariable implements WorkLoad {
private final List<Slice> slices = new ArrayList<Slice>();
public void add(Slice slice) {
if (slices.size() > 0) {
final Slice last = slices.get(slices.size() - 1);
if (slice.getStart() <= last.getEnd()) {
throw new IllegalArgumentException();
}
}
slices.add(slice);
}
public IteratorSlice slices(long timeBiggerThan) {
for (int i = 0; i < slices.size(); i++) {
final Slice current = slices.get(i);
if (current.getEnd() <= timeBiggerThan) {
continue;
}
assert current.getEnd() > timeBiggerThan;
assert current.getStart() >= timeBiggerThan;
final List<Slice> tmp = slices.subList(i, slices.size());
assert tmp.get(0).getStart() >= timeBiggerThan;
return new ListIteratorSlice(tmp);
}
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,72 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.core2;
import java.util.ArrayList;
import java.util.List;
public class WorkLoadWithHoles implements WorkLoad {
private final WorkLoad source;
private final HolesList holes = new HolesList();
public void addHole(long start, long end) {
this.holes.add(new Hole(start, end));
}
public WorkLoadWithHoles(WorkLoad source) {
this.source = source;
}
class MyIterator implements IteratorSlice {
private final IteratorSlice slices;
public MyIterator(IteratorSlice slices) {
this.slices = slices;
}
public Slice next() {
final Slice candidat = slices.next();
throw new UnsupportedOperationException();
}
}
public IteratorSlice slices(long timeBiggerThan) {
return new MyIterator(source.slices(timeBiggerThan));
}
}

View File

@ -56,7 +56,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
protected Url url;
protected Display note;
protected final TimeScale timeScale;
protected final double y;
protected final YMovable y;
protected final String prettyDisplay;
protected final Wink start;
protected final ISkinParam skinParam;
@ -72,7 +72,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
this.note = note;
}
public AbstractTaskDraw(TimeScale timeScale, double y, String prettyDisplay, Wink start, ISkinParam skinParam,
public AbstractTaskDraw(TimeScale timeScale, YMovable y, String prettyDisplay, Wink start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw) {
this.y = y;
this.toTaskDraw = toTaskDraw;
@ -98,14 +98,14 @@ public abstract class AbstractTaskDraw implements TaskDraw {
abstract protected Style getStyle();
final protected double getShapeHeight() {
return getHeight() - 2 * margin;
return getHeightTask() - 2 * margin;
}
final public double getHeight() {
final public double getHeightTask() {
return getFontConfiguration().getFont().getSize2D() + 5;
}
final public double getY() {
final public YMovable getY() {
if (task.getRow() == null) {
return y;
}
@ -116,14 +116,14 @@ public abstract class AbstractTaskDraw implements TaskDraw {
return task;
}
public final double getY(Direction direction) {
public final YMovable getY(Direction direction) {
if (direction == Direction.UP) {
return getY();
}
if (direction == Direction.DOWN) {
return getY() + getHeight();
return getY().add(getHeightTask());
}
return getY() + getHeight() / 2;
return getY().add(getHeightTask() / 2);
}
}

View File

@ -0,0 +1,69 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.draw;
public class FingerPrint {
private final double x;
private final double y;
private final double width;
private final double height;
public FingerPrint(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public String toString() {
return "X=(" + x + "->" + (x + width) + ") Y=(" + y + " ->" + (y + height) + ")";
}
public double overlap(FingerPrint other) {
if (x >= other.x + other.width || other.x >= x + width) {
return 0;
}
if (y >= other.y + other.height || other.y >= y + height) {
return 0;
}
return y + height - other.y;
}
}

View File

@ -42,7 +42,6 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.core.Resource;
import net.sourceforge.plantuml.project.time.Wink;
import net.sourceforge.plantuml.project.timescale.TimeScale;
@ -57,12 +56,12 @@ public class ResourceDraw implements UDrawable {
private final Resource res;
private final TimeScale timeScale;
private final double y;
private final YMovable y;
private final Wink min;
private final Wink max;
private final GanttDiagram gantt;
public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Wink min, Wink max) {
public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, YMovable y, Wink min, Wink max) {
this.res = res;
this.timeScale = timeScale;
this.y = y;
@ -125,7 +124,7 @@ public class ResourceDraw implements UDrawable {
}
public double getY() {
return y;
return y.getValue();
}
}

View File

@ -38,6 +38,7 @@ package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
@ -47,14 +48,20 @@ public interface TaskDraw extends UDrawable {
public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note);
public double getY();
public YMovable getY();
public double getY(Direction direction);
public YMovable getY(Direction direction);
public void drawTitle(UGraphic ug);
public double getHeight();
public double getHeightTask();
public double getHeightMax(StringBounder stringBounder);
public Task getTask();
public FingerPrint getFingerPrint();
public FingerPrint getFingerPrintNote(StringBounder stringBounder);
}

View File

@ -39,6 +39,7 @@ import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.ToTaskDraw;
import net.sourceforge.plantuml.project.core.Task;
@ -54,7 +55,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate;
public class TaskDrawDiamond extends AbstractTaskDraw {
public TaskDrawDiamond(TimeScale timeScale, double y, String prettyDisplay, Wink start, ISkinParam skinParam,
public TaskDrawDiamond(TimeScale timeScale, YMovable y, String prettyDisplay, Wink start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw);
}
@ -66,6 +67,10 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
return style;
}
public double getHeightMax(StringBounder stringBounder) {
return getHeightTask();
}
// final UFont font = UFont.serif(11);
// return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
@ -74,7 +79,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final double titleHeight = title.calculateDimension(ug.getStringBounder()).getHeight();
final double h = (margin + getShapeHeight() - titleHeight) / 2;
final double endingPosition = timeScale.getStartingPosition(start) + getHeight();
final double endingPosition = timeScale.getStartingPosition(start) + getHeightTask();
title.drawU(ug.apply(new UTranslate(endingPosition, h)));
}
@ -96,8 +101,18 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
ug.draw(getDiamond());
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
public FingerPrint getFingerPrint() {
final double h = getHeightTask();
final double startPos = timeScale.getStartingPosition(start);
return new FingerPrint(startPos, y.getValue(), startPos + h, y.getValue() + h);
}
private UShape getDiamond() {
final double h = getHeight() - 2 * margin;
final double h = getHeightTask() - 2 * margin;
final UPolygon result = new UPolygon();
result.addPoint(h / 2, 0);
result.addPoint(h, h / 2);

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.awt.geom.Dimension2D;
import java.util.Collection;
import net.sourceforge.plantuml.FontParam;
@ -48,6 +49,7 @@ import net.sourceforge.plantuml.creole.SheetBlock1;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.ToTaskDraw;
import net.sourceforge.plantuml.project.core.Task;
@ -77,8 +79,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
private final double margin = 2;
public TaskDrawRegular(TimeScale timeScale, double y, String prettyDisplay, Wink start, Wink end, boolean oddStart,
boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw) {
public TaskDrawRegular(TimeScale timeScale, YMovable y, String prettyDisplay, Wink start, Wink end,
boolean oddStart, boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw);
this.end = end;
this.oddStart = oddStart;
@ -106,19 +108,33 @@ public class TaskDrawRegular extends AbstractTaskDraw {
}
public void drawU(UGraphic ug) {
drawNote(ug.apply(UTranslate.dy(getShapeHeight() + margin * 3)));
final double startPos = timeScale.getStartingPosition(start);
ug = applyColors(ug);
ug = ug.apply(new UTranslate(startPos + margin, margin));
drawNote(ug.apply((new UTranslate(startPos + margin, getYNotePosition()))));
ug = applyColors(ug).apply(new UTranslate(margin, margin));
drawShape(ug);
}
private double getYNotePosition() {
return getShapeHeight() + margin * 3;
}
private void drawNote(UGraphic ug) {
if (note == null) {
return;
}
getOpaleNote().drawU(ug);
}
public double getHeightMax(StringBounder stringBounder) {
if (note == null) {
return getHeightTask();
}
return getYNotePosition() + getOpaleNote().calculateDimension(stringBounder).getHeight();
}
private Opale getOpaleNote() {
final Style style = StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.note)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
FontConfiguration fc = new FontConfiguration(style, skinParam, null, FontParam.NOTE);
@ -133,8 +149,24 @@ public class TaskDrawRegular extends AbstractTaskDraw {
final double shadowing = style.value(PName.Shadowing).asDouble();
Opale opale = new Opale(shadowing, borderColor, noteBackgroundColor, sheet1, false);
opale.drawU(ug);
return opale;
}
public FingerPrint getFingerPrint() {
final double h = getHeightTask();
final double startPos = timeScale.getStartingPosition(start);
final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, y.getValue(), endPos - startPos, h);
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
if (note == null) {
return null;
}
final Dimension2D dim = getOpaleNote().calculateDimension(stringBounder);
final double startPos = timeScale.getStartingPosition(start);
// final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, y.getValue() + getYNotePosition(), dim.getWidth(), dim.getHeight());
}
private UGraphic applyColors(UGraphic ug) {
@ -156,27 +188,31 @@ public class TaskDrawRegular extends AbstractTaskDraw {
ug.startUrl(url);
}
if (oddStart && !oddEnd) {
ug.draw(PathUtils.UtoRight(fullLength, getShapeHeight()));
ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoRight(fullLength, getShapeHeight()));
} else if (!oddStart && oddEnd) {
ug.draw(PathUtils.UtoLeft(fullLength, getShapeHeight()));
ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoLeft(fullLength, getShapeHeight()));
} else {
final URectangle full = new URectangle(fullLength, getShapeHeight()).rounded(8);
if (completion == 100) {
ug.draw(full);
ug.apply(UTranslate.dx(startPos)).draw(full);
} else {
final double partialLength = fullLength * completion / 100.;
ug.apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(full);
ug.apply(UTranslate.dx(startPos)).apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(full);
if (partialLength > 2) {
final URectangle partial = new URectangle(partialLength, getShapeHeight()).rounded(8);
ug.apply(new HColorNone()).draw(partial);
ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).draw(partial);
}
if (partialLength > 10 && partialLength < fullLength - 10) {
final URectangle patch = new URectangle(8, getShapeHeight());
ug.apply(new HColorNone()).apply(UTranslate.dx(partialLength - 8)).draw(patch);
ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).apply(UTranslate.dx(partialLength - 8))
.draw(patch);
}
ug.apply(new HColorNone().bg()).draw(full);
ug.apply(UTranslate.dx(startPos)).apply(new HColorNone().bg()).draw(full);
}
}
if (url != null) {
ug.closeUrl();
}
Wink begin = null;
for (Wink pause : paused) {
if (paused.contains(pause.increment())) {
@ -190,9 +226,6 @@ public class TaskDrawRegular extends AbstractTaskDraw {
begin = null;
}
}
if (url != null) {
ug.closeUrl();
}
}
private void drawPause(UGraphic ug, Wink start1, Wink end) {

View File

@ -41,9 +41,9 @@ import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.project.core.AbstractTask;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Wink;
@ -57,12 +57,12 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TaskDrawSeparator implements TaskDraw {
private final TimeScale timeScale;
private final double y;
private final YMovable y;
private final Wink min;
private final Wink max;
private final String name;
public TaskDrawSeparator(String name, TimeScale timeScale, double y, Wink min, Wink max) {
public TaskDrawSeparator(String name, TimeScale timeScale, YMovable y, Wink min, Wink max) {
this.name = name;
this.y = y;
this.timeScale = timeScale;
@ -96,7 +96,7 @@ public class TaskDrawSeparator implements TaskDraw {
final double end = timeScale.getEndingPosition(max);
ug = ug.apply(HColorUtils.BLACK);
ug = ug.apply(UTranslate.dy(getHeight() / 2));
ug = ug.apply(UTranslate.dy(getHeightTask() / 2));
if (widthTitle == 0) {
final ULine line = ULine.hline(end - start);
@ -109,11 +109,17 @@ public class TaskDrawSeparator implements TaskDraw {
}
}
public double getHeight() {
public FingerPrint getFingerPrint() {
final double h = getHeightTask();
final double end = timeScale.getEndingPosition(max);
return new FingerPrint(0, y.getValue(), end, y.getValue() + h);
}
public double getHeightTask() {
return 16;
}
public double getY() {
public YMovable getY() {
return y;
}
@ -124,8 +130,16 @@ public class TaskDrawSeparator implements TaskDraw {
throw new UnsupportedOperationException();
}
public double getY(Direction direction) {
public YMovable getY(Direction direction) {
throw new UnsupportedOperationException();
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
public double getHeightMax(StringBounder stringBounder) {
return getHeightTask();
}
}

View File

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

View File

@ -35,12 +35,37 @@
*/
package net.sourceforge.plantuml.project.time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import net.sourceforge.plantuml.StringUtils;
public enum DayOfWeek {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
static final private Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
static final private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS", Locale.US);
static {
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
}
public static synchronized DayOfWeek fromTime(long time) {
gmt.setTimeInMillis(time);
final int result = gmt.get(Calendar.DAY_OF_WEEK);
if (result == Calendar.SUNDAY) {
return SUNDAY;
}
return DayOfWeek.values()[result - 2];
}
public static synchronized String timeToString(long value) {
gmt.setTimeInMillis(value);
return fromTime(value).shortName() + " " + dateFormatGmt.format(gmt.getTime());
}
static public String getRegexString() {
final StringBuilder sb = new StringBuilder();
for (DayOfWeek day : DayOfWeek.values()) {

View File

@ -62,6 +62,36 @@ public class SequenceDiagramArea {
private double footerHeight;
private double footerMargin;
private double legendWidth;
private double legendHeight;
private boolean isLegendTop;
private HorizontalAlignment legendHorizontalAlignment;
public void setLegend(Dimension2D dimLegend, boolean isLegendTop, HorizontalAlignment horizontalAlignment) {
this.legendHorizontalAlignment = horizontalAlignment;
this.legendWidth = dimLegend.getWidth();
this.legendHeight = dimLegend.getHeight();
this.isLegendTop = isLegendTop;
}
public double getLegendWidth() {
return legendWidth;
}
public boolean hasLegend() {
return legendHeight > 0 && legendWidth > 0;
}
public double getLegendX() {
if (legendHorizontalAlignment == HorizontalAlignment.LEFT) {
return 0;
} else if (legendHorizontalAlignment == HorizontalAlignment.RIGHT) {
return Math.max(0, getWidth() - legendWidth);
} else {
return Math.max(0, getWidth() - legendWidth) / 2;
}
}
public SequenceDiagramArea(double width, double height) {
this.sequenceWidth = width;
this.sequenceHeight = height;
@ -98,7 +128,24 @@ public class SequenceDiagramArea {
}
public double getHeight() {
return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin + footerHeight + captionHeight;
return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin + footerHeight + captionHeight
+ legendHeight;
}
public double getFooterY() {
return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin + captionHeight + legendHeight;
}
public double getCaptionY() {
return sequenceHeight + headerHeight + headerMargin + titleHeight + legendHeight;
}
public double getLegendY() {
if (isLegendTop) {
return titleHeight + headerHeight + headerMargin;
}
return sequenceHeight + headerHeight + headerMargin + titleHeight;
}
public double getTitleX() {
@ -117,15 +164,14 @@ public class SequenceDiagramArea {
return (getWidth() - captionWidth) / 2;
}
public double getCaptionY() {
return sequenceHeight + headerHeight + headerMargin + titleHeight;
}
public double getSequenceAreaX() {
return (getWidth() - sequenceWidth) / 2;
}
public double getSequenceAreaY() {
if (isLegendTop) {
return getTitleY() + titleHeight + legendHeight;
}
return getTitleY() + titleHeight;
}
@ -133,10 +179,6 @@ public class SequenceDiagramArea {
return 0;
}
public double getFooterY() {
return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin + captionHeight;
}
public double getFooterX(HorizontalAlignment align) {
if (align == HorizontalAlignment.LEFT) {
return 0;

View File

@ -176,21 +176,21 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
area.initFooter(getPngTitler(FontParam.FOOTER, index), stringBounder);
area.initHeader(getPngTitler(FontParam.HEADER, index), stringBounder);
final DisplayPositionned legend = diagram.getLegend();
final TextBlock legendBlock;
if (legend.isNull()) {
if (diagram.getLegend().isNull()) {
legendBlock = TextBlockUtils.empty(0, 0);
} else {
if (SkinParam.USE_STYLES()) {
final Style style = StyleSignature.of(SName.root, SName.legend)
.getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder());
legendBlock = style.createTextBlockBordered(legend.getDisplay(),
legendBlock = style.createTextBlockBordered(diagram.getLegend().getDisplay(),
diagram.getSkinParam().getIHtmlColorSet(), diagram.getSkinParam());
} else {
legendBlock = EntityImageLegend.create(legend.getDisplay(), diagram.getSkinParam());
legendBlock = EntityImageLegend.create(diagram.getLegend().getDisplay(), diagram.getSkinParam());
}
}
final Dimension2D dimLegend = legendBlock.calculateDimension(stringBounder);
area.setLegend(dimLegend, isLegendTop(), diagram.getLegend().getHorizontalAlignment());
scale = getScale(area.getWidth(), area.getHeight());
@ -224,61 +224,40 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
delta = 0;
}
double legendYdelta = 0;
if (compTitle != null) {
final StringBounder stringBounder = ug.getStringBounder();
final double h = compTitle.calculateDimension(stringBounder).getHeight();
legendYdelta += h;
compTitle.drawU(ug.apply(new UTranslate(area.getTitleX(), area.getTitleY())));
}
legendYdelta += area.getHeaderHeightMargin();
caption.drawU(ug.apply(new UTranslate(area.getCaptionX(), area.getCaptionY())));
final double delta1 = Math.max(0, dimLegend.getWidth() - area.getWidth());
final double delta1 = Math.max(0, area.getLegendWidth() - area.getWidth());
final boolean legendTop = legend.isNull() == false
&& legend.getVerticalAlignment() == VerticalAlignment.TOP;
double sequenceAreaY = area.getSequenceAreaY();
if (legendTop) {
sequenceAreaY += legendBlock.calculateDimension(ug.getStringBounder()).getHeight();
}
final UTranslate forCore = new UTranslate(area.getSequenceAreaX() + delta1 / 2, sequenceAreaY);
final UTranslate forCore = new UTranslate(area.getSequenceAreaX() + delta1 / 2,
area.getSequenceAreaY());
TextBlock core = drawableSet.asTextBlock(delta, fullDimension.getWidth(), page,
diagram.isShowFootbox());
core = annotatedWorker.addFrame(core);
core.drawU(ug.apply(forCore));
// drawableSet.drawU22(ug.apply(forCore), delta, fullDimension.getWidth(), page,
// diagram.isShowFootbox());
drawHeader(area, ug, index);
drawFooter(area, ug, index, dimLegend.getHeight());
drawFooter(area, ug, index);
if (legend.isNull() == false) {
final double delta2;
if (legend.getHorizontalAlignment() == HorizontalAlignment.LEFT) {
delta2 = 0;
} else if (legend.getHorizontalAlignment() == HorizontalAlignment.RIGHT) {
delta2 = Math.max(0, area.getWidth() - dimLegend.getWidth());
} else {
delta2 = Math.max(0, area.getWidth() - dimLegend.getWidth()) / 2;
}
legendBlock.drawU(ug.apply(new UTranslate(delta2, legendTop ? legendYdelta : area.getHeight())));
if (area.hasLegend()) {
legendBlock.drawU(ug.apply(new UTranslate(area.getLegendX(), area.getLegendY())));
}
}
});
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os);
}
private void drawFooter(SequenceDiagramArea area, UGraphic ug, int page, double legendHeight) {
private void drawFooter(SequenceDiagramArea area, UGraphic ug, int page) {
final PngTitler pngTitler = getPngTitler(FontParam.FOOTER, page);
final TextBlock text = pngTitler.getRibbonBlock();
if (text == null) {
return;
}
text.drawU(ug.apply(new UTranslate(area.getFooterX(diagram.getFooter().getHorizontalAlignment()),
area.getFooterY() + legendHeight)));
text.drawU(ug.apply(
new UTranslate(area.getFooterX(diagram.getFooter().getHorizontalAlignment()), area.getFooterY())));
}
private void drawHeader(SequenceDiagramArea area, UGraphic ug, int page) {
@ -334,4 +313,9 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
skinParam.useUnderlineForHyperlink(), style, skinParam.getIHtmlColorSet(), skinParam);
}
private boolean isLegendTop() {
return diagram.getLegend().isNull() == false
&& diagram.getLegend().getVerticalAlignment() == VerticalAlignment.TOP;
}
}

View File

@ -112,6 +112,7 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
+ heightEnglober2 + title.calculateDimension(stringBounder).getHeight()
+ header.calculateDimension(stringBounder).getHeight()
+ legend.calculateDimension(stringBounder).getHeight()
+ caption.calculateDimension(stringBounder).getHeight()
+ footer.calculateDimension(stringBounder).getHeight() + (annotatedWorker.hasMainFrame() ? 10 : 0);
this.dimTotal = new Dimension2DDouble(totalWidth, totalHeight);
}
@ -159,8 +160,9 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
margin1 = 3;
margin2 = 10;
}
final ImageBuilder imageBuilder = ImageBuilder.buildD(diagram.getSkinParam(), ClockwiseTopRightBottomLeft.margin1margin2((double) margin1, (double) margin2), diagram.getAnimation(), metadata,
null, oneOf(scale, dpiFactor));
final ImageBuilder imageBuilder = ImageBuilder.buildD(diagram.getSkinParam(),
ClockwiseTopRightBottomLeft.margin1margin2((double) margin1, (double) margin2), diagram.getAnimation(),
metadata, null, oneOf(scale, dpiFactor));
imageBuilder.setUDrawable(new Foo(index));
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os);
@ -315,12 +317,12 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
ug = goDown(ug, bodyFramed);
ug = ug.apply(UTranslate.dy(heightEnglober2));
printAligned(ug, HorizontalAlignment.CENTER, caption);
if (diagram.getLegend().getVerticalAlignment() == VerticalAlignment.BOTTOM) {
printAligned(ug, diagram.getLegend().getHorizontalAlignment(), legend);
ug = goDown(ug, legend);
}
printAligned(ug, HorizontalAlignment.CENTER, caption);
ug = goDown(ug, caption);
printAligned(ug, diagram.getFooterOrHeaderTeoz(FontParam.FOOTER).getHorizontalAlignment(), footer);
}

View File

@ -92,7 +92,7 @@ public class CommandLinkState extends SingleLineCommand2<StateDiagram> {
private static RegexLeaf getStatePattern(String name) {
return new RegexLeaf(name,
"([\\p{L}0-9_.]+|[\\p{L}0-9_.]+\\[H\\*?\\]|\\[\\*\\]|\\[H\\*?\\]|(?:==+)(?:[\\p{L}0-9_.]+)(?:==+))[%s]*(\\<\\<.*\\>\\>)?[%s]*(#\\w+)?");
"([\\p{L}0-9_.:]+|[\\p{L}0-9_.:]+\\[H\\*?\\]|\\[\\*\\]|\\[H\\*?\\]|(?:==+)(?:[\\p{L}0-9_.:]+)(?:==+))[%s]*(\\<\\<.*\\>\\>)?[%s]*(#\\w+)?");
}
@Override

View File

@ -84,6 +84,7 @@ import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.cucadiagram.UnparsableGraphvizException;
import net.sourceforge.plantuml.cucadiagram.dot.DotData;
import net.sourceforge.plantuml.cucadiagram.dot.ExeState;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion;
import net.sourceforge.plantuml.cucadiagram.dot.Neighborhood;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
@ -459,10 +460,10 @@ public final class GeneralImageBuilder {
try {
svg = dotStringFactory.getSvg(basefile, dotStrings);
} catch (IOException e) {
return new GraphvizCrash(source.getPlainString());
return new GraphvizCrash(source.getPlainString(), GraphvizUtils.graphviz244onWindows());
}
if (svg.length() == 0) {
return new GraphvizCrash(source.getPlainString());
return new GraphvizCrash(source.getPlainString(), GraphvizUtils.graphviz244onWindows());
}
final String graphvizVersion = extractGraphvizVersion(svg);
try {

View File

@ -42,7 +42,6 @@ import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.BackSlash;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.OptionPrint;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
@ -52,28 +51,33 @@ import net.sourceforge.plantuml.fun.IconLoader;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.GraphicPosition;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.QuoteUtils;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.ugraphic.AffineTransformType;
import net.sourceforge.plantuml.ugraphic.PixelImage;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
import net.sourceforge.plantuml.version.PSystemVersion;
import net.sourceforge.plantuml.version.Version;
public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
private final TextBlockBackcolored graphicStrings;
private final TextBlock text1;
private final BufferedImage flashCode;
private final String text;
private final boolean graphviz244onWindows;
public GraphvizCrash(String text) {
public GraphvizCrash(String text, boolean graphviz244onWindows) {
this.text = text;
this.graphviz244onWindows = graphviz244onWindows;
final FlashCodeUtils utils = FlashCodeFactory.getFlashCodeUtils();
this.flashCode = utils.exportFlashcode(text, Color.BLACK, Color.WHITE);
this.graphicStrings = GraphicStrings.createBlackOnWhite(init(), IconLoader.getRandom(),
this.text1 = GraphicStrings.createBlackOnWhite(init(), IconLoader.getRandom(),
GraphicPosition.BACKGROUND_CORNER_TOP_RIGHT);
}
@ -102,7 +106,7 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
return result;
}
public static void checkOldVersionWarning(final List<String> strings) {
public static void checkOldVersionWarning(List<String> strings) {
final long days = (System.currentTimeMillis() - Version.compileTime()) / 1000L / 3600 / 24;
if (days >= 90) {
strings.add("This version of PlantUML is " + days + " days old, so you should");
@ -110,13 +114,13 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
}
}
public static void pleaseGoTo(final List<String> strings) {
public static void pleaseGoTo(List<String> strings) {
strings.add(" ");
strings.add("Please go to https://plantuml.com/graphviz-dot to check your GraphViz version.");
strings.add(" ");
}
public static void youShouldSendThisDiagram(final List<String> strings) {
public static void youShouldSendThisDiagram(List<String> strings) {
strings.add("You should send this diagram and this image to <b>plantuml@gmail.com</b> or");
strings.add("post to <b>https://plantuml.com/qa</b> to solve this issue.");
strings.add("You can try to turn arround this issue by simplifing your diagram.");
@ -151,6 +155,14 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
return strings;
}
private List<String> getText2() {
final List<String> strings = new ArrayList<String>();
strings.add("<b>It looks like you are running GraphViz 2.44 under Windows.");
strings.add("If you have just installed GraphViz, you <i>may</i> have to execute");
strings.add("the post-install command <b>dot -c</b> like in the following example:");
return strings;
}
public static void addDecodeHint(final List<String> strings) {
strings.add(" ");
strings.add(" Diagram source: (Use http://zxing.org/w/decode.jspx to decode the qrcode)");
@ -161,11 +173,6 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
strings.addAll(OptionPrint.interestingValues());
}
// private static void addTextProperty(final List<String> strings, String prop)
// {
// strings.add(prop + ": " + System.getProperty(prop));
// }
public boolean isHidden() {
return false;
}
@ -175,22 +182,30 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
Dimension2D result = graphicStrings.calculateDimension(stringBounder);
if (flashCode != null) {
result = Dimension2DDouble.mergeTB(result,
new Dimension2DDouble(flashCode.getWidth(), flashCode.getHeight()));
}
return result;
return getMain().calculateDimension(stringBounder);
}
public void drawU(UGraphic ug) {
graphicStrings.drawU(ug);
getMain().drawU(ug);
}
private TextBlock getMain() {
TextBlock result = text1;
if (flashCode != null) {
final double h = graphicStrings.calculateDimension(ug.getStringBounder()).getHeight();
ug = ug.apply(UTranslate.dy(h));
ug.draw(new UImage(new PixelImage(flashCode, AffineTransformType.TYPE_NEAREST_NEIGHBOR))
.scale(3));
final UImage flash = new UImage(new PixelImage(flashCode, AffineTransformType.TYPE_NEAREST_NEIGHBOR))
.scale(3);
result = TextBlockUtils.mergeTB(result, flash, HorizontalAlignment.LEFT);
}
if (graphviz244onWindows) {
final TextBlock text2 = GraphicStrings.createBlackOnWhite(getText2());
result = TextBlockUtils.mergeTB(result, text2, HorizontalAlignment.LEFT);
final UImage dotc = new UImage(new PixelImage(PSystemVersion.getDotc(), AffineTransformType.TYPE_BILINEAR));
result = TextBlockUtils.mergeTB(result, dotc, HorizontalAlignment.LEFT);
}
return result;
}
public ShapeType getShapeType() {

View File

@ -45,11 +45,14 @@ import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.activitydiagram3.ftile.EntityImageLegend;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
import net.sourceforge.plantuml.cucadiagram.EntityPortion;
import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.PortionShower;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
@ -87,13 +90,20 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
HorizontalAlignment.CENTER, skinParam);
this.url = entity.getUrl99();
if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null
|| portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) {
stereoBlock = TextBlockUtils.empty(0, 0);
final DisplayPositionned legend = ((EntityImpl) entity).getLegend();
if (legend != null) {
final TextBlock legendBlock = EntityImageLegend.create(legend.getDisplay(), skinParam);
stereoBlock = legendBlock;
} else {
stereoBlock = TextBlockUtils.withMargin(Display.create(stereotype.getLabels(skinParam.guillemet())).create(
new FontConfiguration(getSkinParam(), FontParam.PACKAGE_STEREOTYPE, stereotype),
HorizontalAlignment.CENTER, skinParam), 1, 0);
if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null
|| portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) {
stereoBlock = TextBlockUtils.empty(0, 0);
} else {
stereoBlock = TextBlockUtils.withMargin(Display.create(stereotype.getLabels(skinParam.guillemet()))
.create(new FontConfiguration(getSkinParam(), FontParam.PACKAGE_STEREOTYPE, stereotype),
HorizontalAlignment.CENTER, skinParam),
1, 0);
}
}
}

View File

@ -42,6 +42,7 @@ import java.util.List;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.ugraphic.UBackground;
import net.sourceforge.plantuml.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicNo;
@ -51,6 +52,7 @@ import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UParam;
import net.sourceforge.plantuml.ugraphic.UParamNull;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UText;
@ -93,7 +95,7 @@ public class Footprint {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
return new MyUGraphic(all, translate.compose((UTranslate) change));
} else if (change instanceof UStroke || change instanceof HColor) {
} else if (change instanceof UStroke || change instanceof HColor || change instanceof UBackground) {
return new MyUGraphic(all, translate);
}
throw new UnsupportedOperationException();
@ -121,6 +123,8 @@ public class Footprint {
drawImage(x, y, (UImage) shape);
} else if (shape instanceof UPath) {
drawPath(x, y, (UPath) shape);
} else if (shape instanceof URectangle) {
drawRectangle(x, y, (URectangle) shape);
} else {
throw new UnsupportedOperationException(shape.getClass().toString());
}
@ -156,6 +160,11 @@ public class Footprint {
addPoint(x + path.getMaxX(), y + path.getMaxY());
}
private void drawRectangle(double x, double y, URectangle rect) {
addPoint(x, y);
addPoint(x + rect.getWidth(), y + rect.getHeight());
}
public void flushUg() {
}

View File

@ -90,7 +90,8 @@ public class Ribbon implements PDrawing {
public IntricatedPoint getTimeProjection(StringBounder stringBounder, TimeTick tick) {
final double x = ruler.getPosInPixel(tick);
final double y = getHeightForConstraints(stringBounder) + getRibbonHeight() / 2;
final double y = getHeightForConstraints(stringBounder) + getHeightForNotes(stringBounder, Position.TOP)
+ getHeightForTopComment(stringBounder) + getRibbonHeight() / 2;
for (ChangeState change : changes) {
if (change.getWhen().compareTo(tick) == 0) {
return new IntricatedPoint(new Point2D.Double(x, y), new Point2D.Double(x, y));

View File

@ -72,8 +72,8 @@ public class DriverEllipseSvg implements UDriver<SvgGraphics> {
final HColor back = param.getBackcolor();
if (back instanceof HColorGradient) {
final HColorGradient gr = (HColorGradient) back;
final String id = svg.createSvgGradient(mapper.toRGB(gr.getColor1()),
mapper.toRGB(gr.getColor2()), gr.getPolicy());
final String id = svg.createSvgGradient(mapper.toRGB(gr.getColor1()), mapper.toRGB(gr.getColor2()),
gr.getPolicy());
svg.setFillColor("url(#" + id + ")");
} else if (back == null || back instanceof HColorBackground) {
svg.setFillColor("none");
@ -92,15 +92,22 @@ public class DriverEllipseSvg implements UDriver<SvgGraphics> {
if (start == 0 && extend == 0) {
svg.svgEllipse(cx, cy, width / 2, height / 2, shape.getDeltaShadow());
} else {
// http://www.itk.ilstu.edu/faculty/javila/SVG/SVG_drawing1/elliptical_curve.htm
start = start + 90;
final double x1 = cx + Math.sin(start * Math.PI / 180.) * width / 2;
final double y1 = cy + Math.cos(start * Math.PI / 180.) * height / 2;
final double x2 = cx + Math.sin((start + extend) * Math.PI / 180.) * width / 2;
final double y2 = cy + Math.cos((start + extend) * Math.PI / 180.) * height / 2;
// svg.svgEllipse(x1, y1, 1, 1, 0);
// svg.svgEllipse(x2, y2, 1, 1, 0);
svg.svgArcEllipse(width / 2, height / 2, x1, y1, x2, y2);
if (extend > 0) {
// http://www.itk.ilstu.edu/faculty/javila/SVG/SVG_drawing1/elliptical_curve.htm
final double x1 = cx + Math.sin(start * Math.PI / 180.) * width / 2;
final double y1 = cy + Math.cos(start * Math.PI / 180.) * height / 2;
final double x2 = cx + Math.sin((start + extend) * Math.PI / 180.) * width / 2;
final double y2 = cy + Math.cos((start + extend) * Math.PI / 180.) * height / 2;
svg.svgArcEllipse(width / 2, height / 2, x1, y1, x2, y2);
} else {
final double x1 = cx + Math.sin((start + extend) * Math.PI / 180.) * width / 2;
final double y1 = cy + Math.cos((start + extend) * Math.PI / 180.) * height / 2;
final double x2 = cx + Math.sin(start * Math.PI / 180.) * width / 2;
final double y2 = cy + Math.cos(start * Math.PI / 180.) * height / 2;
svg.svgArcEllipse(width / 2, height / 2, x1, y1, x2, y2);
}
}
}

View File

@ -106,6 +106,10 @@ public class PSystemVersion extends AbstractPSystem {
return getImage("arecibo.png");
}
public static BufferedImage getDotc() {
return getImage("dotc.png");
}
public static BufferedImage getApple2Image() {
return getImageWebp("apple2.png");
}

View File

@ -44,7 +44,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000;
public static int version() {
return 1202016;
return 1202017;
}
public static int versionPatched() {
@ -93,7 +93,7 @@ public class Version {
}
public static long compileTime() {
return 1598214043932L;
return 1600518611890L;
}
public static String compileTimeString() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

View File

@ -143,4 +143,8 @@ public class GraphvizJs implements Graphviz {
};
}
public boolean graphviz244onWindows() {
return false;
}
}

View File

@ -72,8 +72,8 @@ class Fork extends WBSTextBlock {
final Dimension2D mainDim = main.calculateDimension(stringBounder);
final double dx = (fullDim.getWidth() - mainDim.getWidth()) / 2;
main.drawU(ug.apply(UTranslate.dx(dx)));
drawLine(ug, dx + mainDim.getWidth() / 2, mainDim.getHeight(), dx + mainDim.getWidth() / 2, mainDim.getHeight()
+ deltay / 2);
drawLine(ug, dx + mainDim.getWidth() / 2, mainDim.getHeight(), dx + mainDim.getWidth() / 2,
mainDim.getHeight() + deltay / 2);
double x = 0;
final double y = mainDim.getHeight() + deltay;
if (right.size() == 0) {
@ -102,6 +102,7 @@ class Fork extends WBSTextBlock {
}
final Dimension2D mainDim = main.calculateDimension(stringBounder);
height += mainDim.getHeight();
height += deltay;
width = Math.max(width, mainDim.getWidth());
return new Dimension2DDouble(width, height);
}