Import version 1.2021.8

This commit is contained in:
Arnaud Roques 2021-06-27 18:50:40 +02:00
parent 138b4c1f95
commit d55c9c6ca7
120 changed files with 3310 additions and 1659 deletions

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2021.8-SNAPSHOT</version>
<version>1.2021.9-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>
@ -227,11 +227,6 @@
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.8.1</version>
</plugin>
</plugins>
</build>
</project>

View File

@ -289,6 +289,7 @@ ganttDiagram {
}
timeline {
BackgroundColor transparent
LineColor #C0C0C0
}
closed {
BackGroundColor #E0E8E8

View File

@ -78,7 +78,7 @@ public interface ISkinParam extends ISkinSimple {
public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam);
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection,
boolean isReverseDefine);
boolean isReverseDefine, HorizontalAlignment overrideDefault);
public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue);

View File

@ -72,6 +72,7 @@ public class Option {
private OptionPreprocOutputMode preprocessorOutput = null;
private boolean failfast = false;
private boolean failfast2 = false;
private boolean noerror = false;
private boolean duration = false;
private boolean debugsvek = false;
@ -228,6 +229,8 @@ public class Option {
this.failfast = true;
} else if (s.equalsIgnoreCase("-failfast2")) {
this.failfast2 = true;
} else if (s.equalsIgnoreCase("-noerror")) {
this.noerror = true;
} else if (s.equalsIgnoreCase("-checkonly")) {
this.checkOnly = true;
} else if (s.equalsIgnoreCase("-theme")) {
@ -619,6 +622,14 @@ public class Option {
this.failfast2 = failfast2;
}
public final void setNoerror(boolean noerror) {
this.noerror = noerror;
}
public final boolean isNoerror() {
return noerror;
}
public final File getOutputFile() {
return outputFile;
}

View File

@ -108,7 +108,7 @@ public class OptionPrint {
+ "file\tTo include file as if '!include file' were used");
System.out.println(
" -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern");
System.out.println(" -theme xxx\\t\\tTo use a specific theme");
System.out.println(" -theme xxx\t\tTo use a specific theme");
System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")");
System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern");
System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images");
@ -133,6 +133,7 @@ public class OptionPrint {
System.out.println(" -checkonly\t\tTo check the syntax of files without generating images");
System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs");
System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster");
System.out.println(" -noerror\t\tTo skip images when error in diagrams");
System.out.println(" -duration\t\tTo print the duration of complete diagrams processing");
System.out.println(" -nbthread N\t\tTo use (N) threads for processing");
System.out.println(" -nbthread auto\tTo use " + Option.defaultNbThreads() + " threads for processing");

View File

@ -493,6 +493,7 @@ public class Run {
option.getConfig(), option.getCharset(), option.getFileFormatOption());
}
sourceFileReader.setCheckMetadata(option.isCheckMetadata());
((SourceFileReaderAbstract) sourceFileReader).setNoerror(option.isNoerror());
if (option.isComputeurl()) {
error.goOk();

View File

@ -357,7 +357,8 @@ public class SkinParam implements ISkinParam {
}
public char getCircledCharacter(Stereotype stereotype) {
final String value2 = getValue("spotchar" + Objects.requireNonNull(stereotype).getLabel(Guillemet.DOUBLE_COMPARATOR));
final String value2 = getValue(
"spotchar" + Objects.requireNonNull(stereotype).getLabel(Guillemet.DOUBLE_COMPARATOR));
if (value2 != null && value2.length() > 0) {
return value2.charAt(0);
}
@ -613,7 +614,7 @@ public class SkinParam implements ISkinParam {
}
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection,
boolean isReverseDefine) {
boolean isReverseDefine, HorizontalAlignment overrideDefault) {
final String value;
switch (param) {
case sequenceMessageAlignment:
@ -662,7 +663,7 @@ public class SkinParam implements ISkinParam {
}
final HorizontalAlignment result = HorizontalAlignment.fromString(value);
if (result == null && param == AlignmentParam.noteTextAlignment) {
return getDefaultTextAlignment(HorizontalAlignment.LEFT);
return getDefaultTextAlignment(overrideDefault == null ? HorizontalAlignment.LEFT : overrideDefault);
} else if (result == null && param == AlignmentParam.stateMessageAlignment) {
return getDefaultTextAlignment(HorizontalAlignment.CENTER);
} else if (result == null) {

View File

@ -69,319 +69,398 @@ public class SkinParamDelegator implements ISkinParam {
this.skinParam = skinParam;
}
@Override
public HColor getHyperlinkColor() {
return skinParam.getHyperlinkColor();
}
@Override
public HColor getBackgroundColor(boolean replaceTransparentByWhite) {
return skinParam.getBackgroundColor(replaceTransparentByWhite);
}
@Override
public int getCircledCharacterRadius() {
return skinParam.getCircledCharacterRadius();
}
@Override
public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam) {
return skinParam.getFont(stereotype, false, fontParam);
}
@Override
public HColor getFontHtmlColor(Stereotype stereotype, FontParam... param) {
return skinParam.getFontHtmlColor(stereotype, param);
}
@Override
public HColor getHtmlColor(ColorParam param, Stereotype stereotype, boolean clickable) {
return skinParam.getHtmlColor(param, stereotype, clickable);
}
@Override
public String getValue(String key) {
return skinParam.getValue(key);
}
@Override
public int classAttributeIconSize() {
return skinParam.classAttributeIconSize();
}
@Override
public int getDpi() {
return skinParam.getDpi();
}
@Override
public DotSplines getDotSplines() {
return skinParam.getDotSplines();
}
@Override
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection,
boolean isReverseDefine) {
return skinParam.getHorizontalAlignment(param, arrowDirection, isReverseDefine);
boolean isReverseDefine, HorizontalAlignment overrideDefault) {
return skinParam.getHorizontalAlignment(param, arrowDirection, isReverseDefine, overrideDefault);
}
@Override
public ColorMapper getColorMapper() {
return skinParam.getColorMapper();
}
@Override
public boolean shadowing(Stereotype stereotype) {
return skinParam.shadowing(stereotype);
}
@Override
public boolean shadowing2(Stereotype stereotype, SkinParameter skinParameter) {
return skinParam.shadowing2(stereotype, skinParameter);
}
@Override
public PackageStyle packageStyle() {
return skinParam.packageStyle();
}
@Override
public Sprite getSprite(String name) {
return skinParam.getSprite(name);
}
@Override
public ComponentStyle componentStyle() {
return skinParam.componentStyle();
}
@Override
public boolean stereotypePositionTop() {
return skinParam.stereotypePositionTop();
}
@Override
public boolean useSwimlanes(UmlDiagramType type) {
return skinParam.useSwimlanes(type);
}
@Override
public double getNodesep() {
return skinParam.getNodesep();
}
@Override
public double getRanksep() {
return skinParam.getRanksep();
}
@Override
public double getRoundCorner(CornerParam param, Stereotype stereotype) {
return skinParam.getRoundCorner(param, stereotype);
}
@Override
public double getDiagonalCorner(CornerParam param, Stereotype stereotype) {
return skinParam.getDiagonalCorner(param, stereotype);
}
@Override
public UStroke getThickness(LineParam param, Stereotype stereotype) {
return skinParam.getThickness(param, stereotype);
}
@Override
public LineBreakStrategy maxMessageSize() {
return skinParam.maxMessageSize();
}
@Override
public LineBreakStrategy wrapWidth() {
return skinParam.wrapWidth();
}
@Override
public boolean strictUmlStyle() {
return skinParam.strictUmlStyle();
}
@Override
public boolean forceSequenceParticipantUnderlined() {
return skinParam.forceSequenceParticipantUnderlined();
}
@Override
public ConditionStyle getConditionStyle() {
return skinParam.getConditionStyle();
}
@Override
public ConditionEndStyle getConditionEndStyle() {
return skinParam.getConditionEndStyle();
}
@Override
public double minClassWidth() {
return skinParam.minClassWidth();
}
@Override
public boolean sameClassWidth() {
return skinParam.sameClassWidth();
}
@Override
public Rankdir getRankdir() {
return skinParam.getRankdir();
}
@Override
public boolean useOctagonForActivity(Stereotype stereotype) {
return skinParam.useOctagonForActivity(stereotype);
}
@Override
public HColorSet getIHtmlColorSet() {
return skinParam.getIHtmlColorSet();
}
@Override
public boolean useUnderlineForHyperlink() {
return skinParam.useUnderlineForHyperlink();
}
@Override
public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue) {
return skinParam.getDefaultTextAlignment(defaultValue);
}
@Override
public double getPadding() {
return skinParam.getPadding();
}
@Override
public int groupInheritance() {
return skinParam.groupInheritance();
}
@Override
public Guillemet guillemet() {
return skinParam.guillemet();
}
@Override
public boolean handwritten() {
return skinParam.handwritten();
}
@Override
public String getSvgLinkTarget() {
return skinParam.getSvgLinkTarget();
}
@Override
public String getPreserveAspectRatio() {
return skinParam.getPreserveAspectRatio();
}
@Override
public String getMonospacedFamily() {
return skinParam.getMonospacedFamily();
}
@Override
public Colors getColors(ColorParam param, Stereotype stereotype) throws NoSuchColorException {
return skinParam.getColors(param, stereotype);
}
@Override
public int getTabSize() {
return skinParam.getTabSize();
}
@Override
public boolean shadowingForNote(Stereotype stereotype) {
return shadowingForNote(stereotype);
}
@Override
public int maxAsciiMessageLength() {
return skinParam.maxAsciiMessageLength();
}
@Override
public int colorArrowSeparationSpace() {
return skinParam.colorArrowSeparationSpace();
}
@Override
public SplitParam getSplitParam() {
return skinParam.getSplitParam();
}
@Override
public int swimlaneWidth() {
return skinParam.swimlaneWidth();
}
@Override
public UmlDiagramType getUmlDiagramType() {
return skinParam.getUmlDiagramType();
}
@Override
public HColor hoverPathColor() {
return skinParam.hoverPathColor();
}
@Override
public double getPadding(PaddingParam param) {
return skinParam.getPadding(param);
}
@Override
public boolean useRankSame() {
return skinParam.useRankSame();
}
@Override
public boolean displayGenericWithOldFashion() {
return skinParam.displayGenericWithOldFashion();
}
@Override
public TikzFontDistortion getTikzFontDistortion() {
return skinParam.getTikzFontDistortion();
}
@Override
public boolean responseMessageBelowArrow() {
return skinParam.responseMessageBelowArrow();
}
@Override
public boolean svgDimensionStyle() {
return skinParam.svgDimensionStyle();
}
@Override
public char getCircledCharacter(Stereotype stereotype) {
return skinParam.getCircledCharacter(stereotype);
}
@Override
public LineBreakStrategy swimlaneWrapTitleWidth() {
return skinParam.swimlaneWrapTitleWidth();
}
@Override
public boolean fixCircleLabelOverlapping() {
return skinParam.fixCircleLabelOverlapping();
}
@Override
public void setUseVizJs(boolean useVizJs) {
skinParam.setUseVizJs(useVizJs);
}
@Override
public boolean isUseVizJs() {
return skinParam.isUseVizJs();
}
@Override
public void copyAllFrom(ISkinSimple other) {
skinParam.copyAllFrom(other);
}
@Override
public Map<String, String> values() {
return skinParam.values();
}
@Override
public HorizontalAlignment getStereotypeAlignment() {
return skinParam.getStereotypeAlignment();
}
@Override
public Padder sequenceDiagramPadder() {
return skinParam.sequenceDiagramPadder();
}
@Override
public StyleBuilder getCurrentStyleBuilder() {
return skinParam.getCurrentStyleBuilder();
}
@Override
public void muteStyle(Style modifiedStyle) {
skinParam.muteStyle(modifiedStyle);
}
@Override
public Collection<String> getAllSpriteNames() {
return skinParam.getAllSpriteNames();
}
@Override
public String getDefaultSkin() {
return skinParam.getDefaultSkin();
}
@Override
public void setDefaultSkin(String newFileName) {
skinParam.setDefaultSkin(newFileName);
}
@Override
public ActorStyle actorStyle() {
return skinParam.actorStyle();
}
@Override
public void setSvgSize(String origin, String sizeToUse) {
skinParam.setSvgSize(origin, sizeToUse);
}
@Override
public String transformStringForSizeHack(String s) {
return skinParam.transformStringForSizeHack(s);
}
@Override
public LengthAdjust getlengthAdjust() {
return skinParam.getlengthAdjust();
}
@Override
public void assumeTransparent(ThemeStyle style) {
skinParam.assumeTransparent(style);
}
@Override
public ThemeStyle getThemeStyle() {
return skinParam.getThemeStyle();
}

View File

@ -50,13 +50,14 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.error.PSystemError;
import net.sourceforge.plantuml.preproc.FileWithSuffix;
import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.security.SecurityUtils;
public abstract class SourceFileReaderAbstract {
public abstract class SourceFileReaderAbstract implements ISourceFileReader {
protected File file;
protected File outputDirectory;
@ -65,6 +66,7 @@ public abstract class SourceFileReaderAbstract {
protected BlockUmlBuilder builder;
protected FileFormatOption fileFormatOption;
private boolean checkMetadata;
private boolean noerror;
public void setCheckMetadata(boolean checkMetadata) {
this.checkMetadata = checkMetadata;
@ -120,8 +122,8 @@ public abstract class SourceFileReaderAbstract {
return Collections.singletonList(image);
}
protected void exportWarnOrErrIfWord(final SFile f, final Diagram system) throws FileNotFoundException {
if (OptionFlags.getInstance().isWord()) {
protected void exportWarnOrErrIfWord(SFile f, Diagram system) throws FileNotFoundException {
if (OptionFlags.getInstance().isWord() && f != null) {
final String warnOrError = system.getWarningOrError();
if (warnOrError != null) {
final String name = f.getName().substring(0, f.getName().length() - 4) + ".err";
@ -149,6 +151,9 @@ public abstract class SourceFileReaderAbstract {
system = blockUml.getDiagram();
} catch (Throwable t) {
t.printStackTrace();
if (OptionFlags.getInstance().isSilentlyCompletelyIgnoreErrors()) {
continue;
}
return getCrashedImage(blockUml, t, suggested.getFile(0));
}
@ -157,8 +162,14 @@ public abstract class SourceFileReaderAbstract {
}
OptionFlags.getInstance().logData(SFile.fromFile(file), system);
final List<FileImageData> exportDiagrams = PSystemUtils.exportDiagrams(system, suggested, fileFormatOption,
checkMetadata);
final List<FileImageData> exportDiagrams;
if (noerror) {
exportDiagrams = new ArrayList<FileImageData>();
exportDiagrams.add(
new FileImageData(null, new ImageDataSimple(new Dimension2DDouble(0, 0), FileImageData.ERROR)));
} else
exportDiagrams = PSystemUtils.exportDiagrams(system, suggested, fileFormatOption, checkMetadata);
if (exportDiagrams.size() > 1) {
cpt += exportDiagrams.size() - 1;
}
@ -180,4 +191,9 @@ public abstract class SourceFileReaderAbstract {
abstract protected SuggestedFile getSuggestedFile(BlockUml blockUml) throws FileNotFoundException;
protected final void setNoerror(boolean noerror) {
this.noerror = noerror;
}
}

View File

@ -47,6 +47,9 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class InstructionSwitch extends WithNote implements Instruction, InstructionCollection {
@ -105,7 +108,7 @@ public class InstructionSwitch extends WithNote implements Instruction, Instruct
}
final public boolean kill() {
throw new UnsupportedOperationException();
return current.kill();
}
public LinkRendering getInLinkRendering() {
@ -151,6 +154,16 @@ public class InstructionSwitch extends WithNote implements Instruction, Instruct
// TODO Auto-generated method stub
}
@Override
public boolean addNote(Display note, NotePosition position, NoteType type, Colors colors, Swimlane swimlaneNote) {
if (current.isEmpty()) {
return super.addNote(note, position, type, colors, swimlaneNote);
} else {
return current.addNote(note, position, type, colors, swimlaneNote);
}
}
// public void afterEndwhile(LinkRendering linkRenderer) {
// this.afterEndwhile = linkRenderer;

View File

@ -103,7 +103,7 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
}
public HorizontalAlignment arrowHorizontalAlignment() {
return skinParam.getHorizontalAlignment(AlignmentParam.arrowMessageAlignment, null, false);
return skinParam.getHorizontalAlignment(AlignmentParam.arrowMessageAlignment, null, false, null);
}
private FtileGeometry cachedGeometry;

View File

@ -40,6 +40,7 @@ import java.util.List;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.UseStyle;
import net.sourceforge.plantuml.activitydiagram3.Branch;
import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
@ -58,6 +59,7 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator {
@ -100,7 +102,13 @@ public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator {
for (Branch branch : branches) {
ftiles.add(new FtileMinWidthCentered(branch.getFtile(), 30));
}
final Rainbow arrowColor = Rainbow.build(skinParam());
final Rainbow arrowColor;
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinitionArrow().getMergedStyle(skinParam().getCurrentStyleBuilder());
arrowColor = Rainbow.build(style, skinParam().getIHtmlColorSet(), skinParam().getThemeStyle());
} else {
arrowColor = Rainbow.build(skinParam());
}
if (ftiles.size() == 1) {
final FtileSwitchWithOneLink result = new FtileSwitchWithOneLink(ftiles, branches, swimlane, diamond1,
diamond2, getStringBounder(), arrowColor);

View File

@ -230,7 +230,7 @@ public class FtileGroup extends AbstractFtile {
.withStroke(stroke).withCorner(roundCorner, 0);
final HorizontalAlignment align = inner.skinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment,
null, false);
null, false, null);
type.asBig(name, align, TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext,
skinParam().getStereotypeAlignment()).drawU(ug);

View File

@ -163,7 +163,7 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil, Stylea
}
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null,
false);
false, null);
final Sheet sheet = Parser.build(fc, align, skinParam, CreoleMode.FULL).createSheet(note.getDisplay());
final TextBlock text = new SheetBlock2(new SheetBlock1(sheet, wrapWidth, skinParam.getPadding()), this,
new UStroke(1));

View File

@ -126,14 +126,29 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds {
return;
}
final Point2D p1 = getP1(stringBounder);
final Point2D p2 = getP2(stringBounder);
final double x1 = p1.getX();
final double y1 = p1.getY();
final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder);
final Point2D ptA = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointA());
final Point2D ptB = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointB());
final Point2D ptD = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointD());
final Point2D p2;
final UPolygon arrow;
if (x1 < ptD.getX()) {
p2 = ptD;
arrow = Arrows.asToRight();
} else if (x1 > ptB.getX()) {
p2 = ptB;
arrow = Arrows.asToLeft();
} else {
p2 = ptA;
arrow = Arrows.asToDown();
}
final double x2 = p2.getX();
final double y2 = p2.getY();
final UPolygon arrow = x2 > x1 ? Arrows.asToRight() : Arrows.asToLeft();
final Snake snake = Snake.create(arrowColor, arrow);
snake.addPoint(x1, y1);
snake.addPoint(x1, y2);
@ -147,29 +162,8 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds {
.getTranslated(getFtile1().calculateDimension(stringBounder).getPointOut());
}
private Point2D getP2(StringBounder stringBounder) {
final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder);
final Point2D pt;
if (getFtile1() == tiles.get(0)) {
pt = dimDiamond2.getPointD();
} else if (getFtile1() == tiles.get(tiles.size() - 1)) {
pt = dimDiamond2.getPointB();
} else {
throw new IllegalStateException();
}
return getTranslateDiamond2(stringBounder).getTranslated(pt);
}
}
// protected UTranslate getTranslateOf(Ftile tile, StringBounder stringBounder)
// {
// return getTranslateNude(tile,
// stringBounder).compose(getTranslateMain(stringBounder));
//
// }
class ConnectionVerticalTop extends AbstractConnection {
private final Branch branch;
@ -278,9 +272,14 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds {
final List<Connection> conns = new ArrayList<>();
conns.add(new ConnectionHorizontalThenVertical(tiles.get(0), branches.get(0)));
conns.add(new ConnectionHorizontalThenVertical(tiles.get(tiles.size() - 1), branches.get(tiles.size() - 1)));
conns.add(new ConnectionVerticalThenHorizontal(tiles.get(0)));
conns.add(new ConnectionVerticalThenHorizontal(tiles.get(tiles.size() - 1)));
for (int i = 1; i < tiles.size() - 1; i++) {
final int first = getFirst(stringBounder);
final int last = getLast(stringBounder);
if (first < tiles.size())
conns.add(new ConnectionVerticalThenHorizontal(tiles.get(first)));
if (last > 0)
conns.add(new ConnectionVerticalThenHorizontal(tiles.get(last)));
for (int i = first + 1; i < last; i++) {
final Ftile tile = tiles.get(i);
conns.add(new ConnectionVerticalTop(tile, branches.get(i)));
if (tile.calculateDimension(stringBounder).hasPointOut()) {
@ -291,4 +290,24 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds {
return FtileUtils.addConnection(this, conns);
}
private int getFirst(StringBounder stringBounder) {
for (int i = 0; i < tiles.size() - 1; i++) {
final Ftile tile = tiles.get(i);
if (tile.calculateDimension(stringBounder).hasPointOut()) {
return i;
}
}
return tiles.size();
}
private int getLast(StringBounder stringBounder) {
for (int i = tiles.size() - 1; i >= 0; i--) {
final Ftile tile = tiles.get(i);
if (tile.calculateDimension(stringBounder).hasPointOut()) {
return i;
}
}
return -1;
}
}

View File

@ -35,15 +35,18 @@
*/
package net.sourceforge.plantuml.asciiart;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.skin.ArrowComponent;
import net.sourceforge.plantuml.skin.ArrowConfiguration;
import net.sourceforge.plantuml.skin.ArrowDirection;
import net.sourceforge.plantuml.skin.Component;
import net.sourceforge.plantuml.skin.ComponentType;
import net.sourceforge.plantuml.skin.rose.ComponentRoseGroupingSpace;
import net.sourceforge.plantuml.skin.rose.ComponentRoseNewpage;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.style.Style;
@ -56,7 +59,8 @@ public class TextSkin extends Rose {
}
@Override
public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param, Display stringsToDisplay) {
public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param,
Display stringsToDisplay) {
if (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL
|| config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE
|| config.getArrowDirection() == ArrowDirection.BOTH_DIRECTION) {
@ -70,8 +74,23 @@ public class TextSkin extends Rose {
}
@Override
public Component createComponent(Style style[], ComponentType type, ArrowConfiguration config,
ISkinParam param, Display stringsToDisplay) {
public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, Display stringsToDisplay,
NotePosition notePosition) {
if (type == ComponentType.NOTE || type == ComponentType.NOTE_BOX) {
return new ComponentTextNote(type, stringsToDisplay, fileFormat);
}
throw new UnsupportedOperationException(type.toString());
}
@Override
public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param,
Display stringsToDisplay) {
return createComponentNote(styles, type, param, stringsToDisplay, null);
}
@Override
public Component createComponent(Style style[], ComponentType type, ArrowConfiguration config, ISkinParam param,
Display stringsToDisplay) {
if (type == ComponentType.ACTOR_HEAD || type == ComponentType.ACTOR_TAIL) {
return new ComponentTextActor(type, stringsToDisplay, fileFormat,
fileFormat == FileFormat.UTXT ? AsciiShape.STICKMAN_UNICODE : AsciiShape.STICKMAN);
@ -85,10 +104,9 @@ public class TextSkin extends Rose {
if (type.name().endsWith("_HEAD") || type.name().endsWith("_TAIL")) {
return new ComponentTextParticipant(type, stringsToDisplay, fileFormat);
}
if (type.isArrow()
&& (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL
|| config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE || config
.getArrowDirection() == ArrowDirection.BOTH_DIRECTION)) {
if (type.isArrow() && (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL
|| config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE
|| config.getArrowDirection() == ArrowDirection.BOTH_DIRECTION)) {
return new ComponentTextArrow(type, config, stringsToDisplay, fileFormat, param.maxAsciiMessageLength());
}
if (type.isArrow() && config.isSelfArrow()) {
@ -115,9 +133,6 @@ public class TextSkin extends Rose {
if (type == ComponentType.ALIVE_BOX_OPEN_OPEN) {
return new ComponentTextActiveLine(fileFormat);
}
if (type == ComponentType.NOTE || type == ComponentType.NOTE_BOX) {
return new ComponentTextNote(type, stringsToDisplay, fileFormat);
}
if (type == ComponentType.DIVIDER) {
return new ComponentTextDivider(type, stringsToDisplay, fileFormat);
}
@ -130,9 +145,6 @@ public class TextSkin extends Rose {
if (type == ComponentType.GROUPING_ELSE) {
return new ComponentTextGroupingElse(type, stringsToDisplay, fileFormat);
}
if (type == ComponentType.NEWPAGE) {
return new ComponentTextNewpage(fileFormat);
}
if (type == ComponentType.DELAY_TEXT) {
return new ComponentTextDelay(type, stringsToDisplay, fileFormat);
}
@ -141,5 +153,11 @@ public class TextSkin extends Rose {
}
throw new UnsupportedOperationException(type.toString());
}
@Override
public Component createComponentNewPage(ISkinParam param) {
return new ComponentTextNewpage(fileFormat);
}
}

View File

@ -1,77 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.creole.rosetta;
import java.util.Objects;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.creole.Sheet;
import net.sourceforge.plantuml.creole.SheetBuilder;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
public class CreoleParser2 implements SheetBuilder {
private final FontConfiguration fontConfiguration;
private final ISkinSimple skinParam;
private final HorizontalAlignment horizontalAlignment;
private final CreoleMode creoleMode;
private final FontConfiguration stereotype;
public CreoleParser2(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple skinParam, CreoleMode creoleMode, FontConfiguration stereotype) {
this.stereotype = stereotype;
this.creoleMode = creoleMode;
this.fontConfiguration = fontConfiguration;
this.skinParam = Objects.requireNonNull(skinParam);
this.horizontalAlignment = horizontalAlignment;
}
public Sheet createSheet(Display display) {
final Sheet sheet = new Sheet(horizontalAlignment);
if (display.isWhite() == false) {
final Rosetta rosetta = Rosetta.fromSyntax(WikiLanguage.CREOLE, display);
for (String cs : rosetta.translateTo(WikiLanguage.UNICODE)) {
final StripeRow row = StripeRow.parseUnicode(cs, fontConfiguration);
sheet.add(row);
}
}
return sheet;
}
}

View File

@ -1,105 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public abstract class ReaderAbstractWiki implements ReaderWiki {
static protected final String PNG_OR_GIF = "([-_\\w]+\\.(?:png|gif))";
static protected final String BRACKET1 = "\\[([^\\[\\]]+?)\\]";
static protected final String BRACKET0 = "\\[([^\\[\\]]*?)\\]";
final public List<String> transform(String... data) {
return transform(Arrays.asList(data));
}
// final protected String protectURL(String s) {
// return WikiLanguage.protectURL(s);
// }
final protected String rawCode(String s, String start, String end) {
final StringBuilder sb = new StringBuilder(s.length());
boolean rawMode = false;
boolean rawInRaw = false;
for (int i = 0; i < s.length(); i++) {
if (rawMode == false && s.substring(i).startsWith(start)) {
rawMode = true;
rawInRaw = false;
i += start.length() - 1;
sb.append(WikiLanguage.UNICODE.tag("code"));
if (s.substring(i + 1).startsWith(start)) {
i += start.length();
sb.append(WikiLanguage.hideCharsF7(start));
rawInRaw = true;
}
continue;
}
if (rawMode == true && s.substring(i).startsWith(end) && s.substring(i + 1).startsWith(end) == false) {
rawMode = false;
i += end.length() - 1;
if (rawInRaw && s.substring(i + 1).startsWith(end)) {
i += end.length();
sb.append(WikiLanguage.hideCharsF7(end));
}
sb.append(WikiLanguage.UNICODE.slashTag("code"));
rawInRaw = false;
continue;
}
char ch = s.charAt(i);
if (rawMode) {
ch = WikiLanguage.toF7(ch);
}
sb.append(ch);
}
return sb.toString();
}
protected final String cleanAndHideBackslashSeparator(String s, String sep, String unicodeSep) {
s = s.trim();
if (s.startsWith(sep)) {
s = s.substring(1);
}
if (s.endsWith(sep)) {
s = s.substring(0, s.length() - 1);
}
s = s.trim();
final String regex;
if (sep.equals("^") || sep.equals("|")) {
regex = "\\\\\\" + sep;
} else {
throw new IllegalArgumentException();
}
s = s.replaceAll(regex, unicodeSep);
s = singleLineFormat(s.trim());
s = s.replace(sep, " " + sep + " ");
return s;
}
protected abstract String singleLineFormat(String wiki);
final protected void exportCodeInternal(List<String> uhtml, String tag, List<String> lines) {
uhtml.add(WikiLanguage.UNICODE.tag(tag));
for (String s : lines) {
uhtml.add(s);
}
uhtml.add(WikiLanguage.UNICODE.slashTag(tag));
}
final protected void exportCodeInternalEnsureStartuml(List<String> uhtml, String tag, List<String> lines) {
exportCodeInternal(uhtml, tag, ensureStartuml(lines));
}
private List<String> ensureStartuml(List<String> lines) {
final String first = lines.get(0);
if (first.startsWith("@start")) {
return lines;
}
final List<String> copy = new ArrayList<>(lines);
copy.add(0, "@startuml");
copy.add("@enduml");
return copy;
}
}

View File

@ -1,40 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReaderCreole extends ReaderAbstractWiki implements ReaderWiki {
@Override
protected String singleLineFormat(String wiki) {
// Legacy HTML
wiki = wiki.replace("<b>", WikiLanguage.UNICODE.tag("strong"));
wiki = wiki.replace("</b>", WikiLanguage.UNICODE.slashTag("strong"));
wiki = wiki.replace("<i>", WikiLanguage.UNICODE.tag("em"));
wiki = wiki.replace("</i>", WikiLanguage.UNICODE.slashTag("em"));
// Em & Strong
wiki = wiki.replaceAll("\\*\\*(.+?)\\*\\*",
WikiLanguage.UNICODE.tag("strong") + "$1" + WikiLanguage.UNICODE.slashTag("strong"));
wiki = wiki.replaceAll("//(.+?)//",
WikiLanguage.UNICODE.tag("em") + "$1" + WikiLanguage.UNICODE.slashTag("em"));
// Strike
wiki = wiki.replaceAll("--([^-]+?)--",
WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike"));
return wiki;
}
public List<String> transform(List<String> raw) {
final List<String> uhtml = new ArrayList<>();
for (int i = 0; i < raw.size(); i++) {
String current = raw.get(i);
uhtml.add(singleLineFormat(current));
}
return Collections.unmodifiableList(uhtml);
}
}

View File

@ -1,326 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReaderDokuwiki extends ReaderAbstractWiki implements ReaderWiki {
@Override
protected String singleLineFormat(String wiki) {
final boolean endingSlashSlash = wiki.endsWith("\\\\");
if (endingSlashSlash) {
wiki = wiki.substring(0, wiki.length() - 2);
}
// Raw %% and ''
wiki = rawCode(wiki, "''%%", "%%''");
wiki = rawCode(wiki, "%%", "%%");
wiki = rawCode(wiki, "''", "''");
// Protect/escape some character
for (char c : "^|<".toCharArray()) {
wiki = wiki.replace("\\" + c, "" + WikiLanguage.toF7(c));
}
// Horizontal lines
wiki = wiki.replaceAll("^___+$", WikiLanguage.UNICODE.tag("hr"));
wiki = wiki.replaceAll("^---+$", WikiLanguage.UNICODE.tag("hr"));
wiki = wiki.replaceAll("^\\*\\*\\*+$", WikiLanguage.UNICODE.tag("hr"));
// Strike
wiki = wiki.replaceAll("\\<del\\>([^<>]+?)\\</del\\>",
WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike"));
wiki = wiki.replaceAll("\\<strike\\>([^<>]+?)\\</strike\\>",
WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike"));
wiki = wiki.replaceAll("~~([^~]+?)~~",
WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike"));
// break
wiki = wiki.replace("\\\\ ", WikiLanguage.UNICODE.tag("br"));
// Em & Strong
wiki = wiki.replaceAll("//(.+?)//",
WikiLanguage.UNICODE.tag("em") + "$1" + WikiLanguage.UNICODE.slashTag("em"));
wiki = wiki.replaceAll("\\*\\*(.+?)\\*\\*",
WikiLanguage.UNICODE.tag("strong") + "$1" + WikiLanguage.UNICODE.slashTag("strong"));
wiki = wiki.replace(WikiLanguage.UNICODE.tag("strong") + WikiLanguage.UNICODE.tag("em"),
WikiLanguage.UNICODE.tag("strongem"));
wiki = wiki.replace(WikiLanguage.UNICODE.tag("em") + WikiLanguage.UNICODE.tag("strong"),
WikiLanguage.UNICODE.tag("strongem"));
wiki = wiki.replace(WikiLanguage.UNICODE.slashTag("strong") + WikiLanguage.UNICODE.slashTag("em"),
WikiLanguage.UNICODE.slashTag("strongem"));
wiki = wiki.replace(WikiLanguage.UNICODE.slashTag("em") + WikiLanguage.UNICODE.slashTag("strong"),
WikiLanguage.UNICODE.slashTag("strongem"));
// Underscore
wiki = wiki.replaceAll("__(.+?)__", WikiLanguage.UNICODE.tag("u") + "$1" + WikiLanguage.UNICODE.slashTag("u"));
if (endingSlashSlash) {
wiki += WikiLanguage.UNICODE.tag("br");
}
return wiki;
}
public List<String> transform(List<String> raw) {
final List<String> uhtml = new ArrayList<>();
for (int i = 0; i < raw.size(); i++) {
String current = raw.get(i);
if (current.startsWith("FIXME ")) {
continue;
}
current = current.replaceFirst("^\\s+@start", "@start");
current = current.replaceFirst("^\\s+@end", "@end");
final AutoGroup autoGroup = getAutoGroup(raw, i);
if (autoGroup != null) {
i += autoGroup.getSkipped() - 1;
autoGroup.exportHtml(uhtml);
continue;
}
final StartEndGroup startEndGroup = getStartEndGroup(raw, i);
if (startEndGroup != null) {
i += startEndGroup.getSkipped() - 1;
startEndGroup.exportHtml(uhtml);
continue;
}
if (current.length() == 0) {
uhtml.add(WikiLanguage.UNICODE.tag("p"));
} else {
uhtml.add(singleLineFormat(current));
}
}
return Collections.unmodifiableList(uhtml);
}
private StartEndGroup getStartEndGroup(List<String> raw, int i) {
if (raw.get(i).equals("<code>")) {
return new StartEndGroup(raw, i, "</code>");
}
if (raw.get(i).startsWith("<uml")) {
return new StartEndGroup(raw, i, "</uml>");
}
if (raw.get(i).equals("<plantuml>")) {
return new StartEndGroup(raw, i, "</plantuml>");
}
return null;
}
private AutoGroup getAutoGroup(List<String> raw, int i) {
AutoGroup group = getAutoGroup(raw, i, " * ", " * ");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, " - ", " - ");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, "\t");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, "> ");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, "] ");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, " ");
if (group != null) {
return group;
}
group = getAutoGroup(raw, i, "^");
if (group != null) {
return group;
}
return null;
}
private AutoGroup getAutoGroup(List<String> raw, int i, String... headers) {
if (raw.get(i).startsWith(headers[0]) == false) {
return null;
}
final AutoGroup result = new AutoGroup(headers);
while (i < raw.size() && result.isInTheGroup(raw.get(i))) {
result.addLine(raw.get(i));
i++;
}
return result;
}
class AutoGroup {
private final List<String> lines = new ArrayList<>();
private int skip = 0;
private final String[] headers;
private AutoGroup(String[] headers) {
this.headers = headers;
}
private void addLine(String s) {
if (headers[0].equals("> ") && s.equals(">")) {
lines.add("");
} else if (headers[0].equals("] ") && s.equals("]")) {
lines.add("");
} else if (headers[0].equals("^")) {
lines.add(s);
} else {
lines.add(s.substring(headers[0].length()));
}
skip++;
}
private int getSkipped() {
return skip;
}
private void exportHtml(List<String> uhtml) {
if (headers[0].equals(" * ")) {
exportList(uhtml, "ul");
} else if (headers[0].equals(" - ")) {
exportList(uhtml, "ol");
} else if (headers[0].equals(" ")) {
exportCode(uhtml);
} else if (headers[0].equals("\t")) {
exportCode(uhtml);
} else if (headers[0].equals("> ")) {
exportBlockquote(uhtml);
} else if (headers[0].equals("] ")) {
exportFieldset(uhtml);
} else if (headers[0].equals("^")) {
exportTable(uhtml);
} else {
throw new UnsupportedOperationException();
}
}
private void exportCode(List<String> uhtml) {
exportCodeInternal(uhtml, "codepre", lines);
}
private void exportList(List<String> uhtml, String type) {
uhtml.add(WikiLanguage.UNICODE.tag(type));
for (String s : lines) {
int level = 0;
if (s.startsWith("* ") || s.startsWith("- ")) {
level++;
s = s.substring(2);
}
uhtml.add(WikiLanguage.UNICODE.tag(type + "li", "level", "" + level) + singleLineFormat(s)
+ WikiLanguage.UNICODE.slashTag(type + "li"));
}
uhtml.add(WikiLanguage.UNICODE.slashTag(type));
}
private void exportFieldset(List<String> uhtml) {
uhtml.add(WikiLanguage.UNICODE.tag("fieldset"));
uhtml.addAll(transform(lines));
uhtml.add(WikiLanguage.UNICODE.slashTag("fieldset"));
}
private void exportBlockquote(List<String> uhtml) {
uhtml.add(WikiLanguage.UNICODE.tag("blockquote"));
uhtml.addAll(transform(lines));
uhtml.add(WikiLanguage.UNICODE.slashTag("blockquote"));
}
private void exportTable(List<String> uhtml) {
uhtml.add(WikiLanguage.UNICODE.tag("table"));
int i = 0;
int sizeHeader = 0;
for (String s : lines) {
final String sep = i == 0 ? "^" : "|";
final String tagHeader = i == 0 ? "th" : "tr";
final String cellHeader = i == 0 ? "tdh" : "td";
uhtml.add(WikiLanguage.UNICODE.tag(tagHeader));
s = cleanAndHideBackslashSeparator(s, sep, "\uF500");
final String cols[] = s.split("\\" + sep);
// System.err.println("cols1=" + Arrays.asList(cols));
if (i == 0) {
sizeHeader = cols.length;
} else if (cols.length != sizeHeader) {
System.err.println("lines=" + lines);
System.err.println("WARNING!!! " + sizeHeader + " " + cols.length);
throw new IllegalStateException("WARNING!!! " + sizeHeader + " " + cols.length);
}
for (String cell : cols) {
cell = cell.trim();
// if (cell.length() > 0) {
uhtml.add(WikiLanguage.UNICODE.tag(cellHeader));
// uhtml.add(singleLineFormat(cell));
uhtml.add(WikiLanguage.restoreAllCharsF7(cell.replace('\uF500', sep.charAt(0))));
uhtml.add(WikiLanguage.UNICODE.slashTag(cellHeader));
// }
}
uhtml.add(WikiLanguage.UNICODE.slashTag(tagHeader));
i++;
}
uhtml.add(WikiLanguage.UNICODE.slashTag("table"));
}
public boolean isInTheGroup(String line) {
if (headers[0].equals("^") && line.startsWith("|")) {
return true;
}
if (headers[0].equals("> ") && line.startsWith(">")) {
return true;
}
if (headers[0].equals("] ") && line.startsWith("]")) {
return true;
}
for (String header : headers) {
if (line.startsWith(header)) {
return true;
}
}
return false;
}
}
class StartEndGroup {
private final List<String> lines = new ArrayList<>();
private int skip = 0;
private final String first;
private StartEndGroup(List<String> raw, int i, String end) {
this.first = raw.get(i);
skip++;
i++;
while (i < raw.size() && raw.get(i).equals(end) == false) {
lines.add(raw.get(i));
i++;
skip++;
}
skip++;
}
private void exportHtml(List<String> uhtml) {
if (first.equals("<code>")) {
exportCodeInternal(uhtml, "codepre", lines);
} else if (first.startsWith("<uml")) {
exportCodeInternal(uhtml, "imageuml", lines);
} else if (first.equals("<plantuml>")) {
exportCodeInternalEnsureStartuml(uhtml, "codeandimg", lines);
} else {
throw new UnsupportedOperationException();
}
}
private int getSkipped() {
return skip;
}
}
}

View File

@ -1,11 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.List;
public interface ReaderWiki {
public static final String REGEX_HTTP = "https?://[^\\s/$.?#][^()\\[\\]\\s]*";
public List<String> transform(List<String> data);
}

View File

@ -1,65 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.cucadiagram.Display;
public class Rosetta {
private final List<String> unicodeHtml;
public static Rosetta fromUnicodeHtml(List<String> lines) {
return new Rosetta(lines);
}
public static Rosetta fromSyntax(WikiLanguage syntaxSource, String... wiki) {
return new Rosetta(syntaxSource, Arrays.asList(wiki));
}
public static Rosetta fromSyntax(WikiLanguage syntaxSource, List<String> wiki) {
return new Rosetta(syntaxSource, wiki);
}
public static Rosetta fromSyntax(WikiLanguage syntaxSource, Display display) {
return new Rosetta(syntaxSource, from(display));
}
private static List<String> from(Display display) {
final List<String> result = new ArrayList<>();
for (CharSequence cs : display) {
result.add(cs.toString());
}
return result;
}
private Rosetta(List<String> lines) {
this.unicodeHtml = new ArrayList<>(lines);
}
private Rosetta(WikiLanguage syntaxSource, List<String> wiki) {
final ReaderWiki reader;
if (syntaxSource == WikiLanguage.DOKUWIKI) {
reader = new ReaderDokuwiki();
} else if (syntaxSource == WikiLanguage.CREOLE) {
reader = new ReaderCreole();
// } else if (syntaxSource == WikiLanguage.MARKDOWN) {
// reader = new ReaderMarkdown();
// } else if (syntaxSource == WikiLanguage.ASCIIDOC) {
// reader = new ReaderAsciidoc();
} else {
throw new UnsupportedOperationException();
}
this.unicodeHtml = reader.transform(wiki);
}
public List<String> translateTo(WikiLanguage syntaxDestination) {
final List<String> html = new ArrayList<>();
final WriterWiki writer = new WriterWiki(syntaxDestination);
html.addAll(writer.transform(unicodeHtml));
return Collections.unmodifiableList(html);
}
}

View File

@ -1,129 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.creole.Stripe;
import net.sourceforge.plantuml.creole.atom.Atom;
import net.sourceforge.plantuml.creole.legacy.AtomTextUtils;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.FontStyle;
public class StripeRow implements Stripe {
private final List<Atom> atoms = new ArrayList<>();
public Atom getLHeader() {
return null;
}
public List<Atom> getAtoms() {
return Collections.unmodifiableList(atoms);
}
public void add(Atom atom) {
atoms.add(atom);
}
private static final Pattern bold = Pattern.compile("^" + WikiLanguage.UNICODE.tag("strong") + "(.*)$");
private static final Pattern unbold = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("strong") + "(.*)$");
private static final Pattern italic = Pattern.compile("^" + WikiLanguage.UNICODE.tag("em") + "(.*)$");
private static final Pattern unitalic = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("em") + "(.*)$");
private static final Pattern strike = Pattern.compile("^" + WikiLanguage.UNICODE.tag("strike") + "(.*)$");
private static final Pattern unstrike = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("strike") + "(.*)$");
private static Pattern getPattern(String line) {
if (bold.matcher(line).find()) {
return bold;
}
if (unbold.matcher(line).find()) {
return unbold;
}
if (italic.matcher(line).find()) {
return italic;
}
if (unitalic.matcher(line).find()) {
return unitalic;
}
return null;
}
public static StripeRow parseUnicode(String line, FontConfiguration fontConfiguration) {
final StripeRow result = new StripeRow();
StringBuilder tmp = new StringBuilder();
while (line.length() > 0) {
final Pattern cmd = getPattern(line);
if (cmd == null) {
tmp.append(line.charAt(0));
line = line.substring(1);
continue;
}
if (tmp.length() > 0) {
result.add(AtomTextUtils.create(tmp.toString(), fontConfiguration));
tmp.setLength(0);
}
final Matcher matcher = cmd.matcher(line);
matcher.find();
if (cmd == bold) {
fontConfiguration = fontConfiguration.bold();
} else if (cmd == unbold) {
fontConfiguration = fontConfiguration.unbold();
} else if (cmd == italic) {
fontConfiguration = fontConfiguration.italic();
} else if (cmd == unitalic) {
fontConfiguration = fontConfiguration.unitalic();
} else if (cmd == strike) {
fontConfiguration = fontConfiguration.add(FontStyle.STRIKE);
} else if (cmd == unstrike) {
fontConfiguration = fontConfiguration.remove(FontStyle.STRIKE);
} else {
throw new IllegalStateException();
}
line = matcher.group(1);
}
assert line.length() == 0;
if (tmp.length() > 0) {
result.add(AtomTextUtils.create(tmp.toString(), fontConfiguration));
}
return result;
}
}

View File

@ -1,110 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
public enum WikiLanguage {
DOKUWIKI, MARKDOWN, ASCIIDOC, MEDIAWIKI, CREOLE, UNICODE, HTML_DEBUG;
public String toString() {
return super.toString().toLowerCase();
}
static class MyChar {
final String unicode;
final String htmlDebug;
MyChar(String unicode, String htmlDebug) {
this.unicode = unicode;
this.htmlDebug = htmlDebug;
}
String toRightSyntax(WikiLanguage lg) {
if (lg == WikiLanguage.UNICODE) {
return "" + unicode;
} else if (lg == WikiLanguage.HTML_DEBUG) {
return "" + htmlDebug;
}
throw new UnsupportedOperationException();
}
public String toHtmlDebug(String s) {
return s.replace(unicode, htmlDebug);
}
}
static public String toHtmlDebug(String s) {
s = START.toHtmlDebug(s);
s = END.toHtmlDebug(s);
s = SEMICOLON.toHtmlDebug(s);
s = EQUALS.toHtmlDebug(s);
s = EOB.toHtmlDebug(s);
return s;
}
private static final MyChar START = new MyChar("\uF800", "<<{{");
private static final MyChar END = new MyChar("\uF802", "<</{{");
private static final MyChar SEMICOLON = new MyChar("\uF810", ";;;");
private static final MyChar EQUALS = new MyChar("\uF811", "===");
private static final MyChar EOB = new MyChar("\uF899", "}}>>");
public static String hideCharsF7(String s) {
final StringBuilder sb = new StringBuilder(s.length());
for (char ch : s.toCharArray()) {
sb.append(toF7(ch));
}
return sb.toString();
}
public static String restoreAllCharsF7AndDoEscapeForBackSlash(String s) {
return restoreAllCharsF7(s);
}
public static String restoreAllCharsF7(String s) {
final StringBuilder sb = new StringBuilder(s.length());
for (char ch : s.toCharArray()) {
if (ch >= '\uF700' && ch <= '\uF7FF') {
ch = (char) (ch - '\uF700');
}
sb.append(ch);
}
return sb.toString();
}
public static char toF7(char ch) {
if (ch < 127) {
return (char) ('\uF700' + ch);
}
return ch;
}
public String slashTag(String tagName) {
final StringBuilder tmp = new StringBuilder();
tmp.append(END.toRightSyntax(this));
tmp.append(tagName);
tmp.append(SEMICOLON.toRightSyntax(this));
tmp.append(EOB.toRightSyntax(this));
return tmp.toString();
}
public String tag(String tagName) {
final StringBuilder tmp = new StringBuilder();
tmp.append(START.toRightSyntax(this));
tmp.append(tagName);
tmp.append(SEMICOLON.toRightSyntax(this));
tmp.append(EOB.toRightSyntax(this));
return tmp.toString();
}
public String tag(String tagName, String name, String value) {
final StringBuilder tmp = new StringBuilder();
tmp.append(START.toRightSyntax(this));
tmp.append(tagName);
tmp.append(SEMICOLON.toRightSyntax(this));
tmp.append(name);
tmp.append(EQUALS.toRightSyntax(this));
tmp.append(value);
tmp.append(SEMICOLON.toRightSyntax(this));
tmp.append(EOB.toRightSyntax(this));
return tmp.toString();
}
}

View File

@ -1,28 +0,0 @@
package net.sourceforge.plantuml.creole.rosetta;
import java.util.ArrayList;
import java.util.List;
public class WriterWiki {
private final WikiLanguage syntaxDestination;
public WriterWiki(WikiLanguage syntaxDestination) {
this.syntaxDestination = syntaxDestination;
if (syntaxDestination != WikiLanguage.HTML_DEBUG && syntaxDestination != WikiLanguage.UNICODE) {
throw new IllegalArgumentException(syntaxDestination.toString());
}
}
public List<String> transform(List<String> data) {
if (syntaxDestination == WikiLanguage.UNICODE) {
return data;
}
final List<String> result = new ArrayList<>();
for (String s : data) {
result.add(WikiLanguage.toHtmlDebug(s));
}
return result;
}
}

View File

@ -166,15 +166,19 @@ public class BodierLikeClassOrObject implements Bodier {
public boolean hasUrl() {
for (CharSequence cs : getFieldsToDisplay()) {
final Member m = (Member) cs;
if (m.hasUrl()) {
return true;
if (cs instanceof Member) {
final Member m = (Member) cs;
if (m.hasUrl()) {
return true;
}
}
}
for (CharSequence cs : getMethodsToDisplay()) {
final Member m = (Member) cs;
if (m.hasUrl()) {
return true;
if (cs instanceof Member) {
final Member m = (Member) cs;
if (m.hasUrl()) {
return true;
}
}
}
return false;

View File

@ -70,28 +70,29 @@ public class PSystemDonors extends PlainDiagram {
private static final int COLS = 6;
private static final int FREE_LINES = 6;
public static final String DONORS = "6wOD0AmFjCllA6nYeh4EstErPvQF9MScYM1vdb2SMCJfBY3-0FTEZ_kDz1VHbTtxfXbHwxL9EOEeFWXw"
public static final String DONORS = "6zeD0AmFjCllA6nYeh4EstErPvQF9MScYM1vdb2SMCJfBY3-0FTEZ_kDz1VHbUvzqunHwxL9EOEeFWXw"
+ "mBlRGljG-byVX3bBNWHtfWGNa0AYEBf4VgGRsKwVL1bIWcUfwEzlcRYztJekL2Q9lX7AWU9-EMJWRVfi"
+ "dft6eD4BL1_-zf1sN_s_gRDrUIY4MRfRWH4O5OrmN5ycSw__erfKE0KxXnfs-Z6Tkg0w7AfLYSssDqMq"
+ "akQEMQ6-dOzQJIwAaLAa-6iZ3RyOJ6ZCoUoJv9T-qVYbRiA7rkeQOjm1n3bJEhfkw-ryF8Zb5qby2F84"
+ "Nr2im1n8ET8lejcvwK73mu6XVXVLsDB2FKzI894DBUJDFugaq7k8iylWfk5L0GA_Tr21P0ngr8Ip0tS3"
+ "Akd15fqQkEfYVs5fMOVbAJsJXgSH2oyBQW4r14aCUa5dz9LRfkvvA1m9UKhYEMqLwi-2Tz0s5_IDBIK1"
+ "wslxgLcIF-AKhOSq7RdF-LTd1xnhoChLRyOSaPoWAIzpGPblBL0_0Zqq9so9xrNkBCGXr4VgfW-TQmwr"
+ "Yd12BYaLw-Hbjhsc_w4hPx914PuE5laz-UjYKnnieQibDS0RMYKqwtm2IGtrzvSyNZhV1TUKIDmR4Mr4"
+ "TWtHVp-tD3CK1-ZWDBEXcoPO1gkqwYYs888zGiS7t2Ga1-5ycbpsf-MNw2q_0V1c4a5ts0WqWT-_k3Ba"
+ "o8KqaAbhqrm0R3sjr8k6poCCAdG8kXLLmkbjxleP9erjoyQMPT8kdhSRZ94Vqt75XUKobyW8mnArQDOV"
+ "rWxHBi5LFaxoglTCSXNWKk4zQkFUlsJ0pZ1d859ikkFnIDjY6UgmcCMUwwKkkgVRoS53jnoucqLpc54c"
+ "3va6WoE9gActYFhGOFYRG5Qprnfqds1hkCuC7cQamUkfoGqrEQRXiPtbEDaYH8QvUCKf8bnGi9Tb9pcw"
+ "bf1onEfnICZlH9z4f4fVA8tOkTnLU4RsACZ3UO-iUjIFAPXSG9KnJH2M5gmvGz0UjXR8m5f5psmRnEwN"
+ "TYoOs_pan8f3yHKJRJTkK305PeOmRXX4eZBGAAKNdoGYyDqVTwidrpgiuxjxMZ4EaXQI2AX2cSxyGJLJ"
+ "Jpr2qrYlyVzjhRqiEt_-jKSsEJNPQ-yXYDP1J00Yl42NSdyGmLFWwys6cO1Jh62Y9mbNhbbw6aXOi8K-"
+ "k8awsMOqRxnORbmkMdj-g9AVvdQuc0s-8ST5E6YVVOaghRtKWuhOlkLTXviS1lukgWoBvB9NpsGaT1Ag"
+ "EBV7RZCLpLXbW1NCWTe4zkx-h4pZAMFkLo1LXYj0ljkG8QdHGmjhQbeH5m9hf7DxRsuRuep-BnZeHxJM"
+ "pxrwQ3p9rVKN4uLlHmZZd4ZYSf5u8CAufUP4Wnw-2I8VL0jbO6d733jti49-Wp_66mb7xE03JZtceZpj"
+ "XHnZ2zaxPu4_8NWFeO4iB5RgLSH2ASS3APA2EQjbB4FQILjmLcy0dQ9W_F_UXd1wela5cLtcrHl9N8wv"
+ "brGGwN1_5ebDIxO6vC2-bBbiwuhSphb8Xvtu7_YEyvsFg5iN4IY1A2N1QpCXtztOfzh4flHShy5nNER5"
+ "mUGNiYlQ-PA1hR7OWYndCr3m902rWqA5oglmg_qJrvmpvDzxzr8OQCBpr6rquxaNJ8iLI_2KDA3c9alW"
+ "slTxRh8uK3ZHsE32KdEZXqazMkPJxRXfivuCAf6xL4pq2BERbgZo4rrFgiiXKxTUKBCajAux4tJosnRa" + "qhLppmip9EnB2W00";
+ "dft6XqOlK0t-zf1sN_tVfRDrULKLfWNThS08Z3gDSAJiDVwFQb575Em4DUpqOpgLgreErQh4PjkR8bf9"
+ "SyUiqD3EHvqc5yLaf4ZnraOANZ6OeIadiq-HN_f5uu-w2HrQgsk8vGuWpfdIe-kstgx7WrX-iSG7mHLy"
+ "GHQ1EP1o95v4otFJZOQB1muDkwZ6bfNSyyGAGIgqa3V_A9AItaCykmnk6curGE3rDWf8ng0cJJZRTpUW"
+ "qXviqQM1gwxr5-RMTLYUoisauGd4mis2Ma0DGUA3Nj0PVUMMoJqFXIqXJqayfwr6_Pbu9srpGT_uKX8m"
+ "NpjFpSp-Y56s7j8uSf_phyuEUDUGbQlVZ3d2EOEwlCm5CTzQe7u4UcnEM1BVK-uif23KH-gc3vrhJseL"
+ "uPHSKYhMwKjiUItt3rrfams9vEbWoNotV5rhYWTRw2ga6dX3gpJDEb_0f8Rw-qiUBPtlWcjAnUuDYpOY"
+ "kuRelvzRcXcA0tHeYjdGJG26iKghpc834UmMEZRW9e4SXF9fSicVbb-Yj_m4m5jA15rXGz8CVlzIyf23"
+ "2p6GgUjIN00idbBgHSFZ0GkLEWJTZYgXz3Pt_GoJbctBni8oQHVFEmt6o8_fbEB2V9bBU8HXgLeqvpwi"
+ "7S0kmRFvECshxZFDLO1BXVUOZMl_ae4ymvmHaQBJ5Oz7sXRpK8TX5cFEIrrqJxUJWuTkFN0sY-OneqmU"
+ "iXmO74v6JRr5w4E3uMyAsHnxhKNr2RQ7w_JWPaOUl9wQt5AJ8neksrcEdIq2aip5AtPHuVo2jImZcQDh"
+ "2P4ZLaz2XlnEzKbOgiI5fWaxbxi6psHw5EJXl2TMFUh757GkeAgO9WX92sRE49I7hGKoi5RHCzS6iVkb"
+ "7GlwDZyvSPP3yMKJxJHkoC8Kc1uYlU4W4ZC7iXAzr2GHm7T_tArUPgr37D_TqufnaBIGn40LcTFfFoWp"
+ "zTOZD8tr5ltVrjhBilFdNsjaarEplVOUWcWT90KWmWjqb0j214-1hpSR9WDEM255Jp9SkMxfUI1XmLRw"
+ "u2RgT9jHl-F5SXDoqThpGvN-DBKeEEiRKbo4WlBPboXfxQKULDJshMySRd8m_5rKcPJ9lRsCfib8-0Ig"
+ "E7V7RZCLzTYi0IAO0vK9ZDtzMPd6KyRShr2g3Cy4ylqM6PAC7bfOKzFAk11OAvtRUolR4C_e_u8H_QZM"
+ "kUTUFJITvEe6YeZ2jod8k22Ik5oa7GYmcsjEFEZc6p_oGRLG1fPspR1p1YlaD_GZl95mp3O-KEGn5ytJ"
+ "NiXXMyZUDGly2S1x20zaOR5Aho8MIZaUI94Kp5ajarcadRG5f_GEe5CKZF_VEn0kDz7yYimky-gDP2xJ"
+ "t8yhY7ouFul4fYLR8t9WFoDpsVOLkLrpaGuxzJ_m7UUx7r6tBoB82iIC97Zj9gIx6tjKczZCU6xGu3Wk"
+ "y-DWyelO5Uq2oS3ML6n1Lh8PAF4a1BL39XLclP9VtHzSSowHV-_TIs6W2Sypjz2Dv_fW5TbQYwUa0JKt"
+ "MNpNlZzm9uiJ2YSU2rnO9cxqCALRotogNJTjDf169NALYl4UPdRJ4YK_qVMakXmokVM2cYMXTTsPeZCu"
+ "jWLpwTgvvuKPNEetKtqcfCT0m_Mb1W00";
/*
* Special thanks to our sponsors and donors:

View File

@ -289,7 +289,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
final HColor borderColor = HColorUtils.BLACK;
decoration.drawU(ug.apply(new UTranslate(corner)), backColor, borderColor, shadowing, roundCorner,
skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false),
skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null),
skinParam.getStereotypeAlignment());
// // Print a simple rectangle right now

View File

@ -67,14 +67,14 @@ public class QuoteUtils {
"Gur obl vf vzcbegnag. Ur unf gb yvir.", "Bapr hcba n gvzr va n tnynkl sne, sne njnl...",
"Naq lbh xabj gurer'f n ybat ybat jnl nurnq bs lbh...", "Na nyyretl gb bkltra? Ryz oyvtug?",
"Ohg nybef lbh ner Serapu!", "A'nv-wr qbap gnag irph dhr cbhe prggr vasnzvr?",
"Fbzrguvat vf ebggra va gur Fgngr bs Qraznex.", "Url, jung qb lbh jnag? Zvenpyrf?",
"1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ", "Jung gur uryy vf n tvtnjngg?", "V arrq n inpngvba.",
"Ba qrienvg wnznvf dhvggre Zbagnhona.", "Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...",
"Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...", "Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag",
"Ornz zr hc, Fpbggl.", "Gurer vf ab fcbba.", "Sbyybj gur juvgr enoovg.",
"Arire fraq n uhzna gb qb n znpuvar'f wbo.", "Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.",
"V qba'g guvax jr'er va Xnafnf nalzber.", "Yhxr, V nz lbhe sngure.", "Oybbq, Fjrng naq Grnef",
"Ubhfgba, jr unir n ceboyrz.", "Xrlobneq snvyher, cerff nal xrl gb pbagvahr", "Ovt zvfgnxr!",
"Url, jung qb lbh jnag? Zvenpyrf?", "1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ",
"Jung gur uryy vf n tvtnjngg?", "V arrq n inpngvba.", "Ba qrienvg wnznvf dhvggre Zbagnhona.",
"Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...", "Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...",
"Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag", "Ornz zr hc, Fpbggl.", "Gurer vf ab fcbba.",
"Sbyybj gur juvgr enoovg.", "Arire fraq n uhzna gb qb n znpuvar'f wbo.",
"Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.", "V qba'g guvax jr'er va Xnafnf nalzber.",
"Yhxr, V nz lbhe sngure.", "Oybbq, Fjrng naq Grnef", "Ubhfgba, jr unir n ceboyrz.",
"Xrlobneq snvyher, cerff nal xrl gb pbagvahr", "Ovt zvfgnxr!",
"Ubj znal HZY qrfvtaref qbrf vg gnxr gb punatr n yvtugohyo ?", "Qb lbh yvxr zbivrf nobhg tynqvngbef ?",
"Gur fcvevg bs yrneavat vf n ynfgvat sebagvre.",
"Vg vf phevbhf sbe fnvybef guvf arrq sbe znxvat fragraprf.", "Ubcvat sbe gur orfg, ohg rkcrpgvat gur jbefg",
@ -295,7 +295,10 @@ public class QuoteUtils {
"V'z shmml ba gur jubyr tbbq/onq guvat. Jung qb lbh zrna, 'onq'?",
"Lbh'er evtug. Ab uhzna orvat jbhyq fgnpx obbxf yvxr guvf.",
"V nz fb pyrire gung fbzrgvzrf V qba'g haqrefgnaq n fvatyr jbeq bs jung V nz fnlvat.",
"Jnxr zr hc orsber lbh tb-tb");
"Jnxr zr hc orsber lbh tb-tb",
"Fbzrguvat vf ebggra va gur fgngr bs Qraznex! Naq, Unzyrg vf gnxvat bhg gur genfu!",
"Bu bhv, cneybaf-ra qrf pbcnvaf, cbhe sbhger yn zreqr vyf fbag punzcvbaf", "Gjb qnlf gb ergverzrag!",
"Gh nf qrf qbvtgf ? Pebvfrf-ra ha znk g'nf vagrerg !");
private QuoteUtils() {
}

View File

@ -0,0 +1,972 @@
/* ========================================================================
* 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.
*
*
* Translated and refactored by: Arnaud Roques
*
*
*/
/*
This is a Java port of https://github.com/asciimath/asciimathml/blob/master/asciimath-based/ASCIIMathTeXImg.js
ASCIIMathTeXImg.js itself is based on ASCIIMathML, Version 1.4.7 Aug 30, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen
Modified with TeX conversion for IMG rendering Sept 6, 2006 (c) David Lippman http://www.pierce.ctc.edu/dlippman
Updated to match ver 2.2 Mar 3, 2014
Latest at https://github.com/mathjax/asciimathml
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package net.sourceforge.plantuml.math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ASCIIMathTeXImg {
private int AMnestingDepth;
private int AMpreviousSymbol;
private int AMcurrentSymbol;
private String slice(String str, int start, int end) {
if (end > str.length()) {
return str.substring(start);
}
return str.substring(start, end);
}
private String slice(String str, int start) {
return str.substring(start);
}
private String substr(String str, int pos, int len) {
if (pos + len > str.length()) {
return str.substring(pos);
}
return str.substring(pos, pos + len);
}
static private final int CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, RIGHTBRACKET = 5, SPACE = 6,
UNDEROVER = 7, DEFINITION = 8, LEFTRIGHT = 9, TEXT = 10; // token types
static class Tupple {
private final String input;
private final String tag;
private final String output;
private final String tex;
private final int ttype;
private final String[] rewriteleftright;
private final Collection<String> flags;
private Tupple(String[] rewriteleftright, String input, String tag, String output, String tex, int ttype,
String... flags) {
this.input = input;
this.tag = tag;
this.output = output;
this.tex = tex;
this.ttype = ttype;
this.flags = Arrays.asList(flags);
this.rewriteleftright = rewriteleftright;
}
private Tupple(String input, String tag, String output, String tex, int ttype, String... flags) {
this.input = input;
this.tag = tag;
this.output = output;
this.tex = tex;
this.ttype = ttype;
this.flags = Arrays.asList(flags);
this.rewriteleftright = null;
}
public boolean hasFlag(String flagName) {
return flags.contains(flagName);
}
}
private static final Tupple AMsqrt = new Tupple("sqrt", "msqrt", "sqrt", null, UNARY);
private static final Tupple AMroot = new Tupple("root", "mroot", "root", null, BINARY);
private static final Tupple AMfrac = new Tupple("frac", "mfrac", "/", null, BINARY);
private static final Tupple AMdiv = new Tupple("/", "mfrac", "/", null, INFIX);
private static final Tupple AMover = new Tupple("stackrel", "mover", "stackrel", null, BINARY);
private static final Tupple AMsub = new Tupple("_", "msub", "_", null, INFIX);
private static final Tupple AMsup = new Tupple("^", "msup", "^", null, INFIX);
private static final Tupple AMtext = new Tupple("text", "mtext", "text", null, TEXT);
private static final Tupple AMmbox = new Tupple("mbox", "mtext", "mbox", null, TEXT);
private static final Tupple AMquote = new Tupple("\"", "mtext", "mbox", null, TEXT);
private static final List<Tupple> AMsymbols = new ArrayList<>(Arrays.asList(new Tupple[] { //
// some greek symbols
new Tupple("alpha", "mi", "\u03B1", null, CONST), //
new Tupple("beta", "mi", "\u03B2", null, CONST), //
new Tupple("chi", "mi", "\u03C7", null, CONST), //
new Tupple("delta", "mi", "\u03B4", null, CONST), //
new Tupple("Delta", "mo", "\u0394", null, CONST), //
new Tupple("epsi", "mi", "\u03B5", "epsilon", CONST), //
new Tupple("varepsilon", "mi", "\u025B", null, CONST), //
new Tupple("eta", "mi", "\u03B7", null, CONST), //
new Tupple("gamma", "mi", "\u03B3", null, CONST), //
new Tupple("Gamma", "mo", "\u0393", null, CONST), //
new Tupple("iota", "mi", "\u03B9", null, CONST), //
new Tupple("kappa", "mi", "\u03BA", null, CONST), //
new Tupple("lambda", "mi", "\u03BB", null, CONST), //
new Tupple("Lambda", "mo", "\u039B", null, CONST), //
new Tupple("lamda", "mi", "lambda", null, DEFINITION), //
new Tupple("Lamda", "mi", "Lambda", null, DEFINITION), //
new Tupple("mu", "mi", "\u03BC", null, CONST), //
new Tupple("nu", "mi", "\u03BD", null, CONST), //
new Tupple("omega", "mi", "\u03C9", null, CONST), //
new Tupple("Omega", "mo", "\u03A9", null, CONST), //
new Tupple("phi", "mi", "\u03C6", null, CONST), //
new Tupple("varphi", "mi", "\u03D5", null, CONST), //
new Tupple("Phi", "mo", "\u03A6", null, CONST), //
new Tupple("pi", "mi", "\u03C0", null, CONST), //
new Tupple("Pi", "mo", "\u03A0", null, CONST), //
new Tupple("psi", "mi", "\u03C8", null, CONST), //
new Tupple("Psi", "mi", "\u03A8", null, CONST), //
new Tupple("rho", "mi", "\u03C1", null, CONST), //
new Tupple("sigma", "mi", "\u03C3", null, CONST), //
new Tupple("Sigma", "mo", "\u03A3", null, CONST), //
new Tupple("tau", "mi", "\u03C4", null, CONST), //
new Tupple("theta", "mi", "\u03B8", null, CONST), //
new Tupple("vartheta", "mi", "\u03D1", null, CONST), //
new Tupple("Theta", "mo", "\u0398", null, CONST), //
new Tupple("upsilon", "mi", "\u03C5", null, CONST), //
new Tupple("xi", "mi", "\u03BE", null, CONST), //
new Tupple("Xi", "mo", "\u039E", null, CONST), //
new Tupple("zeta", "mi", "\u03B6", null, CONST), //
// binary operation symbols
new Tupple("*", "mo", "\u22C5", "cdot", CONST), //
new Tupple("**", "mo", "\u2217", "ast", CONST), //
new Tupple("***", "mo", "\u22C6", "star", CONST), //
new Tupple("//", "mo", "/", "/", CONST, "val", "notexcopy"), //
new Tupple("\\\\", "mo", "\\", "backslash", CONST), //
new Tupple("setminus", "mo", "\\", null, CONST), //
new Tupple("xx", "mo", "\u00D7", "times", CONST), //
new Tupple("|><", "mo", "\u22C9", "ltimes", CONST), //
new Tupple("><|", "mo", "\u22CA", "rtimes", CONST), //
new Tupple("|><|", "mo", "\u22C8", "bowtie", CONST), //
new Tupple("-:", "mo", "\u00F7", "div", CONST), //
new Tupple("divide", "mo", "-:", null, DEFINITION), //
new Tupple("@", "mo", "\u2218", "circ", CONST), //
new Tupple("o+", "mo", "\u2295", "oplus", CONST), //
new Tupple("ox", "mo", "\u2297", "otimes", CONST), //
new Tupple("o.", "mo", "\u2299", "odot", CONST), //
new Tupple("sum", "mo", "\u2211", null, UNDEROVER), //
new Tupple("prod", "mo", "\u220F", null, UNDEROVER), //
new Tupple("^^", "mo", "\u2227", "wedge", CONST), //
new Tupple("^^^", "mo", "\u22C0", "bigwedge", UNDEROVER), //
new Tupple("vv", "mo", "\u2228", "vee", CONST), //
new Tupple("vvv", "mo", "\u22C1", "bigvee", UNDEROVER), //
new Tupple("nn", "mo", "\u2229", "cap", CONST), //
new Tupple("nnn", "mo", "\u22C2", "bigcap", UNDEROVER), //
new Tupple("uu", "mo", "\u222A", "cup", CONST), //
new Tupple("uuu", "mo", "\u22C3", "bigcup", UNDEROVER), //
new Tupple("overset", "mover", "stackrel", null, BINARY), //
new Tupple("underset", "munder", "stackrel", null, BINARY), //
// binary relation symbols
new Tupple("!=", "mo", "\u2260", "ne", CONST), //
new Tupple(":=", "mo", ":=", null, CONST), //
new Tupple("lt", "mo", "<", null, CONST), //
new Tupple("gt", "mo", ">", null, CONST), //
new Tupple("<=", "mo", "\u2264", "le", CONST), //
new Tupple("lt=", "mo", "\u2264", "leq", CONST), //
new Tupple("gt=", "mo", "\u2265", "geq", CONST), //
new Tupple(">=", "mo", "\u2265", "ge", CONST), //
new Tupple("-<", "mo", "\u227A", "prec", CONST), //
new Tupple("-lt", "mo", "\u227A", null, CONST), //
new Tupple(">-", "mo", "\u227B", "succ", CONST), //
new Tupple("-<=", "mo", "\u2AAF", "preceq", CONST), //
new Tupple(">-=", "mo", "\u2AB0", "succeq", CONST), //
new Tupple("in", "mo", "\u2208", null, CONST), //
new Tupple("!in", "mo", "\u2209", "notin", CONST), //
new Tupple("sub", "mo", "\u2282", "subset", CONST), //
new Tupple("sup", "mo", "\u2283", "supset", CONST), //
new Tupple("sube", "mo", "\u2286", "subseteq", CONST), //
new Tupple("supe", "mo", "\u2287", "supseteq", CONST), //
new Tupple("-=", "mo", "\u2261", "equiv", CONST), //
new Tupple("~=", "mo", "\u2245", "stackrel{\\sim}{=}", CONST), //
new Tupple("cong", "mo", "~=", null, DEFINITION), //
new Tupple("~~", "mo", "\u2248", "approx", CONST), //
new Tupple("prop", "mo", "\u221D", "propto", CONST), //
// logical symbols
new Tupple("and", "mtext", "and", null, SPACE), //
new Tupple("or", "mtext", "or", null, SPACE), //
new Tupple("not", "mo", "\u00AC", "neg", CONST), //
new Tupple("=>", "mo", "\u21D2", "Rightarrow", CONST), //
new Tupple("implies", "mo", "=>", null, DEFINITION), //
new Tupple("if", "mo", "if", null, SPACE), //
new Tupple("<=>", "mo", "\u21D4", "Leftrightarrow", CONST), //
new Tupple("iff", "mo", "<=>", null, DEFINITION), //
new Tupple("AA", "mo", "\u2200", "forall", CONST), //
new Tupple("EE", "mo", "\u2203", "exists", CONST), //
new Tupple("_|_", "mo", "\u22A5", "bot", CONST), //
new Tupple("TT", "mo", "\u22A4", "top", CONST), //
new Tupple("|--", "mo", "\u22A2", "vdash", CONST), //
new Tupple("|==", "mo", "\u22A8", "models", CONST), //
// grouping brackets
new Tupple("(", "mo", "(", null, LEFTBRACKET, "val"), //
new Tupple(")", "mo", ")", null, RIGHTBRACKET, "val"), //
new Tupple("[", "mo", "[", null, LEFTBRACKET, "val"), //
new Tupple("]", "mo", "]", null, RIGHTBRACKET, "val"), //
new Tupple("{", "mo", "{", "lbrace", LEFTBRACKET), //
new Tupple("}", "mo", "}", "rbrace", RIGHTBRACKET), //
new Tupple("|", "mo", "|", null, LEFTRIGHT, "val"), //
new Tupple("(:", "mo", "\u2329", "langle", LEFTBRACKET), //
new Tupple(":)", "mo", "\u232A", "rangle", RIGHTBRACKET), //
new Tupple("<<", "mo", "\u2329", "langle", LEFTBRACKET), //
new Tupple(">>", "mo", "\u232A", "rangle", RIGHTBRACKET), //
new Tupple("{:", "mo", "{:", null, LEFTBRACKET, "invisible"), //
new Tupple(":}", "mo", ":}", null, RIGHTBRACKET, "invisible"), //
// miscellaneous symbols
new Tupple("int", "mo", "\u222B", null, CONST), //
new Tupple("dx", "mi", "{:d x:}", null, DEFINITION), //
new Tupple("dy", "mi", "{:d y:}", null, DEFINITION), //
new Tupple("dz", "mi", "{:d z:}", null, DEFINITION), //
new Tupple("dt", "mi", "{:d t:}", null, DEFINITION), //
new Tupple("oint", "mo", "\u222E", null, CONST), //
new Tupple("del", "mo", "\u2202", "partial", CONST), //
new Tupple("grad", "mo", "\u2207", "nabla", CONST), //
new Tupple("+-", "mo", "\u00B1", "pm", CONST), //
new Tupple("O/", "mo", "\u2205", "emptyset", CONST), //
new Tupple("oo", "mo", "\u221E", "infty", CONST), //
new Tupple("aleph", "mo", "\u2135", null, CONST), //
new Tupple("...", "mo", "...", "ldots", CONST), //
new Tupple(":.", "mo", "\u2234", "therefore", CONST), //
new Tupple(":'", "mo", "\u2235", "because", CONST), //
new Tupple("/_", "mo", "\u2220", "angle", CONST), //
new Tupple("/_\\", "mo", "\u25B3", "triangle", CONST), //
new Tupple("\\ ", "mo", "\u00A0", null, CONST, "val"), //
new Tupple("frown", "mo", "\u2322", null, CONST), //
new Tupple("%", "mo", "%", "%", CONST, "notexcopy"), //
new Tupple("quad", "mo", "\u00A0\u00A0", null, CONST), //
new Tupple("qquad", "mo", "\u00A0\u00A0\u00A0\u00A0", null, CONST), //
new Tupple("cdots", "mo", "\u22EF", null, CONST), //
new Tupple("vdots", "mo", "\u22EE", null, CONST), //
new Tupple("ddots", "mo", "\u22F1", null, CONST), //
new Tupple("diamond", "mo", "\u22C4", null, CONST), //
new Tupple("square", "mo", "\u25A1", "boxempty", CONST), //
new Tupple("|__", "mo", "\u230A", "lfloor", CONST), //
new Tupple("__|", "mo", "\u230B", "rfloor", CONST), //
new Tupple("|~", "mo", "\u2308", "lceil", CONST), //
new Tupple("lceiling", "mo", "|~", null, DEFINITION), //
new Tupple("~|", "mo", "\u2309", "rceil", CONST), //
new Tupple("rceiling", "mo", "~|", null, DEFINITION), //
new Tupple("CC", "mo", "\u2102", "mathbb{C}", CONST, "notexcopy"), //
new Tupple("NN", "mo", "\u2115", "mathbb{N}", CONST, "notexcopy"), //
new Tupple("QQ", "mo", "\u211A", "mathbb{Q}", CONST, "notexcopy"), //
new Tupple("RR", "mo", "\u211D", "mathbb{R}", CONST, "notexcopy"), //
new Tupple("ZZ", "mo", "\u2124", "mathbb{Z}", CONST, "notexcopy"), //
new Tupple("f", "mi", "f", null, UNARY, "func", "val"), //
new Tupple("g", "mi", "g", null, UNARY, "func", "val"), //
new Tupple("''", "mo", "''", null, 0, "val"), //
new Tupple("'''", "mo", "'''", null, 0, "val"), //
new Tupple("''''", "mo", "''''", null, 0, "val"), //
// standard functions
new Tupple("lim", "mo", "lim", null, UNDEROVER), //
new Tupple("Lim", "mo", "Lim", null, UNDEROVER), //
new Tupple("sin", "mo", "sin", null, UNARY, "func"), //
new Tupple("cos", "mo", "cos", null, UNARY, "func"), //
new Tupple("tan", "mo", "tan", null, UNARY, "func"), //
new Tupple("arcsin", "mo", "arcsin", null, UNARY, "func"), //
new Tupple("arccos", "mo", "arccos", null, UNARY, "func"), //
new Tupple("arctan", "mo", "arctan", null, UNARY, "func"), //
new Tupple("sinh", "mo", "sinh", null, UNARY, "func"), //
new Tupple("cosh", "mo", "cosh", null, UNARY, "func"), //
new Tupple("tanh", "mo", "tanh", null, UNARY, "func"), //
new Tupple("cot", "mo", "cot", null, UNARY, "func"), //
new Tupple("coth", "mo", "coth", null, UNARY, "func"), //
new Tupple("sech", "mo", "sech", null, UNARY, "func"), //
new Tupple("csch", "mo", "csch", null, UNARY, "func"), //
new Tupple("sec", "mo", "sec", null, UNARY, "func"), //
new Tupple("csc", "mo", "csc", null, UNARY, "func"), //
new Tupple("log", "mo", "log", null, UNARY, "func"), //
new Tupple("ln", "mo", "ln", null, UNARY, "func"), //
new Tupple(new String[] { "|", "|" }, "abs", "mo", "abs", null, UNARY, "notexcopy"), //
new Tupple(new String[] { "\\|", "\\|" }, "norm", "mo", "norm", null, UNARY, "notexcopy"), //
new Tupple(new String[] { "\\lfloor", "\\rfloor" }, "floor", "mo", "floor", null, UNARY, "notexcopy"), //
new Tupple(new String[] { "\\lceil", "\\rceil" }, "ceil", "mo", "ceil", null, UNARY, "notexcopy"), //
new Tupple("Sin", "mo", "sin", null, UNARY, "func"), //
new Tupple("Cos", "mo", "cos", null, UNARY, "func"), //
new Tupple("Tan", "mo", "tan", null, UNARY, "func"), //
new Tupple("Arcsin", "mo", "arcsin", null, UNARY, "func"), //
new Tupple("Arccos", "mo", "arccos", null, UNARY, "func"), //
new Tupple("Arctan", "mo", "arctan", null, UNARY, "func"), //
new Tupple("Sinh", "mo", "sinh", null, UNARY, "func"), //
new Tupple("Sosh", "mo", "cosh", null, UNARY, "func"), //
new Tupple("Tanh", "mo", "tanh", null, UNARY, "func"), //
new Tupple("Cot", "mo", "cot", null, UNARY, "func"), //
new Tupple("Sec", "mo", "sec", null, UNARY, "func"), //
new Tupple("Csc", "mo", "csc", null, UNARY, "func"), //
new Tupple("Log", "mo", "log", null, UNARY, "func"), //
new Tupple("Ln", "mo", "ln", null, UNARY, "func"), //
new Tupple(new String[] { "|", "|" }, "Abs", "mo", "abs", null, UNARY, "notexcopy"), //
new Tupple("det", "mo", "det", null, UNARY, "func"), //
new Tupple("exp", "mo", "exp", null, UNARY, "func"), //
new Tupple("dim", "mo", "dim", null, CONST), //
new Tupple("mod", "mo", "mod", "text{mod}", CONST, "notexcopy"), //
new Tupple("gcd", "mo", "gcd", null, UNARY, "func"), //
new Tupple("lcm", "mo", "lcm", "text{lcm}", UNARY, "func", "notexcopy"), //
new Tupple("lub", "mo", "lub", null, CONST), //
new Tupple("glb", "mo", "glb", null, CONST), //
new Tupple("min", "mo", "min", null, UNDEROVER), //
new Tupple("max", "mo", "max", null, UNDEROVER), //
// arrows
new Tupple("uarr", "mo", "\u2191", "uparrow", CONST), //
new Tupple("darr", "mo", "\u2193", "downarrow", CONST), //
new Tupple("rarr", "mo", "\u2192", "rightarrow", CONST), //
new Tupple("->", "mo", "\u2192", "to", CONST), //
new Tupple(">->", "mo", "\u21A3", "rightarrowtail", CONST), //
new Tupple("->>", "mo", "\u21A0", "twoheadrightarrow", CONST), //
new Tupple(">->>", "mo", "\u2916", "twoheadrightarrowtail", CONST), //
new Tupple("|->", "mo", "\u21A6", "mapsto", CONST), //
new Tupple("larr", "mo", "\u2190", "leftarrow", CONST), //
new Tupple("harr", "mo", "\u2194", "leftrightarrow", CONST), //
new Tupple("rArr", "mo", "\u21D2", "Rightarrow", CONST), //
new Tupple("lArr", "mo", "\u21D0", "Leftarrow", CONST), //
new Tupple("hArr", "mo", "\u21D4", "Leftrightarrow", CONST), //
// commands with argument
AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,
new Tupple("cancel", "menclose", "cancel", null, UNARY), //
new Tupple("Sqrt", "msqrt", "sqrt", null, UNARY), //
new Tupple("hat", "mover", "\u005E", null, UNARY, "acc"), //
new Tupple("bar", "mover", "\u00AF", "overline", UNARY, "acc"), //
new Tupple("vec", "mover", "\u2192", null, UNARY, "acc"), //
new Tupple("tilde", "mover", "~", null, UNARY, "acc"), //
new Tupple("dot", "mover", ".", null, UNARY, "acc"), //
new Tupple("ddot", "mover", "..", null, UNARY, "acc"), //
new Tupple("ul", "munder", "\u0332", "underline", UNARY, "acc"), //
new Tupple("ubrace", "munder", "\u23DF", "underbrace", UNARY, "acc"), //
new Tupple("obrace", "mover", "\u23DE", "overbrace", UNARY, "acc"), //
AMtext, AMmbox, AMquote, //
new Tupple("color", "mstyle", null, null, BINARY), //
} //
));
private static String[] AMnames;
private static void AMinitSymbols() {
int symlen = AMsymbols.size();
for (int i = 0; i < symlen; i++) {
if (AMsymbols.get(i).tex != null && !(AMsymbols.get(i).hasFlag("notexcopy"))) {
Tupple tmp = AMsymbols.get(i).hasFlag("acc")
? new Tupple(AMsymbols.get(i).tex, AMsymbols.get(i).tag, AMsymbols.get(i).output, null,
AMsymbols.get(i).ttype, "acc")
: new Tupple(AMsymbols.get(i).tex, AMsymbols.get(i).tag, AMsymbols.get(i).output, null,
AMsymbols.get(i).ttype);
AMsymbols.add(tmp);
}
}
refreshSymbols();
}
private static void refreshSymbols() {
Collections.sort(AMsymbols, new Comparator<Tupple>() {
public int compare(Tupple o1, Tupple o2) {
return o1.input.compareTo(o2.input);
}
});
AMnames = new String[AMsymbols.size()];
for (int i = 0; i < AMsymbols.size(); i++)
AMnames[i] = AMsymbols.get(i).input;
}
private String AMremoveCharsAndBlanks(String str, int n) {
// remove n characters and any following blanks
String st;
if (str.length() > n && str.charAt(n) == '\\' && str.charAt(n + 1) != '\\' && str.charAt(n + 1) != ' ')
st = slice(str, n + 1);
else
st = slice(str, n);
int i;
for (i = 0; i < st.length() && st.charAt(i) <= 32; i = i + 1)
;
return slice(st, i);
}
private int AMposition(String[] arr, String str, int n) {
// return position >=n where str appears or would be inserted
// assumes arr is sorted
int i = 0;
if (n == 0) {
int h, m;
n = -1;
h = arr.length;
while (n + 1 < h) {
m = (n + h) >> 1;
if (arr[m].compareTo(str) < 0)
n = m;
else
h = m;
}
return h;
} else {
for (i = n; i < arr.length && arr[i].compareTo(str) < 0; i++)
;
}
return i; // i=arr.length || arr[i]>=str
}
private Tupple AMgetSymbol(String str) {
// return maximal initial substring of str that appears in names
// return null if there is none
int k = 0; // new pos
int j = 0; // old pos
int mk = 0; // match pos
String st;
String tagst;
String match = "";
boolean more = true;
for (int i = 1; i <= str.length() && more; i++) {
st = str.substring(0, i); // initial substring of length i
j = k;
k = AMposition(AMnames, st, j);
if (k < AMnames.length && slice(str, 0, AMnames[k].length()).equals(AMnames[k])) {
match = AMnames[k];
mk = k;
i = match.length();
}
more = k < AMnames.length && slice(str, 0, AMnames[k].length()).compareTo(AMnames[k]) >= 0;
}
AMpreviousSymbol = AMcurrentSymbol;
if (match.equals("") == false) {
AMcurrentSymbol = AMsymbols.get(mk).ttype;
return AMsymbols.get(mk);
}
// if str[0] is a digit or - return maxsubstring of digits.digits
AMcurrentSymbol = CONST;
k = 1;
st = slice(str, 0, 1);
boolean integ = true;
while ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0 && k <= str.length()) {
st = slice(str, k, k + 1);
k++;
}
if (st.equals(".")) {
st = slice(str, k, k + 1);
if ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0) {
integ = false;
k++;
while ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0 && k <= str.length()) {
st = slice(str, k, k + 1);
k++;
}
}
}
if ((integ && k > 1) || k > 2) {
st = slice(str, 0, k - 1);
tagst = "mn";
} else {
k = 2;
st = slice(str, 0, 1); // take 1 character
tagst = (("A".compareTo(st) > 0 || st.compareTo("Z") > 0)
&& ("a".compareTo(st) > 0 || st.compareTo("z") > 0) ? "mo" : "mi");
}
if (st.equals("-") && AMpreviousSymbol == INFIX) {
AMcurrentSymbol = INFIX;
return new Tupple(st, tagst, st, null, UNARY, "func", "val");
}
return new Tupple(st, tagst, st, null, CONST, "val"); // added val bit
}
private String AMTremoveBrackets(String node) {
String st;
if (node.charAt(0) == '{' && node.charAt(node.length() - 1) == '}') {
int leftchop = 0;
st = substr(node, 1, 5);
if (st.equals("\\left")) {
st = "" + node.charAt(6);
if (st.equals("(") || st.equals("[") || st.equals("{")) {
leftchop = 7;
} else {
st = substr(node, 6, 7);
if (st.equals("\\lbrace")) {
leftchop = 13;
}
}
} else {
st = "" + node.charAt(1);
if (st.equals("(") || st.equals("[")) {
leftchop = 2;
}
}
if (leftchop > 0) {
st = node.substring(node.length() - 8);
if (st.equals("\\right)}") || st.equals("\\right]}") || st.equals("\\right.}")) {
node = "{" + node.substring(leftchop);
node = node.substring(0, node.length() - 8) + "}";
} else if (st.equals("\\rbrace}")) {
node = "{" + node.substring(leftchop);
node = node.substring(0, node.length() - 14) + "}";
}
}
}
return node;
}
private String AMTgetTeXsymbol(Tupple symb) {
String pre;
if (symb.hasFlag("val")) {
pre = "";
} else {
pre = "\\";
}
if (symb.tex == null) {
// can't remember why this was here. Breaks /delta /Delta to removed
// return (pre+(pre==''?symb.input:symb.input.toLowerCase()));
return (pre + symb.input);
} else {
return (pre + symb.tex);
}
}
private String[] AMTparseSexpr(String str) {
Tupple symbol;
int i;
String node, st;
String newFrag = "";
String result[];
str = AMremoveCharsAndBlanks(str, 0);
symbol = AMgetSymbol(str); // either a token or a bracket or empty
if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {
return new String[] { null, str };
}
if (symbol.ttype == DEFINITION) {
str = symbol.output + AMremoveCharsAndBlanks(str, symbol.input.length());
symbol = AMgetSymbol(str);
}
switch (symbol.ttype) {
case UNDEROVER:
case CONST:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
String texsymbol = AMTgetTeXsymbol(symbol);
if (texsymbol.charAt(0) == '\\' || symbol.tag.equals("mo"))
return new String[] { texsymbol, str };
else {
return new String[] { "{" + texsymbol + "}", str };
}
case LEFTBRACKET: // read (expr+)
AMnestingDepth++;
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseExpr(str, true);
AMnestingDepth--;
int leftchop = 0;
if (substr(result[0], 0, 6).equals("\\right")) {
st = "" + result[0].charAt(6);
if (st.equals(")") || st.equals("]") || st.equals("}")) {
leftchop = 6;
} else if (st == ".") {
leftchop = 7;
} else {
st = substr(result[0], 6, 7);
if (st.equals("\\rbrace")) {
leftchop = 13;
}
}
}
if (leftchop > 0) {
result[0] = result[0].substring(leftchop);
if (symbol.hasFlag("invisible"))
node = "{" + result[0] + "}";
else {
node = "{" + AMTgetTeXsymbol(symbol) + result[0] + "}";
}
} else {
if (symbol.hasFlag("invisible"))
node = "{\\left." + result[0] + "}";
else {
node = "{\\left" + AMTgetTeXsymbol(symbol) + result[0] + "}";
}
}
return new String[] { node, result[1] };
case TEXT:
if (symbol != AMquote)
str = AMremoveCharsAndBlanks(str, symbol.input.length());
if (str.charAt(0) == '{')
i = str.indexOf("}");
else if (str.charAt(0) == '(')
i = str.indexOf(")");
else if (str.charAt(0) == '[')
i = str.indexOf("]");
else if (symbol == AMquote)
i = str.substring(1).indexOf("\"") + 1;
else
i = 0;
if (i == -1)
i = str.length();
st = str.substring(1, i);
if (st.charAt(0) == ' ') {
newFrag = "\\ ";
}
newFrag += "\\text{" + st + "}";
if (st.charAt(st.length() - 1) == ' ') {
newFrag += "\\ ";
}
str = AMremoveCharsAndBlanks(str, i + 1);
return new String[] { newFrag, str };
case UNARY:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseSexpr(str);
if (result[0] == null)
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str };
if (symbol.hasFlag("func")) { // functions hack
st = "" + str.charAt(0);
if (st.equals("^") || st.equals("_") || st.equals("/") || st.equals("|") || st.equals(",")
|| (symbol.input.length() == 1 && symbol.input.matches("\\w") && !st.equals("("))) {
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str };
} else {
node = "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}}";
return new String[] { node, result[1] };
}
}
result[0] = AMTremoveBrackets(result[0]);
if (symbol.input.equals("sqrt")) { // sqrt
return new String[] { "\\sqrt{" + result[0] + "}", result[1] };
} else if (symbol.input.equals("cancel")) { // cancel
return new String[] { "\\cancel{" + result[0] + "}", result[1] };
} else if (symbol.rewriteleftright != null) { // abs, floor, ceil
return new String[] { "{\\left" + symbol.rewriteleftright[0] + result[0] + "\\right"
+ symbol.rewriteleftright[1] + '}', result[1] };
} else if (symbol.hasFlag("acc")) { // accent
return new String[] { AMTgetTeXsymbol(symbol) + "{" + result[0] + "}", result[1] };
} else { // font change command
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}}", result[1] };
}
case BINARY:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseSexpr(str);
if (result[0] == null)
return new String[] { '{' + AMTgetTeXsymbol(symbol) + '}', str };
result[0] = AMTremoveBrackets(result[0]);
String[] result2 = AMTparseSexpr(result[1]);
if (result2[0] == null)
return new String[] { '{' + AMTgetTeXsymbol(symbol) + '}', str };
result2[0] = AMTremoveBrackets(result2[0]);
if (symbol.input.equals("color")) {
newFrag = "{\\color{" + result[0].replaceAll("[\\{\\}]", "") + "}" + result2[0] + "}";
} else if (symbol.input.equals("root")) {
newFrag = "{\\sqrt[" + result[0] + "]{" + result2[0] + "}}";
} else {
newFrag = "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}{" + result2[0] + "}}";
}
return new String[] { newFrag, result2[1] };
case INFIX:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
return new String[] { symbol.output, str };
case SPACE:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
return new String[] { "{\\quad\\text{" + symbol.input + "}\\quad}", str };
case LEFTRIGHT:
AMnestingDepth++;
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseExpr(str, false);
AMnestingDepth--;
st = "" + result[0].charAt(result[0].length() - 1);
if (st.equals("|")) { // its an absolute value subterm
node = "{\\left|" + result[0] + "}";
return new String[] { node, result[1] };
} else { // the "|" is a \mid
node = "{\\mid}";
return new String[] { node, str };
}
default:
// alert("default");
str = AMremoveCharsAndBlanks(str, symbol.input.length());
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str };
}
}
private String[] AMTparseIexpr(String str) {
Tupple symbol, sym1, sym2;
String result[];
String node;
str = AMremoveCharsAndBlanks(str, 0);
sym1 = AMgetSymbol(str);
result = AMTparseSexpr(str);
node = result[0];
str = result[1];
symbol = AMgetSymbol(str);
if (symbol.ttype == INFIX && !symbol.input.equals("/")) {
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseSexpr(str);
if (result[0] == null) // show box in place of missing argument
result[0] = "{}";
else
result[0] = AMTremoveBrackets(result[0]);
str = result[1];
if (symbol.input.equals("_")) {
sym2 = AMgetSymbol(str);
if (sym2.input.equals("^")) {
str = AMremoveCharsAndBlanks(str, sym2.input.length());
String[] res2 = AMTparseSexpr(str);
res2[0] = AMTremoveBrackets(res2[0]);
str = res2[1];
node = "{" + node;
node += "_{" + result[0] + "}";
node += "^{" + res2[0] + "}";
node += "}";
} else {
node += "_{" + result[0] + "}";
}
} else { // must be ^
node = node + "^{" + result[0] + "}";
}
if (sym1.hasFlag("func")) {
sym2 = AMgetSymbol(str);
if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) {
result = AMTparseIexpr(str);
node = "{" + node + result[0] + "}";
str = result[1];
}
}
}
return new String[] { node, str };
}
private String[] AMTparseExpr(String str, boolean rightbracket) {
String result[];
Tupple symbol;
String node;
// var symbol, node, result, i, nodeList = [],
String newFrag = "";
boolean addedright = false;
do {
str = AMremoveCharsAndBlanks(str, 0);
result = AMTparseIexpr(str);
node = result[0];
str = result[1];
symbol = AMgetSymbol(str);
if (symbol.ttype == INFIX && symbol.input.equals("/")) {
str = AMremoveCharsAndBlanks(str, symbol.input.length());
result = AMTparseIexpr(str);
if (result[0] == null) // show box in place of missing argument
result[0] = "{}";
else
result[0] = AMTremoveBrackets(result[0]);
str = result[1];
node = AMTremoveBrackets(node);
node = "\\frac" + "{" + node + "}";
node += "{" + result[0] + "}";
newFrag += node;
symbol = AMgetSymbol(str);
} else if (node != null)
newFrag += node;
} while ((((symbol.ttype != RIGHTBRACKET) && (symbol.ttype != LEFTRIGHT || rightbracket))
|| AMnestingDepth == 0) && (symbol.output == null || symbol.output.equals("") == false));
if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {
int len = newFrag.length();
if (len > 2 && newFrag.charAt(0) == '{' && newFrag.indexOf(',') > 0) {
char right = newFrag.charAt(len - 2);
if (right == ')' || right == ']') {
char left = newFrag.charAt(6);
if ((left == '(' && right == ')' && !symbol.output.equals("}")) || (left == '[' && right == ']')) {
String mxout = "\\begin{matrix}";
List<Integer> pos = new ArrayList<>(); // position of commas
pos.add(0);
boolean matrix = true;
int mxnestingd = 0;
List<List<Integer>> subpos = new ArrayList<>();
subpos.add(new ArrayList<>(Arrays.asList(0)));
int lastsubposstart = 0;
int mxanynestingd = 0;
for (int i = 1; i < len - 1; i++) {
if (newFrag.charAt(i) == left)
mxnestingd++;
if (newFrag.charAt(i) == right) {
mxnestingd--;
if (mxnestingd == 0 && i + 3 < newFrag.length() && newFrag.charAt(i + 2) == ','
&& newFrag.charAt(i + 3) == '{') {
pos.add(i + 2);
lastsubposstart = i + 2;
while (subpos.size() <= lastsubposstart)
subpos.add(null);
subpos.set(lastsubposstart, new ArrayList<>(Arrays.asList(i + 2)));
}
}
if (newFrag.charAt(i) == '[' || newFrag.charAt(i) == '(' || newFrag.charAt(i) == '{') {
mxanynestingd++;
}
if (newFrag.charAt(i) == ']' || newFrag.charAt(i) == ')' || newFrag.charAt(i) == '}') {
mxanynestingd--;
}
if (newFrag.charAt(i) == ',' && mxanynestingd == 1) {
subpos.get(lastsubposstart).add(i);
}
if (mxanynestingd < 0) { // happens at the end of the row
if (lastsubposstart == i + 1) { // if at end of row, skip to next row
i++;
} else { // misformed something - abandon treating as a matrix
matrix = false;
}
}
}
pos.add(len);
int lastmxsubcnt = -1;
if (mxnestingd == 0 && pos.size() > 0 && matrix) {
for (int i = 0; i < pos.size() - 1; i++) {
List<String> subarr = null;
if (i > 0)
mxout += "\\\\";
if (i == 0) {
// var subarr = newFrag.substr(pos[i]+7,pos[i+1]-pos[i]-15).split(',');
if (subpos.get(pos.get(i)).size() == 1) {
subarr = new ArrayList<String>(Arrays.asList(
substr(newFrag, pos.get(i) + 7, pos.get(i + 1) - pos.get(i) - 15)));
} else {
subarr = new ArrayList<String>(Arrays.asList(
newFrag.substring(pos.get(i) + 7, subpos.get(pos.get(i)).get(1))));
for (int j = 2; j < subpos.get(pos.get(i)).size(); j++) {
subarr.add(newFrag.substring(subpos.get(pos.get(i)).get(j - 1) + 1,
subpos.get(pos.get(i)).get(j)));
}
subarr.add(newFrag.substring(
subpos.get(pos.get(i)).get(subpos.get(pos.get(i)).size() - 1) + 1,
pos.get(i + 1) - 8));
}
} else {
// var subarr = newFrag.substr(pos[i]+8,pos[i+1]-pos[i]-16).split(',');
if (subpos.get(pos.get(i)).size() == 1) {
subarr = new ArrayList<String>(Arrays.asList(
substr(newFrag, pos.get(i) + 8, pos.get(i + 1) - pos.get(i) - 16)));
} else {
subarr = new ArrayList<String>(Arrays.asList(
newFrag.substring(pos.get(i) + 8, subpos.get(pos.get(i)).get(1))));
for (int j = 2; j < subpos.get(pos.get(i)).size(); j++) {
subarr.add(newFrag.substring(subpos.get(i).get(j - 1) + 1,
subpos.get(i).get(j)));
}
subarr.add(newFrag.substring(
subpos.get(pos.get(i)).get(subpos.get(pos.get(i)).size() - 1) + 1,
pos.get(i + 1) - 8));
}
}
if (lastmxsubcnt > 0 && subarr.size() != lastmxsubcnt) {
matrix = false;
} else if (lastmxsubcnt == -1) {
lastmxsubcnt = subarr.size();
}
// mxout += subarr.join('&');
for (int z = 0; z < subarr.size(); z++) {
mxout += subarr.get(z);
if (z < subarr.size() - 1)
mxout += "&";
}
}
}
mxout += "\\end{matrix}";
if (matrix) {
newFrag = mxout;
}
}
}
}
str = AMremoveCharsAndBlanks(str, symbol.input.length());
if (!symbol.hasFlag("invisible")) {
node = "\\right" + AMTgetTeXsymbol(symbol);
newFrag += node;
addedright = true;
} else {
newFrag += "\\right.";
addedright = true;
}
}
if (AMnestingDepth > 0 && !addedright) {
newFrag += "\\right."; // adjust for non-matching left brackets
// todo: adjust for non-matching right brackets
}
return new String[] { newFrag, str };
}
private String patchColor(String latex) {
return latex.replace("\\color{", "\\textcolor{");
}
public String getTeX(String asciiMathInput) {
AMnestingDepth = 0;
AMpreviousSymbol = 0;
AMcurrentSymbol = 0;
final String result = AMTparseExpr(asciiMathInput, false)[0];
return patchColor(result);
}
static {
AMinitSymbols();
}
}

View File

@ -37,59 +37,24 @@ package net.sourceforge.plantuml.math;
import java.awt.Color;
import java.awt.geom.Dimension2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import net.sourceforge.plantuml.BackSlash;
import net.sourceforge.plantuml.ugraphic.MutableImage;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
public class AsciiMath implements ScientificEquation {
private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/";
private static String JAVASCRIPT_CODE;
private final LatexBuilder builder;
private final String tex;
static {
try {
final BufferedReader br = new BufferedReader(new InputStreamReader(
AsciiMath.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "ASCIIMathTeXImg.js"), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s);
sb.append(BackSlash.NEWLINE);
}
br.close();
JAVASCRIPT_CODE = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
public AsciiMath(String form) throws ScriptException, NoSuchMethodException {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(JAVASCRIPT_CODE);
final Invocable inv = (Invocable) engine;
this.tex = patchColor((String) inv.invokeFunction("plantuml", form));
this.tex = new ASCIIMathTeXImg().getTeX(form);
this.builder = new LatexBuilder(tex);
}
private String patchColor(String latex) {
return latex.replace("\\color{", "\\textcolor{");
}
public Dimension2D getDimension() {
return builder.getDimension();
}

View File

@ -0,0 +1,113 @@
/* ========================================================================
* 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.math;
import java.awt.Color;
import java.awt.geom.Dimension2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import net.sourceforge.plantuml.BackSlash;
import net.sourceforge.plantuml.ugraphic.MutableImage;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
public class AsciiMathJs implements ScientificEquation {
private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/";
private static String JAVASCRIPT_CODE;
private final LatexBuilder builder;
private final String tex;
static {
try {
final BufferedReader br = new BufferedReader(new InputStreamReader(
AsciiMathJs.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "ASCIIMathTeXImg.js"), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s);
sb.append(BackSlash.NEWLINE);
}
br.close();
JAVASCRIPT_CODE = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
public AsciiMathJs(String form) throws ScriptException, NoSuchMethodException {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(JAVASCRIPT_CODE);
final Invocable inv = (Invocable) engine;
this.tex = patchColor((String) inv.invokeFunction("plantuml", form));
this.builder = new LatexBuilder(tex);
}
private String patchColor(String latex) {
return latex.replace("\\color{", "\\textcolor{");
}
public Dimension2D getDimension() {
return builder.getDimension();
}
public UImageSvg getSvg(double scale, Color foregroundColor, Color backgroundColor)
throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException, InstantiationException, IOException {
return builder.getSvg(scale, foregroundColor, backgroundColor);
}
public MutableImage getImage(Color foregroundColor, Color backgroundColor)
throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
return builder.getImage(foregroundColor, backgroundColor);
}
public String getSource() {
return tex;
}
}

View File

@ -35,6 +35,9 @@
*/
package net.sourceforge.plantuml.math;
import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainImageBuilder;
import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainPngBuilder;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
@ -57,9 +60,6 @@ import net.sourceforge.plantuml.ugraphic.MutableImage;
import net.sourceforge.plantuml.ugraphic.PixelImage;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainImageBuilder;
import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainPngBuilder;
public class ScientificEquationSafe {
private final ScientificEquation equation;

View File

@ -43,6 +43,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -63,6 +64,11 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.nwdiag.legacy.GridTextBlockDecorated;
import net.sourceforge.plantuml.nwdiag.legacy.NServerLegacy;
import net.sourceforge.plantuml.nwdiag.legacy.NetworkLegacy;
import net.sourceforge.plantuml.nwdiag.legacy.NwGroupLegacy;
import net.sourceforge.plantuml.nwdiag.next.NPlayField;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax;
@ -76,10 +82,12 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class NwDiagram extends UmlDiagram {
private boolean initDone;
private final Map<String, Square> squares = new LinkedHashMap<String, Square>();
private final List<Network> networks = new ArrayList<>();
private final List<NwGroup> groups = new ArrayList<>();
private NwGroup currentGroup = null;
private final Map<String, NServerLegacy> servers = new LinkedHashMap<String, NServerLegacy>();
private final List<NetworkLegacy> networks = new ArrayList<>();
private final List<NwGroupLegacy> groups = new ArrayList<>();
private NwGroupLegacy currentGroup = null;
private final NPlayField playField = new NPlayField();
public DiagramDescription getDescription() {
return new DiagramDescription("(Nwdiag)");
@ -93,7 +101,7 @@ public class NwDiagram extends UmlDiagram {
initDone = true;
}
private Network currentNetwork() {
private NetworkLegacy currentNetwork() {
if (networks.size() == 0) {
return null;
}
@ -104,7 +112,7 @@ public class NwDiagram extends UmlDiagram {
if (initDone == false) {
return errorNoInit();
}
currentGroup = new NwGroup(name, currentNetwork());
currentGroup = new NwGroupLegacy(name, currentNetwork());
groups.add(currentGroup);
return CommandExecutionResult.ok();
}
@ -117,8 +125,8 @@ public class NwDiagram extends UmlDiagram {
return CommandExecutionResult.ok();
}
private Network createNetwork(String name) {
final Network network = new Network(name, networks.size());
private NetworkLegacy createNetwork(String name) {
final NetworkLegacy network = new NetworkLegacy(playField.createNewStage(), name, networks.size());
networks.add(network);
return network;
}
@ -127,46 +135,37 @@ public class NwDiagram extends UmlDiagram {
if (initDone == false) {
return errorNoInit();
}
final NServerLegacy element;
if (currentNetwork() == null) {
createNetwork(name1);
addSquare(null, name2, toSet(null));
return CommandExecutionResult.ok();
element = new NServerLegacy(name2, currentNetwork(), this.getSkinParam());
} else {
final Square already = squares.get(name1);
final Network network1 = createNetwork("");
final NServerLegacy already = servers.get(name1);
final NetworkLegacy network1 = createNetwork("");
network1.goInvisible();
if (already != null) {
currentNetwork().addSquare(already, toSet(null));
currentNetwork().addServer(already, toSet(null));
already.connect(currentNetwork(), toSet(null));
}
final Square added = addSquare(null, name2, toSet(null));
added.sameColThan(already);
return CommandExecutionResult.ok();
element = new NServerLegacy(name2, currentNetwork(), this.getSkinParam());
element.sameColThan(already);
}
servers.put(name2, element);
addInternal(element, toSet(null));
return CommandExecutionResult.ok();
}
private Square addSquare(Square element, String name, Map<String, String> props) {
if (element == null) {
element = new Square(name, currentNetwork(), this.getSkinParam());
squares.put(name, element);
}
currentNetwork().addSquare(element, props);
private void addInternal(NServerLegacy server, Map<String, String> props) {
currentNetwork().addServer(Objects.requireNonNull(server), props);
server.connect(currentNetwork(), props);
final String description = props.get("description");
if (description != null) {
element.setDescription(description);
server.setDescription(description);
}
final String shape = props.get("shape");
if (shape != null) {
element.setShape(shape);
server.setShape(shape);
}
return element;
}
public CommandExecutionResult endSomething() {
if (initDone == false) {
return errorNoInit();
}
this.currentGroup = null;
return CommandExecutionResult.ok();
}
public CommandExecutionResult addElement(String name, String definition) {
@ -174,19 +173,35 @@ public class NwDiagram extends UmlDiagram {
return errorNoInit();
}
if (currentGroup != null) {
currentGroup.addElement(name);
currentGroup.addName(name);
}
NServerLegacy server = null;
if (currentNetwork() == null) {
if (currentGroup == null) {
final Network network1 = createNetwork("");
network1.goInvisible();
final Square first = addSquare(null, name, toSet(definition));
first.doNotHaveItsOwnColumn();
if (currentGroup != null) {
return CommandExecutionResult.ok();
}
assert currentGroup == null;
final NetworkLegacy network1 = createNetwork("");
network1.goInvisible();
server = new NServerLegacy(name, currentNetwork(), this.getSkinParam());
servers.put(name, server);
server.doNotHaveItsOwnColumn();
} else {
final Square element = squares.get(name);
addSquare(element, name, toSet(definition));
server = servers.get(name);
if (server == null) {
server = new NServerLegacy(name, currentNetwork(), this.getSkinParam());
servers.put(name, server);
}
}
addInternal(server, toSet(definition));
return CommandExecutionResult.ok();
}
public CommandExecutionResult endSomething() {
if (initDone == false) {
return errorNoInit();
}
this.currentGroup = null;
return CommandExecutionResult.ok();
}
@ -274,7 +289,7 @@ public class NwDiagram extends UmlDiagram {
double deltaX = 0;
double deltaY = 0;
for (int i = 0; i < networks.size(); i++) {
final Network current = networks.get(i);
final NetworkLegacy current = networks.get(i);
final String address = current.getOwnAdress();
final TextBlock desc = toTextBlock(current.getName(), address);
final Dimension2D dim = desc.calculateDimension(stringBounder);
@ -285,7 +300,7 @@ public class NwDiagram extends UmlDiagram {
}
double y = 0;
for (int i = 0; i < networks.size(); i++) {
final Network current = networks.get(i);
final NetworkLegacy current = networks.get(i);
final String address = current.getOwnAdress();
final TextBlock desc = toTextBlock(current.getName(), address);
final Dimension2D dim = desc.calculateDimension(stringBounder);
@ -304,9 +319,9 @@ public class NwDiagram extends UmlDiagram {
}
private Map<Network, String> getLinks(Square element) {
final Map<Network, String> result = new LinkedHashMap<Network, String>();
for (Network network : networks) {
private Map<NetworkLegacy, String> getLinks(NServerLegacy element) {
final Map<NetworkLegacy, String> result = new LinkedHashMap<NetworkLegacy, String>();
for (NetworkLegacy network : networks) {
final String s = network.getAdress(element);
if (s != null) {
result.put(network, s);
@ -316,17 +331,17 @@ public class NwDiagram extends UmlDiagram {
}
private GridTextBlockDecorated buildGrid() {
final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), squares.size(), groups,
final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), servers.size(), groups,
networks, getSkinParam());
for (int i = 0; i < networks.size(); i++) {
final Network current = networks.get(i);
final NetworkLegacy current = networks.get(i);
int j = 0;
for (Map.Entry<String, Square> ent : squares.entrySet()) {
final Square square = ent.getValue();
for (Map.Entry<String, NServerLegacy> ent : servers.entrySet()) {
final NServerLegacy square = ent.getValue();
if (square.getMainNetwork() == current) {
final Map<Network, String> conns = getLinks(square);
final Square sameCol = square.getSameCol();
final Map<NetworkLegacy, String> conns = getLinks(square);
final NServerLegacy sameCol = square.getSameCol();
if (sameCol != null) {
square.setNumCol(sameCol.getNumCol());
} else {
@ -357,7 +372,7 @@ public class NwDiagram extends UmlDiagram {
}
if ("color".equalsIgnoreCase(property)) {
final HColor color = value == null ? null
: NwGroup.colors.getColorOrWhite(getSkinParam().getThemeStyle(), value);
: NwGroupLegacy.colors.getColorOrWhite(getSkinParam().getThemeStyle(), value);
if (currentGroup != null) {
currentGroup.setColor(color);
} else if (currentNetwork() != null) {

View File

@ -0,0 +1,113 @@
/* ========================================================================
* 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.core;
import java.util.LinkedHashMap;
import java.util.Map;
import net.sourceforge.plantuml.ComponentStyle;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.nwdiag.next.NBar;
import net.sourceforge.plantuml.skin.ActorStyle;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class NServer {
private final Map<Network, String> connections = new LinkedHashMap<Network, String>();
private USymbol shape = USymbol.RECTANGLE;
private final String name;
private String description;
private final NBar bar = new NBar();
public void connect(Network network, Map<String, String> props) {
String address = props.get("address");
if (address == null) {
address = "";
}
if (address.length() == 0 && connections.containsKey(network)) {
return;
}
connections.put(network, address);
bar.addStage(network.getNstage());
}
@Override
public final String toString() {
return name;
}
public NServer(String name) {
this.description = name;
this.name = name;
}
protected final FontConfiguration getFontConfiguration() {
final UFont font = UFont.serif(11);
return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
}
public final String getDescription() {
return description;
}
public final void setDescription(String description) {
this.description = description;
}
public final String getName() {
return name;
}
public final void setShape(String shapeName) {
final USymbol shapeFromString = USymbol.fromString(shapeName, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE,
PackageStyle.RECTANGLE);
if (shapeFromString != null) {
this.shape = shapeFromString;
}
}
public final USymbol getShape() {
return shape;
}
public final NBar getBar() {
return bar;
}
}

View File

@ -32,55 +32,29 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
import java.util.LinkedHashMap;
import java.util.Map;
package net.sourceforge.plantuml.nwdiag.core;
import net.sourceforge.plantuml.nwdiag.next.NStage;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class Network {
private final String name;
private final Map<Square, String> localSquare = new LinkedHashMap<Square, String>();
private HColor color;
private boolean visible = true;
private String ownAdress;
private double y;
private boolean fullWidth;
private final int stage;
private final NStage nstage;
@Override
public String toString() {
return name + "(" + stage + ")";
return name;
}
public Network(String name, int stage) {
public Network(NStage nstage, String name) {
this.name = name;
this.stage = stage;
}
public String getAdress(Square element) {
return localSquare.get(element);
}
public void addSquare(Square square, Map<String, String> props) {
String address = props.get("address");
if (address == null) {
address = "";
}
if (address.length() == 0 && localSquare.containsKey(square)) {
return;
}
localSquare.put(square, address);
}
public boolean constainsLocally(String name) {
for (Square square : localSquare.keySet()) {
if (square.getName().equals(name)) {
return true;
}
}
return false;
this.nstage = nstage;
}
public final String getOwnAdress() {
@ -103,7 +77,7 @@ public class Network {
this.color = color;
}
public void goInvisible() {
public final void goInvisible() {
this.visible = false;
}
@ -111,36 +85,6 @@ public class Network {
return visible;
}
public void setFullWidth(boolean fullWidth) {
this.fullWidth = fullWidth;
}
public final boolean isFullWidth() {
return fullWidth;
}
public final int getStage() {
return stage;
}
private double xmin;
private double xmax;
private double y;
public void setMinMax(double xmin, double xmax) {
this.xmin = xmin;
this.xmax = xmax;
}
public final double getXmin() {
return xmin;
}
public final double getXmax() {
return xmax;
}
public final double getY() {
return y;
}
@ -149,4 +93,16 @@ public class Network {
this.y = y;
}
public void setFullWidth(boolean fullWidth) {
this.fullWidth = fullWidth;
}
public final boolean isFullWidth() {
return fullWidth;
}
public final NStage getNstage() {
return nstage;
}
}

View File

@ -0,0 +1,116 @@
/* ========================================================================
* 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.core;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.nwdiag.legacy.NServerLegacy;
import net.sourceforge.plantuml.nwdiag.next.NBox;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class NwGroup {
public static final HColorSet colors = HColorSet.instance();
private final Set<String> names = new HashSet<>();
private final String name;
private HColor color;
private String description;
private NBox nbox;
public final NBox getNbox(Map<String, NServerLegacy> servers) {
if (nbox == null) {
nbox = new NBox();
for (Entry<String, NServerLegacy> ent : servers.entrySet()) {
if (names.contains(ent.getKey())) {
nbox.add(ent.getValue().getBar());
}
}
}
return nbox;
}
public void addName(String name) {
this.names.add(name);
}
@Override
public String toString() {
return name;
}
public NwGroup(String name) {
this.name = name;
}
public final String getName() {
return name;
}
public final HColor getColor() {
return color;
}
public final void setColor(HColor color) {
this.color = color;
}
public final void setDescription(String value) {
this.description = value;
}
public final FontConfiguration getGroupDescriptionFontConfiguration() {
final UFont font = UFont.serif(11);
return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
}
protected final String getDescription() {
return description;
}
public final Set<String> names() {
return Collections.unmodifiableSet(names);
}
}

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
public class Footprint {

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
import java.util.List;
@ -47,10 +47,10 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
public static final int NETWORK_THIN = 5;
private final List<NwGroup> groups;
private final List<Network> networks;
private final List<NwGroupLegacy> groups;
private final List<NetworkLegacy> networks;
public GridTextBlockDecorated(int lines, int cols, List<NwGroup> groups, List<Network> networks,
public GridTextBlockDecorated(int lines, int cols, List<NwGroupLegacy> groups, List<NetworkLegacy> networks,
ISkinParam skinparam) {
super(lines, cols, skinparam);
this.groups = groups;
@ -59,7 +59,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
@Override
protected void drawGrid(UGraphic ug) {
for (NwGroup group : groups) {
for (NwGroupLegacy group : groups) {
drawGroups(ug, group, skinparam);
}
drawNetworkTube(ug);
@ -82,7 +82,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
private void drawGroups(UGraphic ug, NwGroup group, ISkinParam skinParam) {
private void drawGroups(UGraphic ug, NwGroupLegacy group, ISkinParam skinParam) {
final StringBounder stringBounder = ug.getStringBounder();
MinMax size = null;
@ -108,7 +108,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
private boolean isThereALink(int j, Network network) {
private boolean isThereALink(int j, NetworkLegacy network) {
for (int i = 0; i < data.getNbLines(); i++) {
final LinkedElement element = data.get(i, j);
if (element != null && element.isLinkedTo(network)) {
@ -123,7 +123,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
final StringBounder stringBounder = ug.getStringBounder();
double y = 0;
for (int i = 0; i < data.getNbLines(); i++) {
final Network network = getNetwork(i);
final NetworkLegacy network = getNetwork(i);
computeMixMax(data.getLine(i), stringBounder, network);
final URectangle rect = new URectangle(network.getXmax() - network.getXmin(), NETWORK_THIN);
@ -142,7 +142,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
}
private void computeMixMax(LinkedElement line[], StringBounder stringBounder, Network network) {
private void computeMixMax(LinkedElement line[], StringBounder stringBounder, NetworkLegacy network) {
double x = 0;
double xmin = network.isFullWidth() ? 0 : -1;
double xmax = 0;
@ -160,15 +160,15 @@ public class GridTextBlockDecorated extends GridTextBlockSimple {
}
private Network getNetwork(int i) {
private NetworkLegacy getNetwork(int i) {
return networks.get(i);
}
public void checkGroups() {
for (int i = 0; i < groups.size(); i++) {
for (int j = i + 1; j < groups.size(); j++) {
final NwGroup group1 = groups.get(i);
final NwGroup group2 = groups.get(j);
final NwGroupLegacy group1 = groups.get(i);
final NwGroupLegacy group2 = groups.get(j);
if (group1.size() == 0 || group2.size() == 0) {
continue;
}

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
@ -124,7 +124,7 @@ public class GridTextBlockSimple implements TextBlock {
data.set(i, j, value);
}
public Footprint getFootprint(NwGroup group) {
public Footprint getFootprint(NwGroupLegacy group) {
return data.getFootprint(group);
}

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
import java.awt.geom.Dimension2D;
import java.util.Collections;
@ -45,6 +45,7 @@ import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.nwdiag.VerticalLine;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -54,12 +55,12 @@ import net.sourceforge.plantuml.utils.MathUtils;
public class LinkedElement {
private final TextBlock box;
private final Network network;
private final Square square;
private final Map<Network, TextBlock> conns;
private final List<Network> networks;
private final NetworkLegacy network;
private final NServerLegacy square;
private final Map<NetworkLegacy, TextBlock> conns;
private final List<NetworkLegacy> networks;
public LinkedElement(Square square, TextBlock box, Map<Network, TextBlock> conns, List<Network> networks) {
public LinkedElement(NServerLegacy square, TextBlock box, Map<NetworkLegacy, TextBlock> conns, List<NetworkLegacy> networks) {
this.networks = networks;
this.box = box;
this.network = square.getMainNetwork();
@ -67,7 +68,7 @@ public class LinkedElement {
this.conns = conns;
}
public boolean isLinkedTo(Network some) {
public boolean isLinkedTo(NetworkLegacy some) {
return conns.containsKey(some);
}
@ -110,7 +111,7 @@ public class LinkedElement {
final TreeSet<Double> skip = new TreeSet<>();
for (Network n : networks) {
for (NetworkLegacy n : networks) {
if (xstart + xMiddle > n.getXmin() && xstart + xMiddle < n.getXmax())
skip.add(n.getY());
}
@ -129,7 +130,7 @@ public class LinkedElement {
final double seven = 7.0;
double x = xMiddle - (conns.size() - 2) * seven / 2;
boolean first = true;
for (Entry<Network, TextBlock> ent : conns.entrySet()) {
for (Entry<NetworkLegacy, TextBlock> ent : conns.entrySet()) {
if (ent.getKey() == network) {
continue;
}
@ -183,11 +184,11 @@ public class LinkedElement {
return new Dimension2DDouble(width, height);
}
public final Network getNetwork() {
public final NetworkLegacy getNetwork() {
return network;
}
public final Square getElement() {
public final NServerLegacy getElement() {
return square;
}

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
import java.util.LinkedHashMap;
import java.util.List;
@ -40,39 +40,24 @@ import java.util.Map;
import java.util.Map.Entry;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.ComponentStyle;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.skin.ActorStyle;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
import net.sourceforge.plantuml.nwdiag.core.NServer;
public class Square {
public class NServerLegacy extends NServer {
private USymbol shape = USymbol.RECTANGLE;
private final String name;
private String description;
private final Network mainNetwork;
private final NetworkLegacy mainNetwork;
private final ISkinSimple spriteContainer;
private boolean hasItsOwnColumn = true;
private Square sameCol;
private NServerLegacy sameCol;
@Override
public String toString() {
return name;
}
public Square(String name, Network network, ISkinSimple spriteContainer) {
this.description = name;
public NServerLegacy(String name, NetworkLegacy network, ISkinSimple spriteContainer) {
super(name);
this.mainNetwork = network;
this.name = name;
this.spriteContainer = spriteContainer;
}
@ -87,48 +72,23 @@ public class Square {
return Display.getWithNewlines(s).create(getFontConfiguration(), HorizontalAlignment.LEFT, spriteContainer);
}
private FontConfiguration getFontConfiguration() {
final UFont font = UFont.serif(11);
return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
}
public LinkedElement asTextBlock(Map<Network, String> conns, List<Network> networks) {
final Map<Network, TextBlock> conns2 = new LinkedHashMap<Network, TextBlock>();
for (Entry<Network, String> ent : conns.entrySet()) {
public LinkedElement asTextBlock(Map<NetworkLegacy, String> conns, List<NetworkLegacy> networks) {
final Map<NetworkLegacy, TextBlock> conns2 = new LinkedHashMap<NetworkLegacy, TextBlock>();
for (Entry<NetworkLegacy, String> ent : conns.entrySet()) {
conns2.put(ent.getKey(), toTextBlock(ent.getValue()));
}
final SymbolContext symbolContext = new SymbolContext(ColorParam.activityBackground.getDefaultValue(),
ColorParam.activityBorder.getDefaultValue()).withShadow(3);
final TextBlock desc = toTextBlock(description);
final TextBlock box = shape.asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), symbolContext,
HorizontalAlignment.CENTER);
final TextBlock desc = toTextBlock(getDescription());
final TextBlock box = getShape().asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0),
symbolContext, HorizontalAlignment.CENTER);
return new LinkedElement(this, box, conns2, networks);
}
public String getDescription() {
return description;
}
public final Network getMainNetwork() {
public final NetworkLegacy getMainNetwork() {
return mainNetwork;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public final void setShape(String shapeName) {
final USymbol shapeFromString = USymbol.fromString(shapeName, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE,
PackageStyle.RECTANGLE);
if (shapeFromString != null) {
this.shape = shapeFromString;
}
}
public void doNotHaveItsOwnColumn() {
this.hasItsOwnColumn = false;
}
@ -137,11 +97,11 @@ public class Square {
return hasItsOwnColumn;
}
public void sameColThan(Square sameCol) {
public void sameColThan(NServerLegacy sameCol) {
this.sameCol = sameCol;
}
public final Square getSameCol() {
public final NServerLegacy getSameCol() {
return sameCol;
}

View File

@ -0,0 +1,102 @@
/* ========================================================================
* 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.legacy;
import java.util.LinkedHashMap;
import java.util.Map;
import net.sourceforge.plantuml.nwdiag.core.Network;
import net.sourceforge.plantuml.nwdiag.next.NStage;
public class NetworkLegacy extends Network {
private final Map<NServerLegacy, String> localServers = new LinkedHashMap<NServerLegacy, String>();
private final int stage;
@Override
public String toString() {
return super.toString() + "(" + stage + ")";
}
public NetworkLegacy(NStage nstage, String name, int stage) {
super(nstage, name);
this.stage = stage;
}
public String getAdress(NServerLegacy server) {
return localServers.get(server);
}
public void addServer(NServerLegacy server, Map<String, String> props) {
String address = props.get("address");
if (address == null) {
address = "";
}
if (address.length() == 0 && localServers.containsKey(server)) {
return;
}
localServers.put(server, address);
}
public boolean constainsLocally(String name) {
for (NServerLegacy server : localServers.keySet()) {
if (server.getName().equals(name)) {
return true;
}
}
return false;
}
public final int getStage() {
return stage;
}
private double xmin;
private double xmax;
public void setMinMax(double xmin, double xmax) {
this.xmin = xmin;
this.xmax = xmax;
}
public final double getXmin() {
return xmin;
}
public final double getXmax() {
return xmax;
}
}

View File

@ -32,7 +32,7 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
public class NwArray {
@ -74,7 +74,7 @@ public class NwArray {
}
public Footprint getFootprint(NwGroup group) {
public Footprint getFootprint(NwGroupLegacy group) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < getNbLines(); i++) {

View File

@ -32,81 +32,50 @@
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag;
package net.sourceforge.plantuml.nwdiag.legacy;
import java.awt.geom.Dimension2D;
import java.util.HashSet;
import java.util.Set;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.nwdiag.core.NwGroup;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class NwGroup {
public class NwGroupLegacy extends NwGroup {
public static final HColorSet colors = HColorSet.instance();
private final String name;
private final Network network;
private final Set<String> elements = new HashSet<>();
private HColor color;
private String description;
private final NetworkLegacy network;
@Override
public String toString() {
return name + " " + network + " " + elements;
return getName() + " " + network + " " + names();
}
public NwGroup(String name, Network network) {
this.name = name;
public NwGroupLegacy(String name, NetworkLegacy network) {
super(name);
this.network = network;
}
public int size() {
return elements.size();
}
public final String getName() {
return name;
}
public void addElement(String name) {
this.elements.add(name);
return names().size();
}
public boolean matches(LinkedElement tested) {
if (network != null && network != tested.getNetwork()) {
return false;
}
return elements.contains(tested.getElement().getName());
}
public final HColor getColor() {
return color;
}
public final void setColor(HColor color) {
this.color = color;
}
public void setDescription(String value) {
this.description = value;
return names().contains(tested.getElement().getName());
}
public void drawGroup(UGraphic ug, MinMax size, ISkinParam skinParam) {
TextBlock block = null;
Dimension2D blockDim = null;
if (description != null) {
block = Display.getWithNewlines(description).create(getGroupDescriptionFontConfiguration(),
if (getDescription() != null) {
block = Display.getWithNewlines(getDescription()).create(getGroupDescriptionFontConfiguration(),
HorizontalAlignment.LEFT, skinParam);
blockDim = block.calculateDimension(ug.getStringBounder());
final double dy = size.getMinY() - blockDim.getHeight();
@ -123,12 +92,7 @@ public class NwGroup {
}
}
private FontConfiguration getGroupDescriptionFontConfiguration() {
final UFont font = UFont.serif(11);
return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
}
public final Network getNetwork() {
public final NetworkLegacy getNetwork() {
return network;
}

View File

@ -0,0 +1,100 @@
/* ========================================================================
* 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.next;
import java.util.HashSet;
import java.util.Set;
public class BooleanGrid {
private final Set<Integer> burned = new HashSet<>();
private int merge(int x, int y) {
return x + (y << 16);
}
public void burn(int x, int y) {
final boolean added = burned.add(merge(x, y));
if (added == false) {
throw new IllegalArgumentException("Already present");
}
}
public boolean isBurned(int x, int y) {
return burned.contains(merge(x, y));
}
public void burnRect(int x1, int y1, int x2, int y2) {
check(x1, y1, x2, y2);
for (int x = x1; x <= x2; x++)
for (int y = y1; y <= y2; y++)
burn(x, y);
}
public boolean isBurnRect(int x1, int y1, int x2, int y2) {
check(x1, y1, x2, y2);
for (int x = x1; x <= x2; x++)
for (int y = y1; y <= y2; y++)
if (isBurned(x, y))
return true;
return false;
}
private void check(int x1, int y1, int x2, int y2) {
if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0) {
throw new IllegalArgumentException();
}
if (x2 < x1) {
throw new IllegalArgumentException();
}
if (y2 < y1) {
throw new IllegalArgumentException();
}
}
// -----------------
public boolean isSpaceAvailable(Staged element, int x) {
if (isBurnRect(x, element.getStart().getNumber(), x + element.getNWidth() - 1, element.getEnd().getNumber())) {
return false;
}
return true;
}
public void useSpace(Staged element, int x) {
burnRect(x, element.getStart().getNumber(), x + element.getNWidth() - 1, element.getEnd().getNumber());
}
}

View File

@ -0,0 +1,89 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag.next;
import java.util.Objects;
public class NBar implements Staged {
private NBox parent;
private NStage start;
private NStage end;
@Override
public String toString() {
return start + "->" + end;
}
public final NBox getParent() {
return parent;
}
public final void setParent(NBox parent) {
this.parent = parent;
}
@Override
public final NStage getStart() {
return start;
}
@Override
public final NStage getEnd() {
return end;
}
public void addStage(NStage stage) {
Objects.requireNonNull(stage);
if (start == null && end == null) {
this.start = stage;
this.end = stage;
} else {
this.start = NStage.getMin(this.start, stage);
this.end = NStage.getMax(this.end, stage);
}
}
@Override
public int getNWidth() {
return 1;
}
@Override
public boolean contains(NStage stage) {
return stage.compareTo(start) >= 0 && stage.compareTo(end) <= 0;
}
}

View File

@ -0,0 +1,89 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.nwdiag.next;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class NBox implements Staged {
private final List<NBar> bars = new ArrayList<>();
private final NTetris<NBar> tetris = new NTetris<>();
public void add(NBar bar) {
this.bars.add(bar);
this.tetris.add(bar);
}
// public void addAll(NBox other) {
// for (NBar bar : other.bars) {
// add(bar);
// }
// }
@Override
public NStage getStart() {
NStage result = bars.get(0).getStart();
for (int i = 1; i < bars.size(); i++) {
result = NStage.getMin(result, bars.get(i).getStart());
}
return result;
}
@Override
public NStage getEnd() {
NStage result = bars.get(0).getEnd();
for (int i = 1; i < bars.size(); i++) {
result = NStage.getMax(result, bars.get(i).getEnd());
}
return result;
}
@Override
public int getNWidth() {
return tetris.getNWidth();
}
public Map<NBar, Integer> getPositions() {
return tetris.getPositions();
}
@Override
public boolean contains(NStage stage) {
return stage.compareTo(getStart()) >= 0 && stage.compareTo(getEnd()) <= 0;
}
}

View File

@ -0,0 +1,95 @@
/* ========================================================================
* 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.next;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class NPlayField {
private final List<NStage> stages = new ArrayList<>();
private final List<NBar> bars = new ArrayList<>();
private final List<NBox> boxes = new ArrayList<>();
public NStage getStage(int num) {
while (stages.size() <= num) {
stages.add(new NStage(stages.size()));
}
return stages.get(num);
}
public NStage createNewStage() {
return getStage(stages.size());
}
public void add(NBar bar) {
if (bar.getParent() == null) {
final NBox single = new NBox();
single.add(bar);
bar.setParent(single);
boxes.add(bar.getParent());
} else if (boxes.contains(bar.getParent()) == false) {
boxes.add(bar.getParent());
}
}
public Map<NBar, Integer> doLayout() {
final NTetris<NBox> tetris = new NTetris<>();
for (NBox box : boxes) {
tetris.add(box);
}
final Map<NBox, Integer> pos = tetris.getPositions();
final Map<NBar, Integer> result = new HashMap<>();
for (Entry<NBox, Integer> ent : pos.entrySet()) {
final NBox box = ent.getKey();
final int boxPos = ent.getValue();
final Map<NBar, Integer> tmp = box.getPositions();
for (Entry<NBar, Integer> ent2 : tmp.entrySet()) {
result.put(ent2.getKey(), boxPos + ent.getValue());
}
}
return Collections.unmodifiableMap(result);
}
}

View File

@ -0,0 +1,75 @@
/* ========================================================================
* 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.next;
import java.util.Objects;
public class NStage implements Comparable<NStage> {
private final int number;
public NStage(int number) {
this.number = number;
}
@Override
public String toString() {
return "S" + number;
}
@Override
public int compareTo(NStage other) {
return Integer.compare(this.number, other.number);
}
public int getNumber() {
return number;
}
public static NStage getMin(NStage stage1, NStage stage2) {
if (stage1.number < stage2.number) {
return stage1;
}
return stage2;
}
public static NStage getMax(NStage stage1, NStage stage2) {
if (stage1.number > stage2.number) {
return stage1;
}
return stage2;
}
}

View File

@ -0,0 +1,74 @@
/* ========================================================================
* 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.next;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
public class NTetris<S extends Staged> {
private final Map<S, Integer> all = new LinkedHashMap<>();
private final BooleanGrid grid = new BooleanGrid();
public void add(S element) {
int x = 0;
while (true) {
if (grid.isSpaceAvailable(element, x)) {
all.put(element, x);
grid.useSpace(element, x);
return;
}
x++;
if (x > 100) {
throw new IllegalStateException();
}
}
}
public final Map<S, Integer> getPositions() {
return Collections.unmodifiableMap(all);
}
public int getNWidth() {
int max = 0;
for (Entry<S, Integer> ent : all.entrySet()) {
max = Math.max(max, ent.getValue() + ent.getKey().getNWidth());
}
return max;
}
}

View File

@ -30,12 +30,18 @@
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.creole.rosetta;
package net.sourceforge.plantuml.nwdiag.next;
import net.sourceforge.plantuml.ugraphic.UShape;
public interface Staged {
public NStage getStart();
public NStage getEnd();
public int getNWidth();
public boolean contains(NStage stage);
public interface URosetta extends UShape {
}

View File

@ -129,7 +129,7 @@ public class GanttArrow implements UDrawable {
} else {
x1 = getX(source.getAttribute(), getSource(), Direction.RIGHT);
y1 = getSource().getY(stringBounder, Direction.RIGHT);
final double y1b = getDestination().getY(stringBounder);
final double y1b = getDestination().getY(stringBounder).getCurrentValue();
drawLine(ug, x1, y1, x1 + 6, y1, x1 + 6, y1b, x2 - 8, y1b, x2 - 8, y2, x2, y2);
}
} else if (this.atStart == Direction.RIGHT && this.atEnd == Direction.LEFT) {

View File

@ -45,6 +45,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
@ -92,6 +93,9 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.real.RealOrigin;
import net.sourceforge.plantuml.real.RealUtils;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
@ -129,6 +133,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private PrintScale printScale = PrintScale.DAILY;
private double factorScale = 1.0;
private Locale locale = Locale.ENGLISH;
private Day today;
private double totalHeightWithoutFooter;
@ -138,6 +143,13 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private Day printStart;
private Day printEnd;
private final RealOrigin origin = RealUtils.createOrigin();
public CommandExecutionResult changeLanguage(String lang) {
this.locale = new Locale(lang);
return CommandExecutionResult.ok();
}
public DiagramDescription getDescription() {
return new DiagramDescription("(Project)");
}
@ -236,10 +248,13 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (HColorUtils.isTransparent(back) == false) {
final URectangle rect1 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(),
timeHeader.getTimeHeaderHeight());
final URectangle rect2 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(),
timeHeader.getTimeFooterHeight());
ug.apply(back.bg()).draw(rect1);
ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2);
if (showFootbox) {
final URectangle rect2 = new URectangle(
calculateDimension(ug.getStringBounder()).getWidth(),
timeHeader.getTimeFooterHeight());
ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2);
}
}
timeHeader.drawTimeHeader(ug, totalHeightWithoutFooter);
@ -300,25 +315,28 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private TimeHeader getTimeHeader() {
if (openClose.getCalendar() == null) {
return new TimeHeaderSimple(getFactorScale(), min, max, getClosedStyle(), getIHtmlColorSet(),
getSkinParam().getThemeStyle());
return new TimeHeaderSimple(getTimelineStyle(), getClosedStyle(), getFactorScale(), min, max,
getIHtmlColorSet(), getSkinParam().getThemeStyle());
} else if (printScale == PrintScale.DAILY) {
return new TimeHeaderDaily(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(),
colorDaysOfWeek, nameDays, printStart, printEnd, getClosedStyle(), getIHtmlColorSet(),
getSkinParam().getThemeStyle());
return new TimeHeaderDaily(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(),
openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, nameDays, printStart,
printEnd, getIHtmlColorSet(), getSkinParam().getThemeStyle());
} else if (printScale == PrintScale.WEEKLY) {
return new TimeHeaderWeekly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(),
colorDaysOfWeek, weekNumberStrategy, getClosedStyle(), getIHtmlColorSet(),
getSkinParam().getThemeStyle());
return new TimeHeaderWeekly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(),
openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, weekNumberStrategy,
getIHtmlColorSet(), getSkinParam().getThemeStyle());
} else if (printScale == PrintScale.MONTHLY) {
return new TimeHeaderMonthly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(),
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle());
return new TimeHeaderMonthly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(),
openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
} else if (printScale == PrintScale.QUARTERLY) {
return new TimeHeaderQuarterly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(),
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle());
return new TimeHeaderQuarterly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(),
openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
} else if (printScale == PrintScale.YEARLY) {
return new TimeHeaderYearly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(),
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle());
return new TimeHeaderYearly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(),
openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
} else {
throw new IllegalStateException();
}
@ -334,6 +352,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
.getMergedStyle(getCurrentStyleBuilder());
}
private Style getTimelineStyle() {
return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.timeline)
.getMergedStyle(getCurrentStyleBuilder());
}
private double getTotalHeight(TimeHeader timeHeader) {
if (showFootbox) {
return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight();
@ -347,7 +370,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
continue;
}
final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()));
final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue());
draw.drawU(ug.apply(move));
}
}
@ -372,7 +395,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
continue;
}
final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()));
final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue());
draw.drawTitle(ug.apply(move), labelStrategy, colTitles, colBars);
}
}
@ -398,7 +421,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
}
private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight, StringBounder stringBounder) {
double y = headerHeight;
Real y = origin.addFixed(headerHeight);
for (Task task : tasks.values()) {
final TaskDraw draw;
if (task instanceof TaskSeparator) {
@ -419,22 +442,23 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote());
}
if (task.getRow() == null) {
y += draw.getFullHeightTask(stringBounder);
y = y.addAtLeast(draw.getFullHeightTask(stringBounder));
}
draws.put(task, draw);
}
while (magicPushOnce(stringBounder)) {
//
}
if (lastY(stringBounder) != 0) {
y = lastY(stringBounder);
origin.compileNow();
magicPush(stringBounder);
double yy = lastY(stringBounder);
if (yy == 0) {
yy = headerHeight;
} else {
for (Resource res : resources.values()) {
final ResourceDraw draw = new ResourceDraw(this, res, timeScale, y, min, max);
final ResourceDraw draw = new ResourceDraw(this, res, timeScale, yy, min, max);
res.setTaskDraw(draw);
y += draw.getHeight();
yy += draw.getHeight();
}
}
this.totalHeightWithoutFooter = y;
this.totalHeightWithoutFooter = yy;
}
private Collection<GanttConstraint> getConstraints(Task task) {
@ -450,46 +474,33 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private double lastY(StringBounder stringBounder) {
double result = 0;
for (TaskDraw td : draws.values()) {
result = Math.max(result, td.getY(stringBounder) + td.getHeightMax(stringBounder));
result = Math.max(result, td.getY(stringBounder).getCurrentValue() + td.getHeightMax(stringBounder));
}
return result;
}
private boolean magicPushOnce(StringBounder stringBounder) {
final List<FingerPrint> notes = new ArrayList<>();
private void magicPush(StringBounder stringBounder) {
final List<TaskDraw> notes = new ArrayList<>();
for (TaskDraw td : draws.values()) {
final FingerPrint taskPrint = td.getFingerPrint(stringBounder);
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 (td.getTrueRow() == null)
for (TaskDraw note : notes) {
final FingerPrint otherNote = note.getFingerPrintNote(stringBounder);
final double deltaY = otherNote.overlap(taskPrint);
if (deltaY > 0) {
final Real bottom = note.getY(stringBounder).addAtLeast(note.getHeightMax(stringBounder));
td.getY(stringBounder).ensureBiggerThan(bottom);
origin.compileNow();
}
}
if (fingerPrintNote != null) {
notes.add(fingerPrintNote);
notes.add(td);
}
}
return false;
}
private void pushIncluding(TaskDraw first, double deltaY) {
boolean skipping = true;
if (first.getTrueRow() != null) {
first = first.getTrueRow();
}
for (TaskDraw td : draws.values()) {
if (td == first) {
skipping = false;
}
if (skipping) {
continue;
}
td.pushMe(deltaY + 1);
}
}
private Day getStart(final TaskImpl tmp) {

View File

@ -51,6 +51,7 @@ import net.sourceforge.plantuml.project.command.CommandFootbox;
import net.sourceforge.plantuml.project.command.CommandGanttArrow;
import net.sourceforge.plantuml.project.command.CommandGanttArrow2;
import net.sourceforge.plantuml.project.command.CommandLabelOnColumn;
import net.sourceforge.plantuml.project.command.CommandLanguage;
import net.sourceforge.plantuml.project.command.CommandNoteBottom;
import net.sourceforge.plantuml.project.command.CommandPage;
import net.sourceforge.plantuml.project.command.CommandPrintBetween;
@ -103,6 +104,7 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandSeparator());
cmds.add(new CommandWeekNumberStrategy());
cmds.add(new CommandLanguage());
cmds.add(new CommandPrintScale());
cmds.add(new CommandPrintBetween());
cmds.add(new CommandPage());

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.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.PrintScale;
public class CommandLanguage extends SingleLineCommand2<GanttDiagram> {
public CommandLanguage() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandLanguage.class.getName(), RegexLeaf.start(), //
new RegexLeaf("language"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("LANG", "(\\w+)"), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
return diagram.changeLanguage(arg.get("LANG", 0));
}
}

View File

@ -78,7 +78,7 @@ public class CommandPrintScale extends SingleLineCommand2<GanttDiagram> {
final String scaleString = arg.get("SCALE", 0);
final PrintScale scale = PrintScale.fromString(scaleString);
diagram.setPrintScale(scale);
final String zoom = arg.get("ZOOM", 0);
if (zoom != null) {
diagram.setFactorScale(Double.parseDouble(zoom));

View File

@ -47,6 +47,7 @@ import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
@ -62,7 +63,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
protected Url url;
protected Display note;
protected final TimeScale timeScale;
private double y;
private Real y;
protected final String prettyDisplay;
protected final Day start;
private final StyleBuilder styleBuilder;
@ -82,7 +83,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
this.note = note;
}
public AbstractTaskDraw(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam,
public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) {
this.y = y;
this.colorSet = colorSet;
@ -133,29 +134,25 @@ public abstract class AbstractTaskDraw implements TaskDraw {
return toTaskDraw.getTaskDraw(task.getRow());
}
final public double getY(StringBounder stringBounder) {
@Override
final public Real getY(StringBounder stringBounder) {
if (task.getRow() == null) {
return y;
}
return getTrueRow().getY(stringBounder);
}
public void pushMe(double deltaY) {
if (task.getRow() == null) {
this.y += deltaY;
}
}
public final Task getTask() {
return task;
}
@Override
public final double getY(StringBounder stringBounder, Direction direction) {
final Style style = getStyle();
final ClockwiseTopRightBottomLeft margin = style.getMargin();
final ClockwiseTopRightBottomLeft padding = style.getPadding();
final double y1 = margin.getTop() + getY(stringBounder);
final double y1 = margin.getTop() + getY(stringBounder).getCurrentValue();
final double y2 = y1 + getShapeHeight(stringBounder);
if (direction == Direction.UP) {

View File

@ -70,17 +70,17 @@ public class RectangleTask {
ug.apply(UTranslate.dy(height)).draw(hline);
}
private void drawRect(UGraphic ug, int completion, HColor documentBackground, double width, double height) {
if (completion == 100 || completion == 0) {
if (completion == 0)
private void drawRect(double widthCompletion, UGraphic ug, HColor documentBackground, double width, double height) {
if (widthCompletion == -1 || widthCompletion == 0) {
if (widthCompletion == 0)
ug = ug.apply(documentBackground.bg());
final URectangle rect = new URectangle(width, height);
ug.draw(rect);
} else {
final URectangle rect1 = new URectangle(width * completion / 100, height);
final URectangle rect1 = new URectangle(widthCompletion, height);
ug.draw(rect1);
final URectangle rect2 = new URectangle(width * (100 - completion) / 100, height);
ug.apply(documentBackground.bg()).apply(UTranslate.dx(width * completion / 100)).draw(rect2);
final URectangle rect2 = new URectangle(width - widthCompletion, height);
ug.apply(documentBackground.bg()).apply(UTranslate.dx(widthCompletion)).draw(rect2);
}
}
@ -129,7 +129,7 @@ public class RectangleTask {
for (int i = 1; i < segments.size() - 1; i++) {
final Segment segment = segments.get(i);
drawPartly(ug, segment, height, documentBackground, i);
drawPartly(segment.getLength() * completion / 100, ug, segment, height, documentBackground, i);
}
final Segment last = segments.get(segments.size() - 1);
@ -142,9 +142,24 @@ public class RectangleTask {
boolean oddEnd) {
final ULine vline = ULine.vline(height);
final double sum = getFullSegmentsLength();
final double lim = completion == 100 ? sum : sum * completion / 100;
double current = 0;
for (int i = 0; i < segments.size(); i++) {
final Segment segment = segments.get(i);
drawPartly(ug, segment, height, documentBackground, i);
final double next = current + segment.getLength();
final double widthCompletion;
if (lim >= next)
widthCompletion = -1;
else if (current >= lim)
widthCompletion = 0;
else {
assert current < lim && lim < next;
widthCompletion = lim - current;
}
drawPartly(widthCompletion, ug, segment, height, documentBackground, i);
if (!oddStart && i == 0) {
ug.apply(UTranslate.dx(segment.getPos1())).draw(vline);
@ -152,10 +167,18 @@ public class RectangleTask {
if (!oddEnd && i == segments.size() - 1) {
ug.apply(UTranslate.dx(segment.getPos2())).draw(vline);
}
current = next;
}
drawIntermediateDotted(ug, height);
}
private double getFullSegmentsLength() {
double result = 0;
for (Segment seg : segments)
result += seg.getLength();
return result;
}
private void drawIntermediateDotted(UGraphic ug, double height) {
ug = ug.apply(new UStroke(2, 3, 1));
for (int i = 0; i < segments.size() - 1; i++) {
@ -167,14 +190,15 @@ public class RectangleTask {
}
}
private void drawPartly(UGraphic ug, final Segment segment, double height, HColor documentBackground, int i) {
private void drawPartly(double widthCompletion, UGraphic ug, final Segment segment, double height,
HColor documentBackground, int i) {
double width = segment.getLength();
if (i != segments.size() - 1) {
width++;
}
if (width > 0) {
drawRect(ug.apply(new HColorNone()).apply(UTranslate.dx(segment.getPos1())), completion, documentBackground,
width, height);
drawRect(widthCompletion, ug.apply(new HColorNone()).apply(UTranslate.dx(segment.getPos1())),
documentBackground, width, height);
}
double pos1 = segment.getPos1();

View File

@ -44,6 +44,7 @@ import net.sourceforge.plantuml.project.LabelStrategy;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.ugraphic.UGraphic;
public interface TaskDraw extends UDrawable {
@ -52,12 +53,10 @@ public interface TaskDraw extends UDrawable {
public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note);
public double getY(StringBounder stringBounder);
public Real getY(StringBounder stringBounder);
public double getY(StringBounder stringBounder, Direction direction);
public void pushMe(double deltaY);
public void drawTitle(UGraphic ug, LabelStrategy labelStrategy, double colTitles, double colBars);
public double getTitleWidth(StringBounder stringBounder);

View File

@ -49,6 +49,7 @@ import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
@ -62,7 +63,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class TaskDrawDiamond extends AbstractTaskDraw {
public TaskDrawDiamond(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam,
public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet);
}
@ -72,6 +73,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.milestone);
}
@Override
public double getHeightMax(StringBounder stringBounder) {
return getFullHeightTask(stringBounder);
}
@ -127,6 +129,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
new SpriteContainerEmpty());
}
@Override
public void drawU(UGraphic ug) {
final Style style = getStyle();
@ -151,14 +154,17 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
ug.draw(getDiamond(ug.getStringBounder()));
}
@Override
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
@Override
public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getFullHeightTask(stringBounder);
final double startPos = timeScale.getStartingPosition(start);
return new FingerPrint(startPos, getY(stringBounder), startPos + h, getY(stringBounder) + h);
return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), startPos + h,
getY(stringBounder).getCurrentValue() + h);
}
private UShape getDiamond(StringBounder stringBounder) {
@ -171,6 +177,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
return result;
}
@Override
public double getX1(TaskAttribute taskAttribute) {
final double x1 = timeScale.getStartingPosition(start);
final double x2 = timeScale.getEndingPosition(start);
@ -179,6 +186,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
return x1 + delta;
}
@Override
public double getX2(TaskAttribute taskAttribute) {
final double x1 = timeScale.getStartingPosition(start);
final double x2 = timeScale.getEndingPosition(start);

View File

@ -60,6 +60,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskImpl;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.sequencediagram.graphic.Segment;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName;
@ -89,7 +90,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
// private final double margin = 2;
public TaskDrawRegular(TimeScale timeScale, double y, String prettyDisplay, Day start, Day end, boolean oddStart,
public TaskDrawRegular(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, boolean oddStart,
boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw,
Collection<GanttConstraint> constraints, StyleBuilder styleBuilder, HColorSet colorSet) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet);
@ -227,7 +228,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
final double h = getFullHeightTask(stringBounder);
final double startPos = timeScale.getStartingPosition(start);
final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, getY(stringBounder), endPos - startPos, h);
return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), endPos - startPos, h);
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
@ -237,8 +238,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
final Dimension2D dim = getOpaleNote().calculateDimension(stringBounder);
final double startPos = timeScale.getStartingPosition(start);
// final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, getY(stringBounder) + getYNotePosition(stringBounder), dim.getWidth(),
dim.getHeight());
return new FingerPrint(startPos, getY(stringBounder).getCurrentValue() + getYNotePosition(stringBounder),
dim.getWidth(), dim.getHeight());
}
private UGraphic applyColors(UGraphic ug) {

View File

@ -50,6 +50,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
@ -67,14 +68,14 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TaskDrawSeparator implements TaskDraw {
private final TimeScale timeScale;
private double y;
private Real y;
private final Day min;
private final Day max;
private final String name;
private final StyleBuilder styleBuilder;
private final HColorSet colorSet;
public TaskDrawSeparator(String name, TimeScale timeScale, double y, Day min, Day max, StyleBuilder styleBuilder,
public TaskDrawSeparator(String name, TimeScale timeScale, Real y, Day min, Day max, StyleBuilder styleBuilder,
HColorSet colorSet) {
this.styleBuilder = styleBuilder;
this.colorSet = colorSet;
@ -126,6 +127,7 @@ public class TaskDrawSeparator implements TaskDraw {
return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), colorSet);
}
@Override
public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
final double widthTitle = getTitle().calculateDimension(stringBounder).getWidth();
@ -168,12 +170,20 @@ public class TaskDrawSeparator implements TaskDraw {
}
}
@Override
public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getFullHeightTask(stringBounder);
final double end = timeScale.getEndingPosition(max);
return new FingerPrint(0, y, end, y + h);
return new FingerPrint(0, getY(stringBounder).getCurrentValue(), end,
getY(stringBounder).getCurrentValue() + h);
}
@Override
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
@Override
public double getFullHeightTask(StringBounder stringBounder) {
final ClockwiseTopRightBottomLeft padding = getStyle().getPadding();
final ClockwiseTopRightBottomLeft margin = getStyle().getMargin();
@ -185,41 +195,41 @@ public class TaskDrawSeparator implements TaskDraw {
return getTitle().calculateDimension(stringBounder).getHeight();
}
public double getY(StringBounder stringBounder) {
@Override
public Real getY(StringBounder stringBounder) {
return y;
}
public void pushMe(double deltaY) {
this.y += deltaY;
}
@Override
public TaskDraw getTrueRow() {
return null;
}
@Override
public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note) {
}
@Override
public Task getTask() {
throw new UnsupportedOperationException();
}
@Override
public double getY(StringBounder stringBounder, Direction direction) {
throw new UnsupportedOperationException();
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
@Override
public double getHeightMax(StringBounder stringBounder) {
return getFullHeightTask(stringBounder);
}
@Override
public double getX1(TaskAttribute taskAttribute) {
throw new UnsupportedOperationException();
}
@Override
public double getX2(TaskAttribute taskAttribute) {
throw new UnsupportedOperationException();
}

View File

@ -68,28 +68,40 @@ public abstract class TimeHeader {
}
private final TimeScale timeScale;
private final Style style;
private final Style closedStyle;
private final Style timelineStyle;
private final HColorSet colorSet;
private final ThemeStyle themeStyle;
protected final Day min;
protected final Day max;
public TimeHeader(Day min, Day max, TimeScale timeScale, Style style, HColorSet colorSet, ThemeStyle themeStyle) {
public TimeHeader(Style timelineStyle, Style closedStyle, Day min, Day max, TimeScale timeScale, HColorSet colorSet,
ThemeStyle themeStyle) {
this.timeScale = timeScale;
this.min = min;
this.max = max;
this.style = Objects.requireNonNull(style);
this.closedStyle = Objects.requireNonNull(closedStyle);
this.timelineStyle = Objects.requireNonNull(timelineStyle);
this.colorSet = colorSet;
this.themeStyle = themeStyle;
}
protected final HColor closedBackgroundColor() {
return style.value(PName.BackGroundColor).asColor(themeStyle, colorSet);
return closedStyle.value(PName.BackGroundColor).asColor(themeStyle, colorSet);
}
protected final HColor closedFontColor() {
return style.value(PName.FontColor).asColor(themeStyle, colorSet);
return closedStyle.value(PName.FontColor).asColor(themeStyle, colorSet);
}
protected final HColor openFontColor() {
return timelineStyle.value(PName.FontColor).asColor(themeStyle, colorSet);
}
protected final HColor getBarColor() {
return timelineStyle.value(PName.LineColor).asColor(themeStyle, colorSet);
}
public abstract double getTimeHeaderHeight();
@ -106,7 +118,12 @@ public abstract class TimeHeader {
final double xmin = getTimeScale().getStartingPosition(min);
final double xmax = getTimeScale().getEndingPosition(max);
final ULine hline = ULine.hline(xmax - xmin);
ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dy(y)).draw(hline);
ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline);
}
protected final void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(getBarColor()).apply(new UTranslate(x, y1)).draw(vbar);
}
final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) {

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -52,11 +53,13 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
protected final LoadPlanable defaultPlan;
protected final Map<Day, HColor> colorDays;
protected final Map<DayOfWeek, HColor> colorDaysOfWeek;
protected final Locale locale;
public TimeHeaderCalendar(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek, TimeScale timeScale, Style style, HColorSet colorSet,
ThemeStyle themeStyle) {
super(min, max, timeScale, style, colorSet, themeStyle);
public TimeHeaderCalendar(Locale locale, Style timelineStyle, Style closedStyle, Day calendar, Day min, Day max,
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
TimeScale timeScale, HColorSet colorSet, ThemeStyle themeStyle) {
super(timelineStyle, closedStyle, min, max, timeScale, colorSet, themeStyle);
this.locale = locale;
this.defaultPlan = defaultPlan;
this.colorDays = colorDays;
this.colorDaysOfWeek = colorDaysOfWeek;

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleDaily;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -65,11 +65,11 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
private final Map<Day, String> nameDays;
public TimeHeaderDaily(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Map<Day, String> nameDays,
Day printStart, Day printEnd, Style style, HColorSet colorSet, ThemeStyle themeStyle) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleDaily(scale, calendar, printStart), style, colorSet, themeStyle);
public TimeHeaderDaily(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min,
Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
Map<Day, String> nameDays, Day printStart, Day printEnd, HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleDaily(scale, calendar, printStart), colorSet, themeStyle);
this.nameDays = nameDays;
}
@ -79,12 +79,38 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
drawTextsDayOfWeek(ug.apply(UTranslate.dy(Y_POS_ROW16())));
drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28())));
drawMonths(ug);
drawVBars(ug, totalHeightWithoutFooter);
drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0,
totalHeightWithoutFooter + getTimeFooterHeight());
printSmallVbars(ug, totalHeightWithoutFooter);
// drawVBars(ug, totalHeightWithoutFooter);
// drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0,
// totalHeightWithoutFooter + getTimeFooterHeight());
printNamedDays(ug);
drawHline(ug, 0);
drawHline(ug, getFullHeaderHeight());
drawHline(ug, totalHeightWithoutFooter);
// drawHline(ug, 0);
// drawHline(ug, getFullHeaderHeight());
}
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter);
}
drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter);
}
private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) {
MonthYear last = null;
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
double startingY = getFullHeaderHeight();
double len = totalHeightWithoutFooter;
if (wink.monthYear().equals(last) == false) {
startingY = 0;
last = wink.monthYear();
len += 24 + 13;
}
drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len);
}
}
@Override
@ -92,8 +118,8 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
drawTextDayOfMonth(ug.apply(UTranslate.dy(12)));
drawTextsDayOfWeek(ug);
drawMonths(ug.apply(UTranslate.dy(24)));
drawHline(ug, 0);
drawHline(ug, getTimeFooterHeight());
// drawHline(ug, 0);
// drawHline(ug, getTimeFooterHeight());
}
private void drawTextsDayOfWeek(UGraphic ug) {
@ -101,7 +127,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
final HColor textColor = getTextBackColor(wink);
printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(), 10, false, textColor), x1, x2);
printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale), 10, false, textColor), x1, x2);
}
}
@ -118,7 +144,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
if (defaultPlan.getLoadAt(wink) <= 0) {
return closedFontColor();
}
return HColorUtils.BLACK;
return openFontColor();
}
private void drawMonths(final UGraphic ug) {
@ -140,32 +166,13 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
}
}
private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) {
MonthYear last = null;
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
double startingY = getFullHeaderHeight();
double len = totalHeightWithoutFooter;
if (wink.monthYear().equals(last) == false) {
startingY = 0;
last = wink.monthYear();
len += 24 + 13;
}
drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len);
}
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock tiny = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock(monthYear.longName(), 12, true, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.longNameYYYY(), 12, true, HColorUtils.BLACK);
final TextBlock tiny = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor());
final TextBlock small = getTextBlock(monthYear.longName(locale), 12, true, openFontColor());
final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale), 12, true, openFontColor());
printCentered(ug, false, start, end, tiny, small, big);
}
private void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
}
private void printNamedDays(final UGraphic ug) {
if (nameDays.size() > 0) {
String last = null;
@ -174,7 +181,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
if (name != null && name.equals(last) == false) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
final TextBlock label = getTextBlock(name, 12, false, HColorUtils.BLACK);
final TextBlock label = getTextBlock(name, 12, false, openFontColor());
final double h = label.calculateDimension(ug.getStringBounder()).getHeight();
double y1 = getTimeHeaderHeight();
double y2 = getFullHeaderHeight();

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -46,11 +47,9 @@ import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderMonthly extends TimeHeaderCalendar {
@ -62,11 +61,11 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
return 16 + 13 - 1;
}
public TimeHeaderMonthly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet,
ThemeStyle themeStyle) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet, themeStyle);
public TimeHeaderMonthly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min,
Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
}
@Override
@ -132,21 +131,16 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor());
printCentered(ug, false, start, end, small);
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock(monthYear.shortName(), 10, false, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.longName(), 10, false, HColorUtils.BLACK);
final TextBlock small = getTextBlock(monthYear.shortName(locale), 10, false, openFontColor());
final TextBlock big = getTextBlock(monthYear.longName(locale), 10, false, openFontColor());
printCentered(ug, false, start, end, small, big);
}
private void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
}
private void printLeft(UGraphic ug, TextBlock text, double start) {
text.drawU(ug.apply(UTranslate.dx(start)));
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -62,11 +62,11 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
return 16 + 13 - 1;
}
public TimeHeaderQuarterly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet,
ThemeStyle themeStyle) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet, themeStyle);
public TimeHeaderQuarterly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max,
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
}
@Override
@ -136,20 +136,15 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor());
printCentered(ug, false, start, end, small);
}
private void printQuarter(UGraphic ug, String quarter, double start, double end) {
final TextBlock small = getTextBlock(quarter, 10, false, HColorUtils.BLACK);
final TextBlock small = getTextBlock(quarter, 10, false, openFontColor());
printCentered(ug, false, start, end, small);
}
private void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
}
private void printLeft(UGraphic ug, TextBlock text, double start) {
text.drawU(ug.apply(UTranslate.dx(start)));
}

View File

@ -69,15 +69,16 @@ public class TimeHeaderSimple extends TimeHeader {
return 0;
}
public TimeHeaderSimple(double scale, Day min, Day max, Style style, HColorSet colorSet, ThemeStyle themeStyle) {
super(min, max, new TimeScaleWink(scale), style, colorSet, themeStyle);
public TimeHeaderSimple(Style timelineStyle, Style closedStyle, double scale, Day min, Day max, HColorSet colorSet,
ThemeStyle themeStyle) {
super(timelineStyle, closedStyle, min, max, new TimeScaleWink(scale), colorSet, themeStyle);
}
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
final ULine vbar = ULine.vline(totalHeightWithoutFooter);
for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) {
final double x1 = timeScale.getStartingPosition(i);
ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dx(x1)).draw(vbar);
ug.apply(getBarColor()).apply(UTranslate.dx(x1)).draw(vbar);
}
}
@ -85,7 +86,7 @@ public class TimeHeaderSimple extends TimeHeader {
for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) {
final String number = "" + (i.getAbsoluteDayNum() + 1);
final TextBlock num = Display.getWithNewlines(number).create(
getFontConfiguration(10, false, HColorUtils.BLACK), HorizontalAlignment.LEFT,
getFontConfiguration(10, false, openFontColor()), HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
final double x1 = timeScale.getStartingPosition(i);
final double x2 = timeScale.getEndingPosition(i);
@ -103,8 +104,8 @@ public class TimeHeaderSimple extends TimeHeader {
final double xmax = getTimeScale().getEndingPosition(max);
drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter);
drawSimpleDayCounter(ug, getTimeScale());
ug.apply(HColorUtils.LIGHT_GRAY).draw(ULine.hline(xmax - xmin));
ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
}
@ -115,7 +116,7 @@ public class TimeHeaderSimple extends TimeHeader {
drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight());
ug = ug.apply(UTranslate.dy(3));
drawSimpleDayCounter(ug, getTimeScale());
ug.apply(HColorUtils.LIGHT_GRAY).draw(ULine.hline(xmax - xmin));
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
}
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -47,7 +48,6 @@ import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -65,11 +65,11 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
return 16;
}
public TimeHeaderWeekly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, WeekNumberStrategy weekNumberStrategy,
Style style, HColorSet colorSet, ThemeStyle themeStyle) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet, themeStyle);
public TimeHeaderWeekly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max,
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
WeekNumberStrategy weekNumberStrategy, HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
this.weekNumberStrategy = weekNumberStrategy;
}
@ -130,7 +130,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
final String num = "" + wink.getWeekOfYear(weekNumberStrategy);
// final String num = "" + wink.getDayOfMonth();
final TextBlock textBlock = getTextBlock(num, 10, false, HColorUtils.BLACK);
final TextBlock textBlock = getTextBlock(num, 10, false, openFontColor());
printLeft(ug.apply(UTranslate.dy(Y_POS_ROW16())), textBlock,
getTimeScale().getStartingPosition(wink) + 5);
}
@ -138,16 +138,11 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.shortNameYYYY(), 12, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor());
final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale), 12, true, openFontColor());
printCentered(ug, false, start, end, small, big);
}
private void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
}
private void printLeft(UGraphic ug, TextBlock text, double start) {
text.drawU(ug.apply(UTranslate.dx(start)));
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.ThemeStyle;
@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -62,11 +62,11 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
return 20 - 1;
}
public TimeHeaderYearly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet,
ThemeStyle themeStyle) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet, themeStyle);
public TimeHeaderYearly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max,
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek,
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
}
@Override
@ -107,15 +107,10 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, openFontColor());
printCentered(ug, true, start, end, small);
}
private void drawVbar(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
}
@Override
public double getFullHeaderHeight() {
return getTimeHeaderHeight();

View File

@ -93,5 +93,5 @@ public class SubjectDayOfWeek implements Subject {
}
}
}

View File

@ -36,6 +36,7 @@
package net.sourceforge.plantuml.project.time;
import java.text.SimpleDateFormat;
import java.time.format.TextStyle;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
@ -72,10 +73,10 @@ public enum DayOfWeek {
return DayOfWeek.values()[result - 2];
}
public static synchronized String timeToString(long value) {
gmt.setTimeInMillis(value);
return fromTime(value).shortName() + " " + dateFormatGmt.format(gmt.getTime());
}
// private static synchronized String timeToString(Locale locale, long value) {
// gmt.setTimeInMillis(value);
// return fromTime(value).shortName(locale) + " " + dateFormatGmt.format(gmt.getTime());
// }
static public String getRegexString() {
final StringBuilder sb = new StringBuilder();
@ -106,7 +107,13 @@ public enum DayOfWeek {
return DayOfWeek.values()[(h + 5) % 7];
}
public String shortName() {
return StringUtils.capitalize(name().substring(0, 2));
public String shortName(Locale locale) {
if (locale == Locale.ENGLISH)
return StringUtils.capitalize(name().substring(0, 2));
final String s = StringUtils.capitalize(
java.time.DayOfWeek.valueOf(this.toString()).getDisplayName(TextStyle.SHORT_STANDALONE, locale));
if (s.length() > 2)
return s.substring(0, 2);
return s;
}
}

View File

@ -35,6 +35,9 @@
*/
package net.sourceforge.plantuml.project.time;
import java.time.format.TextStyle;
import java.util.Locale;
import net.sourceforge.plantuml.StringUtils;
public enum Month {
@ -48,12 +51,21 @@ public enum Month {
this.daysPerMonth = daysPerMonth;
}
public String shortName() {
return longName().substring(0, 3);
public String shortName(Locale locale) {
if (locale == Locale.ENGLISH)
return longName(locale).substring(0, 3);
return StringUtils.capitalize(
java.time.Month.valueOf(this.toString()).getDisplayName(TextStyle.SHORT_STANDALONE, locale));
}
public String longName() {
return StringUtils.capitalize(name());
public String longName(Locale locale) {
if (locale == Locale.ENGLISH)
return StringUtils.capitalize(name());
return StringUtils
.capitalize(java.time.Month.valueOf(this.toString()).getDisplayName(TextStyle.FULL_STANDALONE, locale));
}
static public String getRegexString() {

View File

@ -35,6 +35,8 @@
*/
package net.sourceforge.plantuml.project.time;
import java.util.Locale;
public class MonthYear implements Comparable<MonthYear> {
private final int year;
@ -44,20 +46,20 @@ public class MonthYear implements Comparable<MonthYear> {
return new MonthYear(year, month);
}
public String shortName() {
return month.shortName();
public String shortName(Locale locale) {
return month.shortName(locale);
}
public String shortNameYYYY() {
return month.shortName() + " " + year;
public String shortNameYYYY(Locale locale) {
return month.shortName(locale) + " " + year;
}
public String longName() {
return month.longName();
public String longName(Locale locale) {
return month.longName(locale);
}
public String longNameYYYY() {
return month.longName() + " " + year;
public String longNameYYYY(Locale locale) {
return month.longName(locale) + " " + year;
}
private MonthYear(int year, Month month) {

View File

@ -114,7 +114,7 @@ public class SFile implements Comparable<SFile> {
}
public boolean exists() {
if (isFileOk())
if (internal != null && isFileOk())
return internal.exists();
return false;
}
@ -124,11 +124,11 @@ public class SFile implements Comparable<SFile> {
}
public boolean isAbsolute() {
return internal.isAbsolute();
return internal != null && internal.isAbsolute();
}
public boolean isDirectory() {
return internal.exists() && internal.isDirectory();
return internal != null && internal.exists() && internal.isDirectory();
}
public String getName() {
@ -136,7 +136,7 @@ public class SFile implements Comparable<SFile> {
}
public boolean isFile() {
return internal.isFile();
return internal != null && internal.isFile();
}
public long lastModified() {

View File

@ -193,11 +193,11 @@ public abstract class AbstractMessage implements EventWithDeactivate, WithStyle
&& note.getPosition() != NotePosition.BOTTOM && note.getPosition() != NotePosition.TOP) {
throw new IllegalArgumentException();
}
note = note.withPosition(overideNotePosition(note.getPosition()));
note = note.withPosition(overrideNotePosition(note.getPosition()));
this.noteOnMessages.add(note);
}
protected NotePosition overideNotePosition(NotePosition notePosition) {
protected NotePosition overrideNotePosition(NotePosition notePosition) {
return notePosition;
}

View File

@ -58,7 +58,7 @@ public class MessageExo extends AbstractMessage {
}
@Override
protected NotePosition overideNotePosition(NotePosition notePosition) {
protected NotePosition overrideNotePosition(NotePosition notePosition) {
if (type == MessageExoType.FROM_LEFT || type == MessageExoType.TO_LEFT) {
return NotePosition.RIGHT;
}

View File

@ -60,6 +60,8 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
protected static final String SHORT = "SHORT";
public CommandExoArrowAny(IRegex pattern) {
super(pattern);
}
@ -204,7 +206,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
abstract MessageExoType getMessageExoType(RegexResult arg2);
private boolean isShortArrow(RegexResult arg2) {
final String s = arg2.get("SHORT", 0);
final String s = arg2.get(SHORT, 0);
if (s != null && s.contains("?")) {
return true;
}
@ -212,7 +214,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
}
private boolean containsSymbolExterior(RegexResult arg2, String symbol) {
final String s = arg2.get("SHORT", 0);
final String s = arg2.get(SHORT, 0);
if (s != null && s.contains(symbol)) {
return true;
}

View File

@ -54,7 +54,7 @@ public class CommandExoArrowLeft extends CommandExoArrowAny {
return RegexConcat.build(CommandExoArrowLeft.class.getName(), RegexLeaf.start(), //
new RegexLeaf("PARALLEL", "(&[%s]*)?"), //
new RegexLeaf("ANCHOR", CommandArrow.ANCHOR), //
new RegexLeaf("SHORT", "([?\\[\\]][ox]?)?"), //
new RegexLeaf(SHORT, "([?\\[\\]][ox]?)?"), //
new RegexOr( //
new RegexConcat( //
new RegexLeaf("ARROW_BOTHDRESSING", "(<<?|//?|\\\\\\\\?)?"), //
@ -87,7 +87,7 @@ public class CommandExoArrowLeft extends CommandExoArrowAny {
@Override
MessageExoType getMessageExoType(RegexResult arg2) {
final String start = arg2.get("SHORT", 0);
final String start = arg2.get(SHORT, 0);
final String dressing1 = arg2.get("ARROW_DRESSING1", 0);
final String dressing2 = arg2.get("ARROW_DRESSING2", 0);
if (start != null && start.contains("]")) {

View File

@ -69,7 +69,7 @@ public class CommandExoArrowRight extends CommandExoArrowAny {
new RegexLeaf("ARROW_BODYB2", "(-*)"), //
new RegexLeaf("ARROW_STYLE2", CommandArrow.getColorOrStylePattern()), //
new RegexLeaf("ARROW_BODYA2", "(-+)"))), //
new RegexLeaf("SHORT", "([ox]?[?\\]\\[])?"), //
new RegexLeaf(SHORT, "([ox]?[?\\]\\[])?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), //
RegexLeaf.spaceZeroOrMore(), //
@ -87,7 +87,7 @@ public class CommandExoArrowRight extends CommandExoArrowAny {
@Override
MessageExoType getMessageExoType(RegexResult arg2) {
final String start = arg2.get("SHORT", 0);
final String start = arg2.get(SHORT, 0);
final String dressing1 = arg2.get("ARROW_DRESSING1", 0);
final String dressing2 = arg2.get("ARROW_DRESSING2", 0);
if (start != null && start.contains("[")) {

View File

@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.OptionFlags;
@ -46,6 +47,7 @@ import net.sourceforge.plantuml.PaddingParam;
import net.sourceforge.plantuml.SkinParamBackcolored;
import net.sourceforge.plantuml.SkinParamBackcoloredReference;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.sequencediagram.AbstractMessage;
import net.sourceforge.plantuml.sequencediagram.Delay;
@ -63,6 +65,7 @@ import net.sourceforge.plantuml.sequencediagram.Message;
import net.sourceforge.plantuml.sequencediagram.MessageExo;
import net.sourceforge.plantuml.sequencediagram.Newpage;
import net.sourceforge.plantuml.sequencediagram.Note;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.Notes;
import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober;
@ -141,8 +144,8 @@ class DrawableSetInitializer {
prepareParticipant(stringBounder, p);
}
this.freeY2 = new FrontierStackImpl(drawableSet.getHeadHeight(stringBounder), drawableSet.getAllParticipants()
.size());
this.freeY2 = new FrontierStackImpl(drawableSet.getHeadHeight(stringBounder),
drawableSet.getAllParticipants().size());
this.lastFreeY2 = this.freeY2;
@ -205,8 +208,8 @@ class DrawableSetInitializer {
prepareMissingSpace(stringBounder);
drawableSet.setDimension(new Dimension2DDouble(freeX, getTotalHeight(
freeY2.getFreeY(getFullParticipantRange()), stringBounder)));
drawableSet.setDimension(new Dimension2DDouble(freeX,
getTotalHeight(freeY2.getFreeY(getFullParticipantRange()), stringBounder)));
return drawableSet;
}
@ -248,7 +251,8 @@ class DrawableSetInitializer {
}
public double getYposition(StringBounder stringBounder, Newpage newpage) {
final GraphicalNewpage graphicalNewpage = (GraphicalNewpage) drawableSet.getEvent(Objects.requireNonNull(newpage));
final GraphicalNewpage graphicalNewpage = (GraphicalNewpage) drawableSet
.getEvent(Objects.requireNonNull(newpage));
return graphicalNewpage.getStartingY();
}
@ -303,8 +307,8 @@ class DrawableSetInitializer {
}
private void prepareNewpage(StringBounder stringBounder, Newpage newpage, ParticipantRange range) {
final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY2.getFreeY(range), drawableSet.getSkin()
.createComponentNewPage(drawableSet.getSkinParam()));
final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY2.getFreeY(range),
drawableSet.getSkin().createComponentNewPage(drawableSet.getSkinParam()));
this.lastFreeY2 = freeY2;
freeY2 = freeY2.add(graphicalNewpage.getPreferredHeight(stringBounder), range);
drawableSet.addEvent(newpage, graphicalNewpage);
@ -312,17 +316,17 @@ class DrawableSetInitializer {
private void prepareNewpageSpecial(StringBounder stringBounder, Newpage newpage, Event justBefore,
ParticipantRange range) {
final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY2.getFreeY(range), drawableSet.getSkin()
.createComponentNewPage(drawableSet.getSkinParam()));
final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY2.getFreeY(range),
drawableSet.getSkin().createComponentNewPage(drawableSet.getSkinParam()));
this.lastFreeY2 = freeY2;
freeY2 = freeY2.add(graphicalNewpage.getPreferredHeight(stringBounder), range);
drawableSet.addEvent(newpage, graphicalNewpage, justBefore);
}
private void prepareDivider(StringBounder stringBounder, Divider divider, ParticipantRange range) {
final GraphicalDivider graphicalDivider = new GraphicalDivider(freeY2.getFreeY(range), drawableSet.getSkin()
.createComponent(divider.getUsedStyles(), ComponentType.DIVIDER, null, drawableSet.getSkinParam(),
divider.getText()));
final GraphicalDivider graphicalDivider = new GraphicalDivider(freeY2.getFreeY(range),
drawableSet.getSkin().createComponent(divider.getUsedStyles(), ComponentType.DIVIDER, null,
drawableSet.getSkinParam(), divider.getText()));
freeY2 = freeY2.add(graphicalDivider.getPreferredHeight(stringBounder), range);
drawableSet.addEvent(divider, graphicalDivider);
}
@ -362,8 +366,8 @@ class DrawableSetInitializer {
final double preferredHeight = comp.getPreferredHeight(stringBounder);
freeY2 = freeY2.add(preferredHeight, range);
final Display strings = start.getTitle().equals("group") ? Display.create(start.getComment()) : Display.create(
start.getTitle(), start.getComment());
final Display strings = start.getTitle().equals("group") ? Display.create(start.getComment())
: Display.create(start.getTitle(), start.getComment());
final Component header = drawableSet.getSkin().createComponent(start.getUsedStyles(),
ComponentType.GROUPING_HEADER, null, skinParam, strings);
final ParticipantBox veryfirst = drawableSet.getVeryfirst();
@ -383,7 +387,8 @@ class DrawableSetInitializer {
private void prepareGroupingLeaf(StringBounder stringBounder, final GroupingLeaf m, ParticipantRange range) {
final GraphicalElement element;
final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), null, m.getBackColorGeneral());
final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), null,
m.getBackColorGeneral());
if (m.getType() == GroupingType.ELSE) {
if (m.isParallel()) {
freeY2 = ((FrontierStack) freeY2).restore();
@ -409,8 +414,8 @@ class DrawableSetInitializer {
final List<Component> notes = new ArrayList<>();
for (Note noteOnMessage : m.getNoteOnMessages()) {
final ISkinParam sk = noteOnMessage.getSkinParamBackcolored(drawableSet.getSkinParam());
final Component note = drawableSet.getSkin().createComponent(noteOnMessage.getUsedStyles(),
noteOnMessage.getNoteStyle().getNoteComponentType(), null, sk, noteOnMessage.getStrings());
final Component note = drawableSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(),
noteOnMessage.getNoteStyle().getNoteComponentType(), sk, noteOnMessage.getStrings());
notes.add(note);
}
if (m.isParallel()) {
@ -467,8 +472,9 @@ class DrawableSetInitializer {
p2 = p;
}
}
final NoteBox noteBox = new NoteBox(freeY2.getFreeY(range), drawableSet.getSkin().createComponent(
n.getUsedStyles(), type, null, skinParam, n.getStrings()), p1, p2, n.getPosition(), n.getUrl());
final Component component = drawableSet.getSkin().createComponentNote(n.getUsedStyles(), type, skinParam,
n.getStrings(), n.getPosition());
final NoteBox noteBox = new NoteBox(freeY2.getFreeY(range), component, p1, p2, n.getPosition(), n.getUrl());
return noteBox;
}
@ -477,8 +483,8 @@ class DrawableSetInitializer {
for (Note n : notes) {
final NoteBox noteBox = createNoteBox(stringBounder, n, range);
final ParticipantBox p1 = drawableSet.getLivingParticipantBox(n.getParticipant()).getParticipantBox();
final ParticipantBox p2 = n.getParticipant2() == null ? null : drawableSet.getLivingParticipantBox(
n.getParticipant2()).getParticipantBox();
final ParticipantBox p2 = n.getParticipant2() == null ? null
: drawableSet.getLivingParticipantBox(n.getParticipant2()).getParticipantBox();
notesBoxes.add(noteBox, p1, p2);
}
notesBoxes.ensureConstraints(stringBounder, constraintSet);
@ -522,8 +528,8 @@ class DrawableSetInitializer {
final Component comp = drawableSet.getSkin().createComponent(null, ComponentType.DESTROY, null,
drawableSet.getSkinParam(), null);
final double delta = comp.getPreferredHeight(stringBounder) / 2;
final LivingParticipantBox livingParticipantBox = drawableSet.getLivingParticipantBox(lifeEvent
.getParticipant());
final LivingParticipantBox livingParticipantBox = drawableSet
.getLivingParticipantBox(lifeEvent.getParticipant());
double pos2 = y;
if (message == null) {
pos2 = y;
@ -550,18 +556,18 @@ class DrawableSetInitializer {
}
private void prepareReference(StringBounder stringBounder, Reference reference, ParticipantRange range) {
final LivingParticipantBox p1 = drawableSet.getLivingParticipantBox(drawableSet.getFirst(reference
.getParticipant()));
final LivingParticipantBox p2 = drawableSet.getLivingParticipantBox(drawableSet.getLast(reference
.getParticipant()));
final LivingParticipantBox p1 = drawableSet
.getLivingParticipantBox(drawableSet.getFirst(reference.getParticipant()));
final LivingParticipantBox p2 = drawableSet
.getLivingParticipantBox(drawableSet.getLast(reference.getParticipant()));
final ISkinParam skinParam = new SkinParamBackcoloredReference(drawableSet.getSkinParam(),
reference.getBackColorElement(), reference.getBackColorGeneral());
Display strings = Display.empty();
strings = strings.add("ref");
strings = strings.addAll(reference.getStrings());
final Component comp = drawableSet.getSkin().createComponent(reference.getUsedStyles(),
ComponentType.REFERENCE, null, skinParam, strings);
final Component comp = drawableSet.getSkin().createComponent(reference.getUsedStyles(), ComponentType.REFERENCE,
null, skinParam, strings);
final GraphicalReference graphicalReference = new GraphicalReference(freeY2.getFreeY(range), comp, p1, p2,
reference.getUrl());
@ -625,8 +631,8 @@ class DrawableSetInitializer {
participantDisplay);
final Component tail = drawableSet.getSkin().createComponent(p.getUsedStyles(), tailType, null, skinParam,
participantDisplay);
final Style style = this.defaultLineType.getDefaultStyleDefinition().getMergedStyle(
skinParam.getCurrentStyleBuilder());
final Style style = this.defaultLineType.getDefaultStyleDefinition()
.getMergedStyle(skinParam.getCurrentStyleBuilder());
final Component line = drawableSet.getSkin().createComponent(new Style[] { style }, this.defaultLineType, null,
drawableSet.getSkinParam(), participantDisplay);
final Component delayLine = drawableSet.getSkin().createComponent(null, ComponentType.DELAY_LINE, null,
@ -635,12 +641,12 @@ class DrawableSetInitializer {
skinParam.maxAsciiMessageLength() > 0 ? 1 : 5);
final Component comp = drawableSet.getSkin().createComponent(
new Style[] { ComponentType.ALIVE_BOX_CLOSE_CLOSE.getDefaultStyleDefinition().getMergedStyle(
drawableSet.getSkinParam().getCurrentStyleBuilder()) }, ComponentType.ALIVE_BOX_CLOSE_CLOSE,
null, drawableSet.getSkinParam(), null);
new Style[] { ComponentType.ALIVE_BOX_CLOSE_CLOSE.getDefaultStyleDefinition()
.getMergedStyle(drawableSet.getSkinParam().getCurrentStyleBuilder()) },
ComponentType.ALIVE_BOX_CLOSE_CLOSE, null, drawableSet.getSkinParam(), null);
final LifeLine lifeLine = new LifeLine(box, comp.getPreferredWidth(stringBounder), drawableSet.getSkinParam()
.shadowing(p.getStereotype()));
final LifeLine lifeLine = new LifeLine(box, comp.getPreferredWidth(stringBounder),
drawableSet.getSkinParam().shadowing(p.getStereotype()));
drawableSet.setLivingParticipantBox(p, new LivingParticipantBox(box, lifeLine));
this.freeX = box.getMaxX(stringBounder);

View File

@ -85,8 +85,8 @@ class Step1Message extends Step1Abstract {
final List<Note> noteOnMessages = message.getNoteOnMessages();
for (Note noteOnMessage : noteOnMessages) {
final ISkinParam skinParam = noteOnMessage.getSkinParamBackcolored(drawingSet.getSkinParam());
addNote(drawingSet.getSkin().createComponent(noteOnMessage.getUsedStyles(),
noteOnMessage.getNoteStyle().getNoteComponentType(), null, skinParam, noteOnMessage.getStrings()));
addNote(drawingSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(),
noteOnMessage.getNoteStyle().getNoteComponentType(), skinParam, noteOnMessage.getStrings()));
}
}

View File

@ -68,8 +68,8 @@ class Step1MessageExo extends Step1Abstract {
final List<Note> noteOnMessages = message.getNoteOnMessages();
for (Note noteOnMessage : noteOnMessages) {
final ISkinParam skinParam = noteOnMessage.getSkinParamBackcolored(drawingSet.getSkinParam());
addNote(drawingSet.getSkin().createComponent(noteOnMessage.getUsedStyles(),
ComponentType.NOTE, null, skinParam, noteOnMessage.getStrings()));
addNote(drawingSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, skinParam,
noteOnMessage.getStrings()));
}
}

View File

@ -89,8 +89,8 @@ public class CommunicationTileNoteBottom extends AbstractTile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null,
noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings());
final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam),
noteOnMessage.getStrings());
return comp;
}

View File

@ -87,8 +87,8 @@ public class CommunicationTileNoteLeft extends AbstractTile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null,
noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings());
final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam),
noteOnMessage.getStrings());
return comp;
}

View File

@ -91,8 +91,8 @@ public class CommunicationTileNoteRight extends AbstractTile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null,
noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings());
final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam),
noteOnMessage.getStrings());
return comp;
}

View File

@ -89,8 +89,8 @@ public class CommunicationTileNoteTop extends AbstractTile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null,
noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings());
final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam),
noteOnMessage.getStrings());
return comp;
}

View File

@ -84,8 +84,8 @@ public class CommunicationTileSelfNoteRight extends AbstractTile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(null, ComponentType.NOTE, null,
noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings());
final Component comp = skin.createComponentNote(null, ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam),
noteOnMessage.getStrings());
return comp;
}

View File

@ -81,8 +81,8 @@ public class NoteTile extends AbstractTile implements Tile {
}
private Component getComponent(StringBounder stringBounder) {
final Component comp = skin.createComponent(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()),
null, note.getSkinParamBackcolored(skinParam), note.getStrings());
final Component comp = skin.createComponentNote(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()),
note.getSkinParamBackcolored(skinParam), note.getStrings(), note.getPosition());
return comp;
}

View File

@ -77,8 +77,8 @@ public class NotesTile extends AbstractTile implements Tile {
}
private Component getComponent(StringBounder stringBounder, Note note) {
final Component comp = skin.createComponent(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()),
null, note.getSkinParamBackcolored(skinParam), note.getStrings());
final Component comp = skin.createComponentNote(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()),
note.getSkinParamBackcolored(skinParam), note.getStrings(), note.getPosition());
return comp;
}

View File

@ -69,6 +69,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
private final UFont font;
private final HColor fontColor;
private final HorizontalAlignment alignment;
public AbstractTextualComponent(Style style, LineBreakStrategy maxMessageSize, CharSequence label,
FontConfiguration font, HorizontalAlignment horizontalAlignment, int marginX1, int marginX2, int marginY,
@ -118,6 +119,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
textBlock = this.display.create0(fc, horizontalAlignment, spriteContainer, maxMessageSize, CreoleMode.FULL,
fontForStereotype, htmlColorForStereotype);
}
this.alignment = horizontalAlignment;
}
protected HColorSet getIHtmlColorSet() {
@ -168,4 +170,8 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
return spriteContainer;
}
public final HorizontalAlignment getHorizontalAlignment() {
return alignment;
}
}

View File

@ -60,14 +60,16 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements
private final double paddingY;
private final SymbolContext symbolContext;
private final double roundCorner;
private final HorizontalAlignment position;
public ComponentRoseNote(Style style, SymbolContext symbolContext, FontConfiguration font, Display strings,
double paddingX, double paddingY, ISkinSimple spriteContainer, double roundCorner,
HorizontalAlignment horizontalAlignment) {
super(style, spriteContainer.wrapWidth(), strings, font, horizontalAlignment,
horizontalAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null);
HorizontalAlignment textAlignment, HorizontalAlignment position) {
super(style, spriteContainer.wrapWidth(), strings, font, textAlignment,
textAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null);
this.paddingX = paddingX;
this.paddingY = paddingY;
this.position = position;
if (UseStyle.useBetaStyle()) {
this.symbolContext = style.getSymbolContext(spriteContainer.getThemeStyle(), getIHtmlColorSet());
this.roundCorner = style.value(PName.RoundCorner).asInt();
@ -121,7 +123,15 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements
ug.draw(Opale.getCorner(x2, roundCorner));
UGraphic ug2 = UGraphicStencil.create(ug, this, new UStroke());
ug2 = ug2.apply(new UTranslate(getMarginX1() + diffX / 2, getMarginY()));
if (position == HorizontalAlignment.LEFT) {
ug2 = ug2.apply(new UTranslate(getMarginX1(), getMarginY()));
} else if (position == HorizontalAlignment.RIGHT) {
ug2 = ug2.apply(
new UTranslate(area.getDimensionToUse().getWidth() - getTextWidth(stringBounder), getMarginY()));
} else {
ug2 = ug2.apply(new UTranslate(getMarginX1() + diffX / 2, getMarginY()));
}
getTextBlock().drawU(ug2);

View File

@ -50,6 +50,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.SkinParameter;
import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.skin.ArrowComponent;
import net.sourceforge.plantuml.skin.ArrowConfiguration;
import net.sourceforge.plantuml.skin.ArrowDirection;
@ -90,8 +91,62 @@ public class Rose {
return new FontConfiguration(skinParam, fontParam, null);
}
public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param,
Display stringsToDisplay) {
checkRose();
return createComponentNote(styles, type, param, stringsToDisplay, null);
}
private void checkRose() {
// Quite ugly, but we want to ensure that TextSkin overrides those methods
if (this.getClass() != Rose.class)
throw new IllegalStateException("" + this.getClass());
}
public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, Display stringsToDisplay,
NotePosition notePosition) {
checkRose();
final HorizontalAlignment textAlign;
final HorizontalAlignment position;
if (notePosition == NotePosition.OVER_SEVERAL) {
textAlign = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false,
HorizontalAlignment.LEFT);
if (textAlign == param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false,
HorizontalAlignment.CENTER))
// Which means we use default
position = textAlign;
else
position = HorizontalAlignment.CENTER;
} else {
textAlign = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false, null);
position = textAlign;
}
final Stereotype stereotype = stringsToDisplay == null ? null : stringsToDisplay.getStereotypeIfAny();
final double roundCorner = param.getRoundCorner(CornerParam.DEFAULT, null);
if (type == ComponentType.NOTE) {
return new ComponentRoseNote(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, paddingX, paddingY, param, roundCorner, textAlign, position);
}
if (type == ComponentType.NOTE_HEXAGONAL) {
return new ComponentRoseNoteHexagonal(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, param, textAlign);
}
if (type == ComponentType.NOTE_BOX) {
return new ComponentRoseNoteBox(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, param, roundCorner, textAlign);
}
throw new UnsupportedOperationException(type.toString());
}
public Component createComponent(Style[] styles, ComponentType type, ArrowConfiguration config, ISkinParam param,
Display stringsToDisplay) {
checkRose();
final UFont fontGrouping = param.getFont(null, false, FontParam.SEQUENCE_GROUP);
final Stereotype stereotype = stringsToDisplay == null ? null : stringsToDisplay.getStereotypeIfAny();
@ -215,25 +270,13 @@ public class Rose {
getFontColor(param, FontParam.DATABASE_STEREOTYPE));
}
if (type == ComponentType.NOTE) {
final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null,
false);
return new ComponentRoseNote(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, paddingX, paddingY, param, roundCorner, alignment);
throw new UnsupportedOperationException();
}
if (type == ComponentType.NOTE_HEXAGONAL) {
final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null,
false);
return new ComponentRoseNoteHexagonal(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, param, alignment);
throw new UnsupportedOperationException();
}
if (type == ComponentType.NOTE_BOX) {
final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null,
false);
return new ComponentRoseNoteBox(styles == null ? null : styles[0],
getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE),
stringsToDisplay, param, roundCorner, alignment);
throw new UnsupportedOperationException();
}
final FontConfiguration bigFont = getUFont2(param, FontParam.SEQUENCE_GROUP_HEADER);
if (type == ComponentType.GROUPING_HEADER) {
@ -300,7 +343,7 @@ public class Rose {
return new ComponentRoseReference(styles == null ? null : styles[0], styles == null ? null : styles[1],
getUFont2(param, FontParam.SEQUENCE_REFERENCE),
getSymbolContext(stereotype, param, ColorParam.sequenceReferenceBorder), bigFont, stringsToDisplay,
param.getHorizontalAlignment(AlignmentParam.sequenceReferenceAlignment, null, false), param,
param.getHorizontalAlignment(AlignmentParam.sequenceReferenceAlignment, null, false, null), param,
getHtmlColor(param, stereotype, ColorParam.sequenceReferenceBackground));
}
if (type == ComponentType.ENGLOBER) {
@ -309,15 +352,17 @@ public class Rose {
getUFont2(param, FontParam.SEQUENCE_BOX), param, roundCorner);
}
return null;
throw new UnsupportedOperationException();
}
public ComponentRoseNewpage createComponentNewPage(ISkinParam param) {
public Component createComponentNewPage(ISkinParam param) {
checkRose();
return new ComponentRoseNewpage(null, getHtmlColor(param, ColorParam.sequenceNewpageSeparator));
}
public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param,
Display stringsToDisplay) {
checkRose();
final HColor sequenceArrow = config.getColor() == null ? getHtmlColor(param, ColorParam.arrow)
: config.getColor();
if (config.getArrowDirection() == ArrowDirection.SELF) {
@ -369,9 +414,9 @@ public class Rose {
}
} else {
messageHorizontalAlignment = param.getHorizontalAlignment(AlignmentParam.sequenceMessageAlignment,
arrowDirection, config.isReverseDefine());
arrowDirection, config.isReverseDefine(), null);
textHorizontalAlignment = param.getHorizontalAlignment(AlignmentParam.sequenceMessageTextAlignment,
config.getArrowDirection(), false);
config.getArrowDirection(), false, null);
}
return new ComponentRoseArrow(styles == null ? null : styles[0], sequenceArrow,
getUFont2(param, FontParam.ARROW), stringsToDisplay, config, messageHorizontalAlignment, param,

View File

@ -383,7 +383,7 @@ public class Cluster implements Moveable {
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
zstereo, minX, minY, maxX, maxY, stroke);
decoration.drawU(ug, backColor, borderColor, shadowing, roundCorner,
skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false),
skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null),
skinParam2.getStereotypeAlignment());
return;
}
@ -781,7 +781,7 @@ public class Cluster implements Moveable {
sblabel.append(">");
label = sblabel.toString();
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment,
null, false);
null, false, null);
sb.append("labeljust=\"" + align.getGraphVizValue() + "\";");
} else {
label = "\"\"";

View File

@ -325,7 +325,7 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) {
if (umlDiagramType == UmlDiagramType.STATE) {
return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false);
return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false, null);
}
return skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER);
}

View File

@ -233,7 +233,9 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi
public Ports getPorts(StringBounder stringBounder) {
final Dimension2D dimHeader = header.calculateDimension(stringBounder);
return ((WithPorts) body).getPorts(stringBounder).translateY(dimHeader.getHeight());
if (body instanceof WithPorts)
return ((WithPorts) body).getPorts(stringBounder).translateY(dimHeader.getHeight());
return new Ports();
}
private UStroke getStroke() {

View File

@ -178,7 +178,7 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
stereoBlock, 0, 0, widthTotal, heightTotal, stroke);
final HorizontalAlignment horizontalAlignment = getSkinParam()
.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false);
.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null);
final HorizontalAlignment stereotypeAlignment = getSkinParam().getStereotypeAlignment();
decoration.drawU(ug, back, borderColor, shadowing, roundCorner, horizontalAlignment, stereotypeAlignment);

View File

@ -40,6 +40,7 @@ import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Objects;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.Dimension2DDouble;
@ -129,7 +130,9 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
textBlock = new TextBlockEmpty();
} else {
final FontConfiguration fc = new FontConfiguration(getSkinParam(), FontParam.NOTE, null);
textBlock = BodyFactory.create3(strings, FontParam.NOTE, getSkinParam(), HorizontalAlignment.LEFT, fc,
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null,
false, null);
textBlock = BodyFactory.create3(strings, FontParam.NOTE, getSkinParam(), align, fc,
getSkinParam().wrapWidth());
}
}
@ -297,7 +300,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
return null;
}
private static double getOrthoDistance(Line2D.Double seg, Point2D pt) {
if (isHorizontal(seg)) {
return Math.abs(seg.getP1().getY() - pt.getY());
@ -307,7 +310,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
}
throw new IllegalArgumentException();
}
private static boolean isHorizontal(Line2D.Double seg) {
return seg.getP1().getY() == seg.getP2().getY();
}
@ -316,8 +319,6 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
return seg.getP1().getX() == seg.getP2().getX();
}
public ShapeType getShapeType() {
return ShapeType.RECTANGLE;
}

View File

@ -62,9 +62,9 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma
public EntityImageNoteLink(Display note, Colors colors, ISkinParam skinParam, StyleBuilder styleBuilder) {
final Rose skin = new Rose();
comp = skin.createComponent(
comp = skin.createComponentNote(
new Style[] { ComponentType.NOTE.getDefaultStyleDefinition().getMergedStyle(styleBuilder) },
ComponentType.NOTE, null, colors.mute(skinParam), note);
ComponentType.NOTE, colors.mute(skinParam), note);
}
public Dimension2D calculateDimension(StringBounder stringBounder) {

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