1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-22 04:55:10 +00:00

version 1.2018.0

This commit is contained in:
Arnaud Roques 2018-01-04 23:32:45 +01:00
parent 6ede577f01
commit 0be8ee2e6f
36 changed files with 1497 additions and 94 deletions

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2017.21-SNAPSHOT</version>
<version>1.2018.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>

View File

@ -109,15 +109,29 @@ public class CharSequence2Impl implements CharSequence2 {
if (trim.startsWith("/'")) {
final int idx = string.indexOf("'/");
if (idx != -1) {
return new CharSequence2Impl(s.subSequence(idx + 2, s.length()), location, preprocessorError);
return new CharSequence2Impl(removeSpecialInnerComment(s.subSequence(idx + 2, s.length())), location,
preprocessorError);
}
}
if (trim.endsWith("'/")) {
final int idx = string.lastIndexOf("/'");
if (idx != -1) {
return new CharSequence2Impl(s.subSequence(0, idx), location, preprocessorError);
return new CharSequence2Impl(removeSpecialInnerComment(s.subSequence(0, idx)), location,
preprocessorError);
}
}
if (trim.contains("/'''") && trim.contains("'''/")) {
return new CharSequence2Impl(removeSpecialInnerComment(s), location, preprocessorError);
}
return this;
}
private CharSequence removeSpecialInnerComment(CharSequence cs) {
final String s = cs.toString();
if (s.contains("/'''") && s.contains("'''/")) {
return s.replaceAll("/'''[-\\w]*'''/", "");
}
return cs;
}
}

View File

@ -54,7 +54,8 @@ public enum LineParam {
activityBorder,
titleBorder,
diagramBorder,
rectangleBorder;
rectangleBorder,
componentBorder;
// sequenceBoxBorder(0.1);
}

View File

@ -421,7 +421,15 @@ public class Option {
final Defines result = Defines.createWithFileName(f);
for (Map.Entry<String, String> ent : defines.entrySet()) {
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false);
}
return result;
}
public Defines getDefaultDefines() {
final Defines result = Defines.createEmpty();
result.overrideFilename(filename);
for (Map.Entry<String, String> ent : defines.entrySet()) {
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false);
}
return result;
}
@ -557,10 +565,6 @@ public class Option {
return imageIndex;
}
public String getFilename() {
return filename;
}
public final void setFilename(String filename) {
this.filename = filename;
}

View File

@ -69,8 +69,8 @@ public class Pipe {
ps.flush();
return error;
}
final SourceStringReader sourceStringReader = new SourceStringReader(Defines.createEmpty(option
.getFilename()), source, option.getConfig());
final Defines defines = option.getDefaultDefines();
final SourceStringReader sourceStringReader = new SourceStringReader(defines, source, option.getConfig());
if (option.isComputeurl()) {
for (BlockUml s : sourceStringReader.getBlocks()) {
ps.println(s.getEncodedUrl());

View File

@ -62,7 +62,7 @@ import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory;
import net.sourceforge.plantuml.ftp.FtpServer;
import net.sourceforge.plantuml.objectdiagram.ObjectDiagramFactory;
import net.sourceforge.plantuml.png.MetadataTag;
import net.sourceforge.plantuml.preproc.Stdlib;
import net.sourceforge.plantuml.preproc.StdlibOld;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.StatsUtils;
@ -79,7 +79,7 @@ public class Run {
final Option option = new Option(argsArray);
ProgressBar.setEnable(option.isTextProgressBar());
if (OptionFlags.getInstance().getExtractStdLib()) {
Stdlib.extractStdLib();
StdlibOld.extractStdLib();
return;
}
if (OptionFlags.getInstance().isDumpStats()) {

View File

@ -115,6 +115,13 @@ public class ActivityDiagram3 extends UmlDiagram {
}
}
public void addSpot(String spot) {
final InstructionSpot ins = new InstructionSpot(spot, nextLinkRenderer(), swinlanes.getCurrentSwimlane());
current().add(ins);
setNextLinkRendererInternal(LinkRendering.none());
manageSwimlaneStrategy();
}
public CommandExecutionResult addGoto(String name) {
final InstructionGoto ins = new InstructionGoto(swinlanes.getCurrentSwimlane(), name);
current().add(ins);

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandArrow3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandArrowLong3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandBackward3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandBreak;
import net.sourceforge.plantuml.activitydiagram3.command.CommandCircleSpot3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf2;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElseLegacy1;
@ -126,6 +127,7 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory {
// cmds.add(new CommandGroupEnd3());
cmds.add(new CommandStart3());
cmds.add(new CommandStop3());
cmds.add(new CommandCircleSpot3());
cmds.add(new CommandBreak());
cmds.add(new CommandEnd3());
cmds.add(new CommandKill3());

View File

@ -0,0 +1,80 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.activitydiagram3;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileKilled;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
public class InstructionSpot extends MonoSwimable implements Instruction {
private boolean killed = false;
private final LinkRendering inlinkRendering;
private final String spot;
public InstructionSpot(String spot, LinkRendering inlinkRendering, Swimlane swimlane) {
super(swimlane);
this.spot = spot;
this.inlinkRendering = inlinkRendering;
if (inlinkRendering == null) {
throw new IllegalArgumentException();
}
}
public Ftile createFtile(FtileFactory factory) {
Ftile result = factory.spot(getSwimlaneIn(), spot);
result = eventuallyAddNote(factory, result, result.getSwimlaneIn());
if (killed) {
return new FtileKilled(result);
}
return result;
}
public void add(Instruction other) {
throw new UnsupportedOperationException();
}
final public boolean kill() {
this.killed = true;
return true;
}
public LinkRendering getInLinkRendering() {
return inlinkRendering;
}
}

View File

@ -0,0 +1,64 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.activitydiagram3.command;
import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class CommandCircleSpot3 extends SingleLineCommand2<ActivityDiagram3> {
public CommandCircleSpot3() {
super(getRegexConcat());
}
static RegexConcat getRegexConcat() {
return new RegexConcat(//
new RegexLeaf("^"), //
new RegexLeaf("SPOT", "\\((\\S)\\)"), //
new RegexLeaf(";?$"));
}
@Override
protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) {
diagram.addSpot(arg.get("SPOT", 0));
return CommandExecutionResult.ok();
}
}

View File

@ -62,6 +62,8 @@ public interface FtileFactory {
public Ftile end(Swimlane swimlane);
public Ftile spot(Swimlane swimlane, String spot);
public Ftile activity(Display label, Swimlane swimlane, BoxStyle style, Colors colors);
public Ftile addNote(Ftile ftile, Swimlane swimlane, Collection<PositionedNote> notes);
@ -74,8 +76,9 @@ public interface FtileFactory {
public Ftile assembly(Ftile tile1, Ftile tile2);
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test, Display yes,
Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward, boolean noOut);
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut);
public Ftile createWhile(Swimlane swimlane, Ftile whileBlock, Display test, Display yes, Display out,
LinkRendering afterEndwhile, HtmlColor color, Instruction specialOut);

View File

@ -111,6 +111,10 @@ public class FtileFactoryDelegator implements FtileFactory {
return factory.stop(swimlane);
}
public Ftile spot(Swimlane swimlane, String spot) {
return factory.spot(swimlane, spot);
}
public Ftile activity(Display label, Swimlane swimlane, BoxStyle style, Colors colors) {
return factory.activity(label, swimlane, style, colors);
}
@ -141,10 +145,11 @@ public class FtileFactoryDelegator implements FtileFactory {
return factory.assembly(tile1, tile2);
}
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test, Display yes,
Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward, boolean noOut) {
return factory.repeat(swimlane, swimlaneOut, startLabel, repeat, test, yes, out, color, backRepeatLinkRendering,
backward, noOut);
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut) {
return factory.repeat(swimlane, swimlaneOut, startLabel, repeat, test, yes, out, color,
backRepeatLinkRendering, backward, noOut);
}
public Ftile createWhile(Swimlane swimlane, Ftile whileBlock, Display test, Display yes, Display out,
@ -181,4 +186,5 @@ public class FtileFactoryDelegator implements FtileFactory {
protected FtileFactory getFactory() {
return factory;
}
}

View File

@ -55,6 +55,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileBox;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileCircleEnd;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileCircleSpot;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileCircleStart;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileCircleStop;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDecorateIn;
@ -91,6 +92,12 @@ public class VCompactFactory implements FtileFactory {
return new FtileCircleStop(skinParam(), color, swimlane);
}
public Ftile spot(Swimlane swimlane, String spot) {
// final HtmlColor color = rose.getHtmlColor(skinParam, ColorParam.activityBackground);
final UFont font = skinParam.getFont(null, false, FontParam.ACTIVITY);
return new FtileCircleSpot(skinParam(), swimlane, spot, font);
}
public Ftile end(Swimlane swimlane) {
final HtmlColor color = rose.getHtmlColor(skinParam, ColorParam.activityEnd);
return new FtileCircleEnd(skinParam(), color, swimlane);
@ -163,5 +170,4 @@ public class VCompactFactory implements FtileFactory {
public ISkinParam skinParam() {
return skinParam;
}
}

View File

@ -82,7 +82,7 @@ public class FtileBox extends AbstractFtile {
private final LinkRendering inRenreding;
private final Swimlane swimlane;
private final BoxStyle style;
private final ISkinParam skinParam;
// private final ISkinParam skinParam;
final public LinkRendering getInLinkRendering() {
return inRenreding;
@ -119,7 +119,7 @@ public class FtileBox extends AbstractFtile {
public FtileBox(ISkinParam skinParam, Display label, UFont font, Swimlane swimlane, BoxStyle style) {
super(skinParam);
this.style = style;
this.skinParam = skinParam;
// this.skinParam = skinParam;
this.swimlane = swimlane;
this.inRenreding = new LinkRendering(HtmlColorAndStyle.build(skinParam));
final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
@ -142,8 +142,8 @@ public class FtileBox extends AbstractFtile {
final double heightTotal = dimTotal.getHeight();
final UDrawable rect = style.getUDrawable(widthTotal, heightTotal, skinParam().shadowing());
final HtmlColor borderColor = SkinParamUtils.getColor(skinParam, ColorParam.activityBorder, null);
final HtmlColor backColor = SkinParamUtils.getColor(skinParam, ColorParam.activityBackground, null);
final HtmlColor borderColor = SkinParamUtils.getColor(skinParam(), ColorParam.activityBorder, null);
final HtmlColor backColor = SkinParamUtils.getColor(skinParam(), ColorParam.activityBackground, null);
ug = ug.apply(new UChangeColor(borderColor)).apply(new UChangeBackColor(backColor)).apply(getThickness());
rect.drawU(ug);

View File

@ -0,0 +1,119 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.activitydiagram3.ftile.vertical;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractFtile;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.UCenteredCharacter;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class FtileCircleSpot extends AbstractFtile {
private static final int SIZE = 20;
private final Swimlane swimlane;
private final String spot;
private final FontConfiguration fc;
public FtileCircleSpot(ISkinParam skinParam, Swimlane swimlane, String spot, UFont font) {
super(skinParam);
this.spot = spot;
this.swimlane = swimlane;
// this.font = font;
this.fc = new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
}
@Override
public Collection<Ftile> getMyChildren() {
return Collections.emptyList();
}
public Set<Swimlane> getSwimlanes() {
if (swimlane == null) {
return Collections.emptySet();
}
return Collections.singleton(swimlane);
}
public Swimlane getSwimlaneIn() {
return swimlane;
}
public Swimlane getSwimlaneOut() {
return swimlane;
}
public void drawU(UGraphic ug) {
final HtmlColor borderColor = SkinParamUtils.getColor(skinParam(), ColorParam.activityBorder, null);
final HtmlColor backColor = SkinParamUtils.getColor(skinParam(), ColorParam.activityBackground, null);
final UEllipse circle = new UEllipse(SIZE, SIZE);
if (skinParam().shadowing()) {
circle.setDeltaShadow(3);
}
ug.apply(new UChangeColor(borderColor)).apply(new UChangeBackColor(backColor)).apply(getThickness())
.draw(circle);
ug.apply(new UChangeColor(fc.getColor())).apply(new UTranslate(SIZE / 2, SIZE / 2))
.draw(new UCenteredCharacter(spot.charAt(0), fc.getFont()));
}
@Override
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0, SIZE);
}
}

View File

@ -39,7 +39,7 @@ import java.io.IOException;
public class TranscoderSmart implements Transcoder {
// private final Transcoder oldOne = new TranscoderImpl(new AsciiEncoder(), new CompressionHuffman());
private final Transcoder oldOne = new TranscoderImpl(new AsciiEncoder(), new CompressionHuffman());
private final Transcoder zlib = new TranscoderImpl(new AsciiEncoder(), new CompressionZlib());
private final Transcoder brotli = new TranscoderImpl(new AsciiEncoder(), new CompressionBrotli());
@ -47,7 +47,12 @@ public class TranscoderSmart implements Transcoder {
if (code.startsWith("0")) {
return brotli.decode(code.substring(1));
}
return zlib.decode(code);
try {
return zlib.decode(code);
} catch (Exception ex) {
return oldOne.decode(code);
}
// return zlib.decode(code);
}
public String encode(String text) throws IOException {

View File

@ -41,6 +41,10 @@ import net.sourceforge.plantuml.cucadiagram.Rankdir;
public enum Position {
RIGHT, LEFT, BOTTOM, TOP;
public static Position fromString(String s) {
return Position.valueOf(s.toUpperCase());
}
public Position withRankdir(Rankdir rankdir) {
if (rankdir == null) {
throw new IllegalArgumentException();

View File

@ -51,7 +51,7 @@ public class SkinParameter {
ColorParam.artifactBorder, FontParam.ARTIFACT, FontParam.ARTIFACT_STEREOTYPE);
public static final SkinParameter COMPONENT1 = new SkinParameter("COMPONENT1", ColorParam.componentBackground,
ColorParam.componentBorder, FontParam.COMPONENT, FontParam.COMPONENT_STEREOTYPE);
ColorParam.componentBorder, FontParam.COMPONENT, FontParam.COMPONENT_STEREOTYPE, LineParam.componentBorder);
public static final SkinParameter NODE = new SkinParameter("NODE", ColorParam.nodeBackground,
ColorParam.nodeBorder, FontParam.NODE, FontParam.NODE_STEREOTYPE);
@ -72,7 +72,7 @@ public class SkinParameter {
ColorParam.frameBorder, FontParam.FRAME, FontParam.FRAME_STEREOTYPE);
public static final SkinParameter COMPONENT2 = new SkinParameter("COMPONENT2", ColorParam.componentBackground,
ColorParam.componentBorder, FontParam.COMPONENT, FontParam.COMPONENT_STEREOTYPE);
ColorParam.componentBorder, FontParam.COMPONENT, FontParam.COMPONENT_STEREOTYPE, LineParam.componentBorder);
public static final SkinParameter AGENT = new SkinParameter("AGENT", ColorParam.agentBackground,
ColorParam.agentBorder, FontParam.AGENT, FontParam.AGENT_STEREOTYPE);
@ -90,7 +90,7 @@ public class SkinParameter {
ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
public static final SkinParameter RECTANGLE = new SkinParameter("RECTANGLE", ColorParam.rectangleBackground,
ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE, LineParam.rectangleBorder);
public static final SkinParameter COLLECTIONS = new SkinParameter("COLLECTIONS", ColorParam.collectionsBackground,
ColorParam.collectionsBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
@ -115,14 +115,21 @@ public class SkinParameter {
private final FontParam fontParam;
private final FontParam fontParamStereotype;
private final String name;
private final LineParam lineParam;
private SkinParameter(String name, ColorParam colorParamBack, ColorParam colorParamBorder, FontParam fontParam,
FontParam fontParamStereotype) {
FontParam fontParamStereotype, LineParam lineParam) {
this.name = name;
this.colorParamBack = colorParamBack;
this.colorParamBorder = colorParamBorder;
this.fontParam = fontParam;
this.fontParamStereotype = fontParamStereotype;
this.lineParam = lineParam;
}
private SkinParameter(String name, ColorParam colorParamBack, ColorParam colorParamBorder, FontParam fontParam,
FontParam fontParamStereotype) {
this(name, colorParamBack, colorParamBorder, fontParam, fontParamStereotype, null);
}
public String getUpperCaseName() {
@ -154,8 +161,8 @@ public class SkinParameter {
public UStroke getStroke(ISkinParam skinParam, Stereotype stereotype) {
UStroke result = null;
if (name.equals("RECTANGLE")) {
result = skinParam.getThickness(LineParam.rectangleBorder, stereotype);
if (lineParam != null) {
result = skinParam.getThickness(lineParam, stereotype);
}
if (result == null) {
result = new UStroke(1.5);

View File

@ -67,20 +67,14 @@ public class Defines implements Truth {
}
public static Defines createEmpty() {
return createEmpty(null);
}
public static Defines createEmpty(String filename) {
final Defines result = new Defines();
if (filename != null) {
result.overrideFilename(filename);
}
return result;
return new Defines();
}
public void overrideFilename(String filename) {
environment.put("filename", filename);
environment.put("filenameNoExtension", nameNoExtension(filename));
if (filename != null) {
environment.put("filename", filename);
environment.put("filenameNoExtension", nameNoExtension(filename));
}
}
public void importFrom(Defines other) {
@ -98,7 +92,8 @@ public class Defines implements Truth {
if (file == null) {
throw new IllegalArgumentException();
}
final Defines result = createEmpty(file.getName());
final Defines result = createEmpty();
result.overrideFilename(file.getName());
result.environment.put("filedate", new Date(file.lastModified()).toString());
// result.environment.put("filename", file.getName());
// result.environment.put("filenameNoExtension", nameNoExtension(file));

View File

@ -266,7 +266,7 @@ public class PreprocessorInclude implements ReadLine {
}
private InputStream getStdlibInputStream(String filename) {
return Stdlib.getResourceAsStream(filename);
return StdlibOld.getResourceAsStream(filename);
}
private InputStream getStdlibInputStreamOld(String filename) {

View File

@ -0,0 +1,266 @@
package net.sourceforge.plantuml.preproc;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.Log;
import org.brotli.dec.BrotliInputStream;
public class Stdlib6 {
static private final Map<String, Stdlib6> all = new ConcurrentHashMap<String, Stdlib6>();
private static final String SEPARATOR = "\uF8FF";
private final Map<String, List<String>> raw = new HashMap<String, List<String>>();
// private final Map<String, SoftReference<byte[]>> cache = new ConcurrentHashMap<String, SoftReference<byte[]>>();
private final String name;
private final Map<String, String> info = new HashMap<String, String>();
public static InputStream getResourceAsStream(String fullname) {
fullname = fullname.toLowerCase().replace(".puml", "");
final int last = fullname.indexOf('/');
if (last == -1) {
return null;
}
try {
final Stdlib6 folder = retrieve(fullname.substring(0, last));
if (folder == null || folder.raw.size() == 0) {
return null;
}
final byte[] data = folder.getData(fullname.substring(last + 1));
if (data == null) {
return null;
}
return new ByteArrayInputStream(data);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static InputStream getInternalInputStream(String fullname, String extension) {
final String res = "/stdlib/" + fullname + extension;
return Stdlib6.class.getResourceAsStream(res);
}
private static Stdlib6 retrieve(final String name) throws IOException {
Stdlib6 result = all.get(name);
if (result == null) {
result = new Stdlib6(name);
all.put(name, result);
}
return result;
}
private final Pattern sizePattern = Pattern.compile("\\[(\\d+)x(\\d+)/16\\]");
private Stdlib6(String name) throws IOException {
this.name = name;
Log.info("Opening archive " + name);
final DataInputStream dataStream = getDataStream();
if (dataStream == null) {
return;
}
fillMap(dataStream.readUTF());
// final InputStream spriteStream = getSpriteStream();
int pos = 0;
while (true) {
final String filename = dataStream.readUTF();
// System.err.println("filename=" + filename);
if (filename.equals(SEPARATOR)) {
break;
}
final List<String> text = new ArrayList<String>();
while (true) {
final String s = dataStream.readUTF();
if (s.equals(SEPARATOR)) {
break;
}
text.add(s);
if (isSpriteLine(s)) {
final Matcher m = sizePattern.matcher(s);
final boolean ok = m.find();
if (ok == false) {
throw new IOException(s);
}
final int width = Integer.parseInt(m.group(1));
final int height = Integer.parseInt(m.group(2));
text.add("" + pos);
pos += spriteSize(width, height);
// System.err.println("Sprite! " + width + " " + height + " " + s);
text.add("}");
}
}
raw.put(filename.toLowerCase(), text);
// System.err.println("data=" + text.size());
// final int len = is.readInt();
// this.data.put(filename.toLowerCase(), new Portion(pos, len));
// pos += len;
}
dataStream.close();
}
private int spriteSize(int width, int height) {
final int nbLines = (height + 1) / 2;
return width * nbLines;
}
private String readSprite(int width, int height, InputStream inputStream) throws IOException {
final StringBuilder result = new StringBuilder();
final int nbLines = (height + 1) / 2;
int line = 0;
for (int j = 0; j < nbLines; j++) {
final StringBuilder sb1 = new StringBuilder();
final StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < width; i++) {
final int b = inputStream.read();
final int b1 = (b & 0xF0) >> 4;
final int b2 = (b & 0x0F);
sb1.append(toHexString(b1));
sb2.append(toHexString(b2));
}
result.append(sb1.toString());
result.append("\n");
line++;
if (line < height) {
result.append(sb2.toString());
result.append("\n");
line++;
}
}
return result.toString();
}
private String toHexString(final int b) {
return Integer.toHexString(b).toUpperCase();
}
private boolean isSpriteLine(String s) {
return s.trim().startsWith("sprite") && s.trim().endsWith("{");
}
private void fillMap(String infoString) {
for (String s : infoString.split("\n")) {
if (s.contains("=")) {
final String data[] = s.split("=");
this.info.put(data[0], data[1]);
}
}
}
private DataInputStream getDataStream() throws IOException {
final InputStream raw = getInternalInputStream(name, "-dat2.repx");
if (raw == null) {
return null;
}
return new DataInputStream(new BrotliInputStream(raw));
}
private InputStream getSpriteStream() throws IOException {
final InputStream raw = getInternalInputStream(name, "-spr.repx");
if (raw == null) {
return null;
}
return new BrotliInputStream(raw);
}
private byte[] getData(String filename) throws IOException {
final List<String> result = raw.get(filename);
if (result == null) {
return null;
}
final StringBuilder sb = new StringBuilder();
for (Iterator<String> it = result.iterator(); it.hasNext();) {
final String s = it.next();
sb.append(s);
sb.append("\n");
if (isSpriteLine(s)) {
final Matcher m = sizePattern.matcher(s);
final boolean ok = m.find();
if (ok == false) {
throw new IOException(s);
}
final int width = Integer.parseInt(m.group(1));
final int height = Integer.parseInt(m.group(2));
final InputStream spriteStream = getSpriteStream();
final int pos = Integer.parseInt(it.next());
// System.err.println("pos=" + pos);
spriteStream.skip(pos);
sb.append(readSprite(width, height, spriteStream));
sb.append("\n");
spriteStream.close();
}
}
return sb.toString().getBytes("UTF-8");
}
public static void extractStdLib() throws IOException {
// for (String name : getAll()) {
// final Stdlib6 folder = new Stdlib6(name);
// folder.extractMeFull(new File("stdlib", name));
// }
}
private static List<String> getAll() throws IOException {
final List<String> result = new ArrayList<String>();
final InputStream home = getInternalInputStream("home", ".repx");
final BufferedReader br = new BufferedReader(new InputStreamReader(home));
String name;
while ((name = br.readLine()) != null) {
result.add(name);
}
return Collections.unmodifiableList(result);
}
// private void extractMeFull(File dir) throws IOException {
// final DataInputStream idx = getDataIndex();
// final DataInputStream txt = getFullTexts();
// final String infoString = idx.readUTF();
// while (true) {
// final String filename = idx.readUTF();
// if (filename.length() == 0) {
// idx.close();
// txt.close();
// return;
// }
// final int len = idx.readInt();
// final File f = new File("stdlib/" + name + "/" + filename + ".puml");
// f.getParentFile().mkdirs();
// final FileOutputStream fos = new FileOutputStream(f);
// final byte data[] = new byte[len];
// txt.readFully(data);
// fos.write(data);
// fos.close();
// }
// }
public static void addInfoVersion(List<String> strings) {
try {
for (String name : getAll()) {
final Stdlib6 folder = new Stdlib6(name);
strings.add("* " + name + " (Version " + folder.getVersion() + ")");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String getVersion() {
return info.get("VERSION");
}
}

View File

@ -20,9 +20,9 @@ import net.sourceforge.plantuml.Log;
import org.brotli.dec.BrotliInputStream;
public class Stdlib {
public class StdlibOld {
static private final Map<String, Stdlib> all = new ConcurrentHashMap<String, Stdlib>();
static private final Map<String, StdlibOld> all = new ConcurrentHashMap<String, StdlibOld>();
static class Portion {
int position;
@ -54,7 +54,7 @@ public class Stdlib {
return null;
}
try {
final Stdlib folder = retrieve(fullname.substring(0, last));
final StdlibOld folder = retrieve(fullname.substring(0, last));
if (folder == null) {
return null;
}
@ -71,19 +71,19 @@ public class Stdlib {
private static InputStream getInternalInputStream(String fullname, String extension) {
final String res = "/stdlib/" + fullname + extension;
return Stdlib.class.getResourceAsStream(res);
return StdlibOld.class.getResourceAsStream(res);
}
private static Stdlib retrieve(final String name) throws IOException {
Stdlib result = all.get(name);
private static StdlibOld retrieve(final String name) throws IOException {
StdlibOld result = all.get(name);
if (result == null) {
result = new Stdlib(name);
result = new StdlibOld(name);
all.put(name, result);
}
return result;
}
private Stdlib(String name) throws IOException {
private StdlibOld(String name) throws IOException {
this.name = name;
Log.info("Opening archive " + name);
int pos = 0;
@ -147,7 +147,7 @@ public class Stdlib {
public static void extractStdLib() throws IOException {
for (String name : getAll()) {
final Stdlib folder = new Stdlib(name);
final StdlibOld folder = new StdlibOld(name);
folder.extractMeFull(new File("stdlib", name));
}
}
@ -188,7 +188,7 @@ public class Stdlib {
public static void addInfoVersion(List<String> strings) {
try {
for (String name : getAll()) {
final Stdlib folder = new Stdlib(name);
final StdlibOld folder = new StdlibOld(name);
strings.add("* " + name + " (Version " + folder.getVersion() + ")");
}
} catch (IOException e) {

View File

@ -58,7 +58,7 @@ public class PSystemSaltFactory extends PSystemBasicFactory<PSystemSalt> {
@Override
public PSystemSalt executeLine(PSystemSalt system, String line) {
if (system == null && line.equals("salt")) {
if (system == null && line.replace('\t', ' ').trim().equals("salt")) {
return new PSystemSalt();
}
if (system == null) {

View File

@ -0,0 +1,76 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.timingdiagram;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
public class CommandNote extends SingleLineCommand2<TimingDiagram> {
public CommandNote() {
super(getRegexConcat());
}
private static RegexConcat getRegexConcat() {
return new RegexConcat(new RegexLeaf("^"), //
new RegexLeaf("[%s]*note[%s]+"), //
new RegexLeaf("POSITION", "(top|bottom)[%s]+of[%s]+"), //
new RegexLeaf("CODE", CommandTimeMessage.PLAYER_CODE), //
new RegexLeaf("[%s]*:[%s]*"), //
new RegexLeaf("NOTE", "(.+)"), //
new RegexLeaf("[%s]*$"));
}
@Override
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
final String code = arg.get("CODE", 0);
final Player player = diagram.getPlayer(code);
if (player == null) {
return CommandExecutionResult.error("Unkown \"" + code + "\"");
}
final Display note = Display.getWithNewlines(arg.get("NOTE", 0));
final TimeTick now = diagram.getNow();
// final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet());
player.addNote(now, note, Position.fromString(arg.get("POSITION", 0)));
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,84 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.timingdiagram;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.CommandMultilines2;
import net.sourceforge.plantuml.command.MultilinesStrategy;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
public class CommandNoteLong extends CommandMultilines2<TimingDiagram> {
public CommandNoteLong() {
super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE);
}
public String getPatternEnd() {
return "(?i)^end[%s]?note$";
}
public CommandExecutionResult executeNow(final TimingDiagram diagram, BlocLines lines) {
final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499()));
lines = lines.subExtract(1, 1);
lines = lines.removeEmptyColumns();
final String code = line0.get("CODE", 0);
final Player player = diagram.getPlayer(code);
if (player == null) {
return CommandExecutionResult.error("Unkown \"" + code + "\"");
}
final Display note = lines.toDisplay();
final TimeTick now = diagram.getNow();
// final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet());
player.addNote(now, note, Position.fromString(line0.get("POSITION", 0)));
return CommandExecutionResult.ok();
}
private static RegexConcat getRegexConcat() {
return new RegexConcat(new RegexLeaf("^"), //
new RegexLeaf("[%s]*note[%s]+"), //
new RegexLeaf("POSITION", "(top|bottom)[%s]+of[%s]+"), //
new RegexLeaf("CODE", CommandTimeMessage.PLAYER_CODE), //
new RegexLeaf("[%s]*$"));
}
}

View File

@ -227,7 +227,7 @@ public class Histogram implements TimeDrawing {
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
}
public double getHeight() {
public double getHeight(StringBounder stringBounder) {
return stepHeight * allStates.size() + 10;
}

View File

@ -44,6 +44,7 @@ import java.util.TreeSet;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
@ -70,6 +71,7 @@ public class Player implements TextBlock, TimeProjected {
private final Set<ChangeState> changes = new TreeSet<ChangeState>();
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
private final List<TimingNote> notes = new ArrayList<TimingNote>();
public Player(String code, String full, TimingStyle type, ISkinParam skinParam, TimingRuler ruler) {
this.code = code;
@ -139,7 +141,7 @@ public class Player implements TextBlock, TimeProjected {
private TimeDrawing computeTimeDrawing() {
final TimeDrawing result;
if (type == TimingStyle.CONCISE) {
result = new Ribbon(ruler, skinParam);
result = new Ribbon(ruler, skinParam, notes);
} else if (type == TimingStyle.ROBUST) {
result = new Histogram(ruler, skinParam);
} else {
@ -158,17 +160,16 @@ public class Player implements TextBlock, TimeProjected {
public Dimension2D calculateDimension(StringBounder stringBounder) {
final TextBlock title = getTitle();
final double width = ruler.getWidth();
final double zoneHeight = getZoneHeight();
final double zoneHeight = getZoneHeight(stringBounder);
return new Dimension2DDouble(width, title.calculateDimension(stringBounder).getHeight() * 2 + zoneHeight);
}
public MinMax getMinMax(StringBounder stringBounder) {
throw new UnsupportedOperationException();
}
private double getZoneHeight() {
return getTimeDrawing().getHeight();
private double getZoneHeight(StringBounder stringBounder) {
return getTimeDrawing().getHeight(stringBounder);
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
@ -201,4 +202,8 @@ public class Player implements TextBlock, TimeProjected {
this.constraints.add(new TimeConstraint(tick1, tick2, message));
}
public void addNote(TimeTick now, Display note, Position position) {
this.notes.add(new TimingNote(now, this, note, position, skinParam));
}
}

View File

@ -41,6 +41,7 @@ import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
@ -64,10 +65,12 @@ public class Ribbon implements TimeDrawing {
private final TimingRuler ruler;
private String initialState;
private Colors initialColors;
private final List<TimingNote> notes;
public Ribbon(TimingRuler ruler, ISkinParam skinParam) {
public Ribbon(TimingRuler ruler, ISkinParam skinParam, List<TimingNote> notes) {
this.ruler = ruler;
this.skinParam = skinParam;
this.notes = notes;
}
public IntricatedPoint getTimeProjection(StringBounder stringBounder, TimeTick tick) {
@ -93,23 +96,28 @@ public class Ribbon implements TimeDrawing {
return new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
}
private TextBlock getTextBlock(String value) {
private TextBlock createTextBlock(String value) {
final Display display = Display.getWithNewlines(value);
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
}
public void drawU(UGraphic ug) {
UGraphic ugDown = ug.apply(new UTranslate(0, getHeightForConstraints()));
final StringBounder stringBounder = ug.getStringBounder();
final double halfDelta = delta / 2;
drawNotes(ug.apply(new UTranslate(0, -delta)), Position.TOP);
final TextBlock inital;
final StringBounder stringBounder = ugDown.getStringBounder();
final double ribbonHeight = getRibbonHeight();
UGraphic ugDown = ug.apply(new UTranslate(0, getHeightForConstraints()
+ getHeightForNotes(stringBounder, Position.TOP)));
final TextBlock initial;
if (initialState == null) {
inital = null;
initial = null;
} else {
inital = getTextBlock(initialState);
initial = createTextBlock(initialState);
final double a = getPosInPixel(changes.get(0));
drawPentaA(ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -delta / 2)),
drawPentaA(ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -halfDelta)),
getInitialWidth(stringBounder) + a, changes.get(0));
}
@ -118,28 +126,28 @@ public class Ribbon implements TimeDrawing {
final double b = getPosInPixel(changes.get(i + 1));
assert b > a;
if (changes.get(i).isCompletelyHidden() == false) {
drawHexa(ugDown.apply(new UTranslate(a, -delta / 2)), b - a, changes.get(i));
drawHexa(ugDown.apply(new UTranslate(a, -halfDelta)), b - a, changes.get(i));
}
}
if (changes.size() >= 1) {
final ChangeState last = changes.get(changes.size() - 1);
final double a = getPosInPixel(last);
if (last.isCompletelyHidden() == false) {
drawPentaB(ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a, last);
drawPentaB(ugDown.apply(new UTranslate(a, -halfDelta)), ruler.getWidth() - a, last);
}
}
ugDown = ugDown.apply(new UTranslate(0, delta / 2));
ugDown = ugDown.apply(new UTranslate(0, halfDelta));
if (inital != null) {
final Dimension2D dimInital = inital.calculateDimension(stringBounder);
inital.drawU(ugDown.apply(new UTranslate(-getDelta() - dimInital.getWidth(), -dimInital.getHeight() / 2)));
if (initial != null) {
final Dimension2D dimInital = initial.calculateDimension(stringBounder);
initial.drawU(ugDown.apply(new UTranslate(-getDelta() - dimInital.getWidth(), -dimInital.getHeight() / 2)));
}
for (int i = 0; i < changes.size(); i++) {
final ChangeState change = changes.get(i);
final double x = ruler.getPosInPixel(change.getWhen());
if (change.isBlank() == false && change.isCompletelyHidden() == false) {
final TextBlock state = getTextBlock(change.getState());
final TextBlock state = createTextBlock(change.getState());
final Dimension2D dim = state.calculateDimension(stringBounder);
final double xtext;
if (i == changes.size() - 1) {
@ -152,29 +160,46 @@ public class Ribbon implements TimeDrawing {
}
final String commentString = change.getComment();
if (commentString != null) {
final TextBlock comment = getTextBlock(commentString);
final TextBlock comment = createTextBlock(commentString);
final Dimension2D dimComment = comment.calculateDimension(stringBounder);
comment.drawU(ugDown.apply(new UTranslate(x + getDelta(), -delta - dimComment.getHeight())));
}
}
for (TimeConstraint constraint : constraints) {
constraint.drawU(ug.apply(new UTranslate(0, 15)), ruler, skinParam);
constraint.drawU(ug.apply(new UTranslate(0, getHeightForConstraints() / 2)), ruler, skinParam);
}
drawNotes(
ug.apply(new UTranslate(0, getHeightForConstraints() + getHeightForNotes(stringBounder, Position.TOP)
+ ribbonHeight)), Position.BOTTOM);
}
private void drawNotes(UGraphic ug, final Position position) {
for (TimingNote note : notes) {
if (note.getPosition() == position) {
final double x = ruler.getPosInPixel(note.getWhen());
note.drawU(ug.apply(new UTranslate(x, 0)));
}
}
}
private double getInitialWidth(final StringBounder stringBounder) {
return getTextBlock(initialState).calculateDimension(stringBounder).getWidth() + 2 * delta;
return createTextBlock(initialState).calculateDimension(stringBounder).getWidth() + getRibbonHeight();
}
private void drawHexa(UGraphic ug, double len, ChangeState change) {
final HexaShape shape = HexaShape.create(len, 2 * delta, change.getContext());
final HexaShape shape = HexaShape.create(len, getRibbonHeight(), change.getContext());
shape.drawU(ug);
}
private double getRibbonHeight() {
return 2 * delta;
}
private void drawPentaB(UGraphic ug, double len, ChangeState change) {
final PentaBShape shape = PentaBShape.create(len, 2 * delta, change.getContext());
final PentaBShape shape = PentaBShape.create(len, getRibbonHeight(), change.getContext());
shape.drawU(ug);
}
@ -184,7 +209,7 @@ public class Ribbon implements TimeDrawing {
if (back != null) {
context = context.withBackColor(back);
}
final PentaAShape shape = PentaAShape.create(len, 2 * delta, context);
final PentaAShape shape = PentaAShape.create(len, getRibbonHeight(), context);
shape.drawU(ug);
}
@ -195,8 +220,19 @@ public class Ribbon implements TimeDrawing {
return 30;
}
public double getHeight() {
return 3 * delta + getHeightForConstraints();
public double getHeight(StringBounder stringBounder) {
return 3 * delta + getHeightForConstraints() + getHeightForNotes(stringBounder, Position.TOP)
+ getHeightForNotes(stringBounder, Position.BOTTOM);
}
private double getHeightForNotes(StringBounder stringBounder, Position position) {
double height = 0;
for (TimingNote note : notes) {
if (note.getPosition() == position) {
height = Math.max(height, note.getHeight(stringBounder));
}
}
return height;
}
public double getDelta() {
@ -205,7 +241,7 @@ public class Ribbon implements TimeDrawing {
public TextBlock getWidthHeader(StringBounder stringBounder) {
if (initialState != null) {
return TextBlockUtils.empty(getInitialWidth(stringBounder), 2 * delta);
return TextBlockUtils.empty(getInitialWidth(stringBounder), getRibbonHeight());
}
return TextBlockUtils.empty(0, 0);
}

View File

@ -0,0 +1,244 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.timingdiagram;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class RibbonNew implements TimeDrawing {
private final List<ChangeState> changes = new ArrayList<ChangeState>();
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
private final double delta = 12;
private final ISkinParam skinParam;
private final TimingRuler ruler;
private String initialState;
private Colors initialColors;
private final List<TimingNote> notes;
public RibbonNew(TimingRuler ruler, ISkinParam skinParam, List<TimingNote> notes) {
this.ruler = ruler;
this.skinParam = skinParam;
this.notes = notes;
}
public IntricatedPoint getTimeProjection(StringBounder stringBounder, TimeTick tick) {
final double x = ruler.getPosInPixel(tick);
final double y = delta * 0.5 + getHeightForConstraints();
for (ChangeState change : changes) {
if (change.getWhen().compareTo(tick) == 0) {
return new IntricatedPoint(new Point2D.Double(x, y), new Point2D.Double(x, y));
}
}
return new IntricatedPoint(new Point2D.Double(x, y - delta), new Point2D.Double(x, y + delta));
}
public void addChange(ChangeState change) {
this.changes.add(change);
}
private double getPosInPixel(ChangeState change) {
return ruler.getPosInPixel(change.getWhen());
}
private FontConfiguration getFontConfiguration() {
return new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
}
private TextBlock createTextBlock(String value) {
final Display display = Display.getWithNewlines(value);
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
}
public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
final double ribbonHeight = getRibbonHeight(stringBounder);
UGraphic ugDown = ug.apply(new UTranslate(0, getHeightForConstraints()));
final TextBlock inital;
if (initialState == null) {
inital = null;
} else {
inital = createTextBlock(initialState);
final double a = getPosInPixel(changes.get(0));
drawPentaA(ribbonHeight, ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -delta / 2)),
getInitialWidth(stringBounder) + a, changes.get(0));
}
for (int i = 0; i < changes.size() - 1; i++) {
final double a = getPosInPixel(changes.get(i));
final double b = getPosInPixel(changes.get(i + 1));
assert b > a;
if (changes.get(i).isCompletelyHidden() == false) {
drawHexa(ribbonHeight, ugDown.apply(new UTranslate(a, -delta / 2)), b - a, changes.get(i));
}
}
if (changes.size() >= 1) {
final ChangeState last = changes.get(changes.size() - 1);
final double a = getPosInPixel(last);
if (last.isCompletelyHidden() == false) {
drawPentaB(ribbonHeight, ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a, last);
}
}
ugDown = ugDown.apply(new UTranslate(0, delta / 2));
if (inital != null) {
final Dimension2D dimInital = inital.calculateDimension(stringBounder);
inital.drawU(ugDown.apply(new UTranslate(-getDelta() - dimInital.getWidth(), -dimInital.getHeight() / 2)));
}
for (int i = 0; i < changes.size(); i++) {
final ChangeState change = changes.get(i);
final double x = ruler.getPosInPixel(change.getWhen());
if (change.isBlank() == false && change.isCompletelyHidden() == false) {
final TextBlock state = createTextBlock(change.getState());
final Dimension2D dim = state.calculateDimension(stringBounder);
final double xtext;
if (i == changes.size() - 1) {
xtext = x + getDelta();
} else {
final double x2 = ruler.getPosInPixel(changes.get(i + 1).getWhen());
xtext = (x + x2) / 2 - dim.getWidth() / 2;
}
state.drawU(ugDown.apply(new UTranslate(xtext, -dim.getHeight() / 2)));
}
final String commentString = change.getComment();
if (commentString != null) {
final TextBlock comment = createTextBlock(commentString);
final Dimension2D dimComment = comment.calculateDimension(stringBounder);
comment.drawU(ugDown.apply(new UTranslate(x + getDelta(), -delta - dimComment.getHeight())));
}
}
for (TimeConstraint constraint : constraints) {
constraint.drawU(ug.apply(new UTranslate(0, ribbonHeight / 2)), ruler, skinParam);
}
for (TimingNote note : notes) {
final double x = ruler.getPosInPixel(note.getWhen());
note.drawU(ug.apply(new UTranslate(x, ribbonHeight)));
}
}
private double getInitialWidth(final StringBounder stringBounder) {
return createTextBlock(initialState).calculateDimension(stringBounder).getWidth() + 2 * delta;
}
private void drawHexa(double ribbonHeight, UGraphic ug, double len, ChangeState change) {
final HexaShape shape = HexaShape.create(len, ribbonHeight, change.getContext());
shape.drawU(ug);
}
private void drawPentaB(double ribbonHeight, UGraphic ug, double len, ChangeState change) {
final PentaBShape shape = PentaBShape.create(len, ribbonHeight, change.getContext());
shape.drawU(ug);
}
private void drawPentaA(double ribbonHeight, UGraphic ug, double len, ChangeState change) {
SymbolContext context = change.getContext();
final HtmlColor back = initialColors.getColor(ColorType.BACK);
if (back != null) {
context = context.withBackColor(back);
}
final PentaAShape shape = PentaAShape.create(len, ribbonHeight, context);
shape.drawU(ug);
}
private double getHeightForConstraints() {
if (constraints.size() == 0) {
return 0;
}
return 30;
}
public double getHeight(StringBounder stringBounder) {
return getHeightForConstraints() + getRibbonHeight(stringBounder) + getHeightForNotes(stringBounder);
}
private double getRibbonHeight(StringBounder stringBounder) {
double height = 24;
return height;
}
private double getHeightForNotes(StringBounder stringBounder) {
double height = 0;
for (TimingNote note : notes) {
height = Math.max(height, note.getHeight(stringBounder));
}
return height;
}
public double getDelta() {
return delta;
}
public TextBlock getWidthHeader(StringBounder stringBounder) {
if (initialState != null) {
return TextBlockUtils.empty(getInitialWidth(stringBounder), getRibbonHeight(stringBounder));
}
return TextBlockUtils.empty(0, 0);
}
public void setInitialState(String initialState, Colors initialColors) {
this.initialState = initialState;
this.initialColors = initialColors;
}
public void addConstraint(TimeConstraint constraint) {
this.constraints.add(constraint);
}
}

View File

@ -0,0 +1,226 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.timingdiagram;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class RibbonOld implements TimeDrawing {
private final List<ChangeState> changes = new ArrayList<ChangeState>();
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
private final double delta = 12;
private final ISkinParam skinParam;
private final TimingRuler ruler;
private String initialState;
private Colors initialColors;
public RibbonOld(TimingRuler ruler, ISkinParam skinParam) {
this.ruler = ruler;
this.skinParam = skinParam;
}
public IntricatedPoint getTimeProjection(StringBounder stringBounder, TimeTick tick) {
final double x = ruler.getPosInPixel(tick);
final double y = delta * 0.5 + getHeightForConstraints();
for (ChangeState change : changes) {
if (change.getWhen().compareTo(tick) == 0) {
return new IntricatedPoint(new Point2D.Double(x, y), new Point2D.Double(x, y));
}
}
return new IntricatedPoint(new Point2D.Double(x, y - delta), new Point2D.Double(x, y + delta));
}
public void addChange(ChangeState change) {
this.changes.add(change);
}
private double getPosInPixel(ChangeState change) {
return ruler.getPosInPixel(change.getWhen());
}
private FontConfiguration getFontConfiguration() {
return new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
}
private TextBlock getTextBlock(String value) {
final Display display = Display.getWithNewlines(value);
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
}
public void drawU(UGraphic ug) {
UGraphic ugDown = ug.apply(new UTranslate(0, getHeightForConstraints()));
final TextBlock inital;
final StringBounder stringBounder = ugDown.getStringBounder();
if (initialState == null) {
inital = null;
} else {
inital = getTextBlock(initialState);
final double a = getPosInPixel(changes.get(0));
drawPentaA(ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -delta / 2)),
getInitialWidth(stringBounder) + a, changes.get(0));
}
for (int i = 0; i < changes.size() - 1; i++) {
final double a = getPosInPixel(changes.get(i));
final double b = getPosInPixel(changes.get(i + 1));
assert b > a;
if (changes.get(i).isCompletelyHidden() == false) {
drawHexa(ugDown.apply(new UTranslate(a, -delta / 2)), b - a, changes.get(i));
}
}
if (changes.size() >= 1) {
final ChangeState last = changes.get(changes.size() - 1);
final double a = getPosInPixel(last);
if (last.isCompletelyHidden() == false) {
drawPentaB(ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a, last);
}
}
ugDown = ugDown.apply(new UTranslate(0, delta / 2));
if (inital != null) {
final Dimension2D dimInital = inital.calculateDimension(stringBounder);
inital.drawU(ugDown.apply(new UTranslate(-getDelta() - dimInital.getWidth(), -dimInital.getHeight() / 2)));
}
for (int i = 0; i < changes.size(); i++) {
final ChangeState change = changes.get(i);
final double x = ruler.getPosInPixel(change.getWhen());
if (change.isBlank() == false && change.isCompletelyHidden() == false) {
final TextBlock state = getTextBlock(change.getState());
final Dimension2D dim = state.calculateDimension(stringBounder);
final double xtext;
if (i == changes.size() - 1) {
xtext = x + getDelta();
} else {
final double x2 = ruler.getPosInPixel(changes.get(i + 1).getWhen());
xtext = (x + x2) / 2 - dim.getWidth() / 2;
}
state.drawU(ugDown.apply(new UTranslate(xtext, -dim.getHeight() / 2)));
}
final String commentString = change.getComment();
if (commentString != null) {
final TextBlock comment = getTextBlock(commentString);
final Dimension2D dimComment = comment.calculateDimension(stringBounder);
comment.drawU(ugDown.apply(new UTranslate(x + getDelta(), -delta - dimComment.getHeight())));
}
}
for (TimeConstraint constraint : constraints) {
constraint.drawU(ug.apply(new UTranslate(0, 15)), ruler, skinParam);
}
}
private double getInitialWidth(final StringBounder stringBounder) {
return getTextBlock(initialState).calculateDimension(stringBounder).getWidth() + getRibonHeight();
}
private void drawHexa(UGraphic ug, double len, ChangeState change) {
final HexaShape shape = HexaShape.create(len, getRibonHeight(), change.getContext());
shape.drawU(ug);
}
private double getRibonHeight() {
return 2 * delta;
}
private void drawPentaB(UGraphic ug, double len, ChangeState change) {
final PentaBShape shape = PentaBShape.create(len, getRibonHeight(), change.getContext());
shape.drawU(ug);
}
private void drawPentaA(UGraphic ug, double len, ChangeState change) {
SymbolContext context = change.getContext();
final HtmlColor back = initialColors.getColor(ColorType.BACK);
if (back != null) {
context = context.withBackColor(back);
}
final PentaAShape shape = PentaAShape.create(len, getRibonHeight(), context);
shape.drawU(ug);
}
private double getHeightForConstraints() {
if (constraints.size() == 0) {
return 0;
}
return 30;
}
public double getHeight(StringBounder stringBounder) {
return 3 * delta + getHeightForConstraints();
}
public double getDelta() {
return delta;
}
public TextBlock getWidthHeader(StringBounder stringBounder) {
if (initialState != null) {
return TextBlockUtils.empty(getInitialWidth(stringBounder), getRibonHeight());
}
return TextBlockUtils.empty(0, 0);
}
public void setInitialState(String initialState, Colors initialColors) {
this.initialState = initialState;
this.initialColors = initialColors;
}
public void addConstraint(TimeConstraint constraint) {
this.constraints.add(constraint);
}
}

View File

@ -41,7 +41,7 @@ import net.sourceforge.plantuml.graphic.color.Colors;
public interface TimeDrawing extends TimeProjected, UDrawable {
public double getHeight();
public double getHeight(StringBounder stringBounder);
public void addChange(ChangeState change);

View File

@ -61,6 +61,8 @@ public class TimingDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandAtTime());
cmds.add(new CommandAtPlayer());
cmds.add(new CommandTimeMessage());
cmds.add(new CommandNote());
cmds.add(new CommandNoteLong());
cmds.add(new CommandConstraint());
cmds.add(new CommandScalePixel());

View File

@ -0,0 +1,103 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.timingdiagram;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineBreakStrategy;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.creole.CreoleParser;
import net.sourceforge.plantuml.creole.Sheet;
import net.sourceforge.plantuml.creole.SheetBlock1;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.svek.image.Opale;
import net.sourceforge.plantuml.ugraphic.UGraphic;
public class TimingNote {
private final TimeTick when;
private final Player player;
private final Display note;
private final Position position;
private final ISkinParam skinParam;
public TimingNote(TimeTick when, Player player, Display note, Position position, ISkinParam skinParam) {
this.note = note;
this.player = player;
this.when = when;
this.skinParam = skinParam;
this.position = position;
}
public void drawU(UGraphic ug) {
final Opale opale = createOpale();
opale.drawU(ug);
}
private Opale createOpale() {
final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.NOTE, null);
final Rose rose = new Rose();
final HtmlColor noteBackgroundColor = rose.getHtmlColor(skinParam, ColorParam.noteBackground);
final HtmlColor borderColor = rose.getHtmlColor(skinParam, ColorParam.noteBorder);
final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT),
skinParam, CreoleMode.FULL).createSheet(note);
final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding());
final Opale opale = new Opale(borderColor, noteBackgroundColor, sheet1, skinParam.shadowing(), false);
return opale;
}
public double getHeight(StringBounder stringBounder) {
return createOpale().calculateDimension(stringBounder).getHeight();
}
public TimeTick getWhen() {
return when;
}
public final Position getPosition() {
return position;
}
}

View File

@ -57,7 +57,7 @@ public class SpriteMonochrome implements Sprite {
private final int grayLevel;
private final int pixels[][];
SpriteMonochrome(int width, int height, int grayLevel) {
public SpriteMonochrome(int width, int height, int grayLevel) {
if (grayLevel != 2 && grayLevel != 4 && grayLevel != 8 && grayLevel != 16) {
throw new IllegalArgumentException();
}
@ -67,7 +67,41 @@ public class SpriteMonochrome implements Sprite {
this.pixels = new int[height][width];
}
void setPixel(int x, int y, int level) {
public SpriteMonochrome xSymetric() {
final SpriteMonochrome result = new SpriteMonochrome(width, height, grayLevel);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
result.setPixel(i, j, this.getPixel(i, j));
}
}
for (int j = 0; j < height; j++) {
for (int i = 0; i < width / 2; i++) {
final int i2 = width - 1 - i;
final int level = result.getPixel(i, j) ^ result.getPixel(i2, j);
result.setPixel(i2, j, level);
}
}
return result;
}
public SpriteMonochrome ySymetric() {
final SpriteMonochrome result = new SpriteMonochrome(width, height, grayLevel);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
result.setPixel(i, j, this.getPixel(i, j));
}
}
for (int i = 0; i < width; i++) {
for (int j = 0; j < height / 2; j++) {
final int j2 = height - 1 - j;
final int level = result.getPixel(i, j) ^ result.getPixel(i, j2);
result.setPixel(i, j2, level);
}
}
return result;
}
public void setPixel(int x, int y, int level) {
if (x < 0 || x >= width) {
return;
}
@ -80,11 +114,21 @@ public class SpriteMonochrome implements Sprite {
pixels[y][x] = level;
}
public int getPixel(int x, int y) {
if (x >= width) {
throw new IllegalArgumentException("x=" + x + " width=" + width);
}
if (y >= height) {
throw new IllegalArgumentException("y=" + y + " height=" + height);
}
return pixels[y][x];
}
public int getHeight() {
return height;
}
int getWidth() {
public int getWidth() {
return width;
}

View File

@ -63,7 +63,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.graphic.GraphicPosition;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.preproc.PreprocessorInclude;
import net.sourceforge.plantuml.preproc.Stdlib;
import net.sourceforge.plantuml.preproc.StdlibOld;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
@ -174,7 +174,7 @@ public class PSystemVersion extends AbstractPSystem {
}
strings.add(" ");
strings.add("<b>Stdlib:");
Stdlib.addInfoVersion(strings);
StdlibOld.addInfoVersion(strings);
strings.add(" ");
strings.addAll(GraphvizUtils.getTestDotStrings(true));

View File

@ -43,7 +43,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000;
public static int version() {
return 1201720;
return 1201800;
}
public static int versionPatched() {
@ -88,7 +88,7 @@ public class Version {
}
public static long compileTime() {
return 1513011425649L;
return 1515094976440L;
}
public static String compileTimeString() {